Introduction

My Project Manager recently asked me why our folder selection dialog didn't
look the same as the one in Microsoft Word®. This question took me by surprise,
since we have been using my
XBrowseForFolder dialog for several years:

When I looked at the dialog in Microsoft Word, I saw that my
Project Manager was right. This is what I found:

While this looks superficially like
CFileDialog, using
HPS HwndSpy
shows that it is entirely different. Instead of being dialog-based, Word
uses a window whose class is "bosa_sdm_Microsoft Word 9.0". And instead
of using a standard SysListView32 list control, the one in Word
has a class name of "OpenListView":

What would it take to display a folder selection dialog like Word's? Would it be
possible to do the same thing using
CFileDialog?
These questions were in my mind as I studied the folder selection window in Word.

A Journey Into CFileDialog

The most obvious thing to say about a folder selection dialog is that it should display only folders, not files.
I tried a number of tricks that had the desired effect, but also were pretty slow. In the end I used a filter for the file extension - one that
was generated by guidgen.

The next thing to take care of was the
places bar -
the toolbar with icons
that is displayed on the left in the above screenshot. Fortunately
Paul DiLascia's article on the Windows 2000-style file open dialog
shows a simple way to do this.

XFolderDialog allows you to select the style of open file dialog
by specifying the OS version - OS versions before Windows 2000 do not
support the places bar. You can also specify "OS autodetect", which will
display the places bar whenever possible.

The following screenshots show the demo program and how XFolderDialog will appear
from Windows 98 to Vista, using OS autodetect:

Click to enlarge.

98

2000

XP

Vista

FEATURE NOTE

Setting OS to 5 on Windows 98 will not work - XFolderDialog will not display.

Of course, you can "downgrade" to OS version 4 on Windows 2000, XP, and Vista.
Here is what OS version 4 XFolderDialog looks like on XP:

Persistent List View Mode

Starting with version 1.3, XFolderDialog supports persistent
list view mode for XP and Vista. "Persistent list view mode" refers to the view that you see when the list is displaying folders. As you see from the screenshot, for XP it can be set to one of five types of view. With the standard Windows Open dialog on XP, this view is not persistent - it will always open in List mode.

XFolderDialog provides two mechanisms for persisting the list view mode:

Persistence via registry/INI file - the view mode will be restored from the registry/INI file when XFolderDialog is displayed, and saved when it is closed. This happens completely automatically and is the default, unless you change it by API call. If using the registry, the view mode will be restored/saved using the key

Persistence via API calls - if you do not want to use the built-in mechanism for restoring/saving the view mode, you can use the GetViewMode()/SetViewMode() functions. It is then up to you to load and save the view mode.

Persistent list view mode is also supported for Vista, which has seven view modes vs. five for XP. Just as for XP, XFolderDialog running on Vista provides two mechanisms for persisting the list view mode. Unlike XP, Vista itself persists the list view mode, and so it isn't necessary for your program to do it (although it will work correctly on Vista if you do want to use the XFolderDialog persistence mechanisms).

The following table shows list view modes:

View Mode

XP

Vista

XLVM_XP_DO_NOT_PERSIST

XLVM_XP_UNDEFINED

XLVM_XP_ICONS

XLVM_XP_LIST

XLVM_XP_DETAILS

XLVM_XP_THUMBNAILS

XLVM_XP_TILES

XLVM_VISTA_DO_NOT_PERSIST

XLVM_VISTA_UNDEFINED

XLVM_VISTA_DETAILS

XLVM_VISTA_TILES

XLVM_VISTA_EXTRA_LARGE_ICONS

XLVM_VISTA_MEDIUM_ICONS

XLVM_VISTA_LARGE_ICONS

XLVM_VISTA_SMALL_ICONS

XLVM_VISTA_LIST

IMPLEMENTATION NOTE

Except for XXXX_DO_NOT_PERSIST and XXXX_UNDEFINED, the above symbols are #define'd as the actual list view commands sent via WM_COMMAND message.

CXFolderDialog API

Here are functions provided by CXFolderDialog:

Function

Description

enum XFILEDIALOG_OS_VERSION void EnableRegistry(BOOL bEnable)

Enables/disables use of registry to store view mode

enum XFILEDIALOG_OS_VERSION GetOsVersion()

Gets OS version used for folder select dialog

CString GetPath()

Gets path of selected folder

int GetViewMode()

Gets last-used view mode from folder select dialog

void SetOsVersion(enum XFILEDIALOG_OS_VERSION eOsVersion)

