![]() |
Desktop Development »
Dialogs and Windows »
Dialogs
Intermediate
License: The Code Project Open License (CPOL)
XFolderDialog - a folder selection dialog based on CFileDialogBy Hans DietrichXFolderDialog provides a folder selection dialog like that used in MS Word, and includes persistent list view type. |
VC6Win2K, WinXP, MFC, VS2005, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
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.
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:
HKEY_CURRENT_USER\Software\<Company>\<App Name>\XFolderDialog\ViewMode
For example, the key for XFolderDialogTest.exe isHKEY_CURRENT_USER\Software\CodeProject\XFolderDialogTest\XFolder Dialog\ViewMode
and was set by this code in XFolderDialogTest.cpp:SetRegistryKey(_T("CodeProject"));
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.
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 |
To integrate CXFolderDialog into your app, you first need to
add following files to your project:
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:
|
|
| For Visual Studio 2005 -
right-click .rc file in Resource View, then choose
Resource Includes... from shortcut menu:
#include
"XFolderDialog.rc" right before #endif:
|
Next, include header file XFolderDialog.h in appropriate project
files. Now you are ready to start using CXFolderDialog.
The demo app shows how to call XFolderDialog:
CXFolderDialog dlg(m_strInitialFolder);
dlg.SetOsVersion((enum CXFolderDialog::XFILEDIALOG_OS_VERSION) m_nOsVersion);
dlg.SetTitle(_T("Select Folder")); // defaults to "Select Folder"
if (dlg.DoModal() == IDOK)
{
CString strPath = dlg.GetPath();
.
.
.
|
typedef struct tagOFNA {
DWORD lStructSize;
HWND hwndOwner;
HINSTANCE hInstance;
LPCSTR lpstrFilter;
LPSTR lpstrCustomFilter;
DWORD nMaxCustFilter;
DWORD nFilterIndex;
LPSTR lpstrFile;
DWORD nMaxFile;
LPSTR lpstrFileTitle;
DWORD nMaxFileTitle;
LPCSTR lpstrInitialDir;
LPCSTR lpstrTitle;
DWORD Flags;
WORD nFileOffset;
WORD nFileExtension;
LPCSTR lpstrDefExt;
LPARAM lCustData;
LPOFNHOOKPROC lpfnHook;
LPCSTR lpTemplateName;
#ifdef _MAC
LPEDITMENU lpEditInfo;
LPCSTR lpstrPrompt;
#endif
#if (_WIN32_WINNT >= 0x0500)
void * pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
#endif // (_WIN32_WINNT >= 0x0500)
} OPENFILENAMEA, *LPOPENFILENAMEA;
|
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.
Here is code that does this:
#if (_WIN32_WINNT >= 0x0500)
#pragma message(__FILE__ "(" makestring(__LINE__) \
") : OPENFILENAME is large size (3 extra items are included)")
if (IsWin2000())
// OS >= 2000, force to large size
m_ofnEx.lStructSize = sizeof(OPENFILENAME);
else
// use small size
m_ofnEx.lStructSize = OPENFILENAME_SIZE_VERSION_400;
#else // _WIN32_WINNT < 0x0500, or isn't defined
#pragma message(__FILE__ "(" makestring(__LINE__) \
") : OPENFILENAME is small size (3 extra items are NOT included)")
if (IsWin2000())
// OS >= 2000, force to large size
m_ofnEx.lStructSize = sizeof(OPENFILENAMEEX);
else
// use small size
m_ofnEx.lStructSize = OPENFILENAME_SIZE_VERSION_400;
#endif
Using Visual Studio 6, normal situation is that _WIN32_WINNT
will not be defined, as you can see from message displayed in IDE output
window:
Compiling... XFolderDialog.cpp ...\src\XFolderDialog.cpp(68) : _WIN32_WINNT is not defined ...\src\XFolderDialog.cpp(290) : OPENFILENAME is small size (3 extra items are NOT included)
In Visual Studio 2005, _WIN32_WINNT is defined:
Compiling... XFolderDialog.cpp ...\src\XFolderDialog.cpp(66) : _WIN32_WINNT = 0x0500 ...\src\XFolderDialog.cpp(280) : OPENFILENAME is large size (3 extra items are included)
This software is released into the public domain. You are free to use it in any way you like, except that you may not sell this source code. If you modify it or extend it, please to consider posting new code here for everyone to share. 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.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 25 Feb 2008 Editor: Sean Ewington |
Copyright 2005 by Hans Dietrich Everything else Copyright © CodeProject, 1999-2009 Web22 | Advertise on the Code Project |