Allows you to choose between old-style and Explorer-style dialog

void SetTitle(LPCTSTR lpszTitle)

Sets title of folder select dialog

void SetViewMode(int cmd)

Sets view mode for folder select dialog list control

How to use

To integrate CXFolderDialog into your app, you first need to add following files to your project:

XFolderDialog.cpp

XFolderDialog.h

XFileOpenListView.cpp

XFileOpenListView.h

XFolderDialog.rc

XFolderDialogRes.h

XHistoryCombo.cpp

XHistoryCombo.h

XWinVer.cpp

XWinVer.h

You also need to add XFolderDialog.rc to project rc file:

For Visual Studio 6 - go to View | Resource Includes... and in bottom listbox, scroll down to end. Insert #include "XFolderDialog.rc" right before #endif:

A Note on _WIN32_WINNT

The preprocessor symbol _WIN32_WINNT is used in commdlg.h
in OPENFILENAME struct to configure its size. When
_WIN32_WINNT is equal to or greater than 0x500, an additional
three items are included in struct. The struct size (stored in
struct member lStructSize) is how
::GetOpenFileName() determines which dialog to display - the
old-style or Explorer-style dialog.

When XFolderDialog is displayed using
XFILEDIALOG_AUTO_DETECT_OS_VERSION, the Explorer-style dialog
will always be displayed on Windows 2000 (or later) systems. You can
overrride this behavior by using XFILEDIALOG_OS_VERSION_4. Again,
this override is accomplished by tweaking size of the
OPENFILENAME struct.

Acknowledgments

Paul DiLascia has written a number of articles on customizing common file dialog.
He first mentions it in
this August 2000 article
which discusses the Windows 2000-style file open dialog (the one with the Places bar).
He first discusses list view type in
this March 2004 article,
and follows up in
November 2004
with an article about persisting list view. His final article in
February 2005
addressed bug in the earlier code.

Version 1.4 - 2010 June 2

Version 1.3 - 2008 February 22

Fixed bug when new folder is created and OK pressed, reported by McLyndon and Super Garrison.

Fixed bug when new path entered in mru combo, reported by Brad Bruce, with
fix suggested by Manfred Drasch.

Fixed bug when used in dll, reported by k-mommos.

Fixed bug where you click My Computer then select folder, with fix suggested by Wade Ledbetter.

Added ability to set/save list view mode, requested by Aetschmaen.

Added demo project for VS2005.

Version 1.2 - 2005 March 22

Fixed problem with initial sizing of placebar, reported by XXX.

Version 1.1 - 2005 March 17

Improved performance by using file filter.

Changed screenshot paths to use forward slash.

Version 1.0 - 2005 March 15

Initial public release

Usage

This software is released under the
Code Project Open License (CPOL).
You are free to use this software in any way you like, except that you
may not sell this source code. This software is provided "as is" with no expressed or implied warranty.
I accept no liability for any damage or loss of business that this
software may cause.

Share

About the Author

I attended St. Michael's College of the University of Toronto, with the intention of becoming a priest. A friend in the University's Computer Science Department got me interested in programming, and I have been hooked ever since.

Recently, I have moved to Los Angeles where I am doing consulting and development work.

For consulting and custom software development, please see www.hdsoft.org.

My remedy, as someone intimated in a high google return of a third-party discussion site, came quickly and without secondary error.

Knowing that the bolt had no nut of the correct pitch (W7.1 onthetopof VS2010 breaks due to WU of 110318) and seeing there in "Programs and Feetchers" that a whole load of updates occured 110424, the day after a successful compile of the sample "DIBLOOK" ("ships" with .. wha-huh? ) I surmise the condition of 110428 NO-COMPILE of HD's code and, testing, ... DIBLOOK too, resulting in c3861 and ATL-blahblahblah ktmw32.dll fiasco nonesense, is what an actual fail due to break warned of on-site where THE ACTUAL VS2010 SP1 update IS OBTAINED has occured.

Believe it not, doing exactly what the installer ques the user to do when he attempts to "roll-back" one of the wu, possibly the c++ compiler update itself, that is "insert installation dvd" to obtain the vs_setup.msi location, enables the wu to be uninstalled. Everything, including compile functionality of previous day, returned immediately and no further system alterations to either W7.1 or VS2010 had to be done.

My issue, and I think HD gets it (subsequent posts ...), is that wu has got some sort of privilage that can break VS2010. And, of course, there's always the issue with documentation wrt to this ATL stuff.

Sorry to say that looking at the wu panel right now NOW gives me a great feeling of trepidation wrt future of Windows.

P.S.

I mean, I should have noted the size of that package when I originally installed it. "What is this that weighs this much?" And in answer to your question, I can right-click and hide the offendors, yes.

Trying to find a solution to the CFileDialog open multiple files conundrum in MFC, ran across your multiple code samples here in cdprjct.

Trying to compile these projects is more frustrating still: with respect to ktmw32.dll and specifically all the atl reference resolutions that occur (for God only knows what reason ...) your code apparently wants access to something that I haven't got!

Not to rail, just out there for information ... while it's true that the SDK is necessary for the compile here, the SDK "missing" or in some incarnation less than what it might be, is NOT actually the issue with my c3861.

On the surface C3861 is probably the issue; I'm not gonna spend another second trying to figure out why I'm getting a compile error ... etc, yes?

MS just (110318) came out with SP1 for VS2010, right? So, (but they don't INFORM me, the user ...) using WindowsUpdate I update my dev box 110424 .. dumdeedumdeedumdum ... three days later I go to compile projects that on the 21st where hunky dory compiles, right?

The lump of floorbutter that IS the Windows Update to SP1 along with all the various other hotfixes that comes piping onto the box that DOESN'T NEED AN INSTALLER TO INSTALL ON TOP OF MY INSTALL ... breaks the W7 SDK (some 7.1 funktorius BS).

So I'm can't "uninstall" the WU updates until I find the installation DVD for VS2010Pro (a web install, of all fated things ... Soren forbid)

But happily ever after .. I uninstalled the wues and now SP1 and SDK issue is pre-110422 ok.

I am getting this same error all of a sudden and wondered about your last statement regarding the SP1 and SDK issue is pre-110422. Could you elaborate further? I rolled back the latest wues and had to perform maintenance on Visual Studio 2010. Without the latest windows updates applied I am still receiving the C3861 error and just wondered if you had a solution.

In my case all of the compiles did fail due to the C3861 error. The error in itself points to the fact, as you well know, that in the header file AtlTranactionManager.h uses method AtlLoadSystemLibraryUsingFullPath(L"KTM32.dll")which is not declared anywhere. I found the header ktm32.h and it's not there.

I just started getting this error too and it was working perfectly for me yesterday. This may be unrelated but in my Windows update history I see that a security update for MS Visual Studio 2010 (KB2455033) was installed around 3:00a this morning. Thanks, Microsoft! If anybody has a clue how to fix it I would be most grateful.

I forgot to add that I have seen several postings about problems with the Windows update for VS2010 breaking builds, but none that suggest a fix for the C3861 problem. Probably the best thing is to post on the Microsoft support forum.

Adding a pOKButton->SetFocus in OnCbnKillfocusMruCombo could fix this. But I am not if it is appropriate.

Quote from our blind user:

"when in the browse for folder area, ... there is no way to tab to the ok button, you can tab to cancel and you can make all of your folders and you can browse for folders and all that junk but you cannot get to the ok button to finally confirm the new folder choice."

I don't know if this is a bug or not but on Windows 7 the "Look in" drop-down seems to always default to the Documents library. This is different compared to how XFolderDialog works on Windows XP and Vista where "Look in" defaults to the folder from which I most recently opened or saved a file (the expected behavior).

I meet that problem too.
the DoModal called GetOpenFileName,msdn say:OFN_NOCHANGEDIR flag is ineffective for GetOpenFileName
Solution:
we must save the current dir before GetOpenFileName and restore after.

Could you let me know what was fixed to have this issue resolved. I am using a older version of the code and experiencing the same message "Attempted unsupported operation". Can you point me to the changes in the code.

The bad news: I haven't been able to trap the listview messages when a label edit completes, so I'm not sure it will be possible to fix this to work on pre-Win7 systems. However, there are a few more things I want to try, and I will post here if I succeed.

Update: I've done more testing, and I was wrong about this working on Win7.

clicking on browse button(from which XFolderDialog is opened) starts from the other path given in CFilesource for my other file open dialog. XFolderDialog is not storing the last path it selected.
even if i select a path using XFolderDialog and open it again in the same, still it starts from the path which was set by my other file open dialog.

I'm using this control but I've found one issue, after the directory has been selected and the CXfolderDialog is closed, if you try to go to Explorer and try to delete the directory, looks like the directory is locked and cannot be deleted, it can only be deleted once the application is closed. Any ideas???