Click here to Skip to main content
Email Password   helpLost your password?

Introduction

As I mentioned in my other article "CIconDialog - Selecting Icons", while developing a wizard application, I needed a dialog to select an icon from executables and another one for selecting folders on multiple ones, but did not find anything about in MFC. So, CFolderDialog was written. It wraps the ::SHBrowseForFolder API.

Sample Usage

Sample Image

The CFolderDialog is derived from CCommonDialog and acts like any common dialog. See sample usage:

//...

#ifndef __FOLDERDLG_H__
    #include "FolderDlg.h"

#endif
// ...

void CSomeDialog::OnSomeHandler( void ) 
{ 
    m_strFolderPath = _T( "d:\\Windows" ); // Just for sample    

    m_strDisplayName.Empty();
    
    CFolderDialog dlg(  _T( "Dialog Title" ), m_strFolderPath, this );
    if( dlg.DoModal() == IDOK  )
    {    
        m_strFolderPath  = dlg.GetFolderPath();
        m_strDisplayName = dlg.GetFolderDisplayName();
        // Use folder path and display name here ...

    }    
}
//

Sample Image

See demo project source for more.

Setting the Root Folder

You can also set the root folder of the dialog, specifying the location of the root folder from which to start browsing. Only the specified folder and any subfolders that are beneath it in the namespace hierarchy will appear in the dialog box.

Sample Image

See sample usage:

//...

#ifndef __FOLDERDLG_H__
    #include "FolderDlg.h"

#endif
// ...

void CSomeDialog::OnSomeHandler( void ) 
{
    CFolderDialog dlg( _T( "Root folder is C:\" ), NULL, this );
    dlg.SetRootFolder( _T( "C:\\" );
    
    if( dlg.DoModal() == IDOK  )
    {       
        // ...
    }
}
//

Sample Image

Thanks to Eckhard Schwabe and Jose Insa for that sample.

Custom Filtering

Under Microsoft� Windows� XP/2003 or later, you can do custom filtering on the contents of the dialog box.

Sample Image

To create a custom filter, follow these steps:

  1. Set the BIF_NEWDIALOGSTYLE flag in the uFlags member of the CFolderDialog constructor. Override the OnIUnknown virtual member function in the derived class. On OnIUnknown, the function's pIUnknown parameter will contain a pointer to an instance of IUnknown. Call QueryInterface on that IUnknown to obtain a pointer to an IFolderFilterSite.
  2. Create an object that implements IFolderFilter - derive a class from it that implements all basic pure virtual member functions of IUnknown, and implement IFolderFilterSite::ShouldShow and IFolderFilterSite::GetEnumFlags functions, that do filtering.
  3. Call IFolderFilterSite::SetFilter (pointer to which you obtained in step 1), passing it a pointer to your custom IFolderFilter derived class. IFolderFilterSite::ShouldShow and IFolderFilterSite::GetEnumFlags methods can then be used to include and exclude items from the tree.
  4. Once the filter is created, the IFolderFilterSite interface is no longer needed. Call IFolderFilterSite::Release if you have no further use for it.

Sample Image

I have added a sample custom filtering (look at the picture, the dialog shows only "JPG/GIF/BMP" files in the tree). Thanks to Arik Poznanski for his article "C# does Shell, Part 1". For more information, please see the source code.

Class Members

Base Class

Data Members

Construction

Constructs a CFolderDialog object:

CFolderDialog( IN LPCTSTR pszTitle = NULL, IN LPCTSTR pszSelPath = 
      NULL, IN CWnd* pWndParent = NULL, IN UINT uFlags = BIF_RETURNONLYFSDIRS )

Operations

Overridables

Microsoft� Windows� XP/2003 or later:

Functions, that are valid to be called only from Overridables:

Shell version 5.0 or later:

Notes

If you convert this project to VC 7.0 or later, do not forget to add shlwapi.dll to the list of delay loaded DLLs because it uses ::StrRetToStr function of shlwapi.dll 5.0. Go to "[Project Properties]>[Configuration Properties]>[Linker]>[Input]" and add "shlwapi.dll;" to the list of "[Delay Loaded DLLs]". VC 6.0 project does this using "/DelayLoad" linker option, not supported under VC 7.0 or later.

Version History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralBug If initial folder can not be reached. [modified]
Member 3057688
22:42 17 Jan '10  
I found a problem: if initial path situated in some other network and you can not reach it, for example \\12.1.100.52\... then DoModal hangs up.

I solved it by adding a check for existance:

VOID CFolderDialog::SetSelection( IN LPCTSTR pszPath )
{
ASSERT( m_hWnd != NULL );
ASSERT( AfxIsValidString( pszPath, MAX_PATH ) );

// Dmitry Barovik. 18.01.2010. Add check for existence
if (PathFileExists(pszPath))
::SendMessage(m_hWnd, BFFM_SETSELECTION, (WPARAM)TRUE, (LPARAM)pszPath);
else
::SendMessage(m_hWnd, BFFM_SETSELECTION, (WPARAM)TRUE, (LPARAM)(_T("")));
}

modified on Monday, January 18, 2010 4:08 AM

GeneralRe: Bug If initial folder can not be reached.
Armen Hakobyan
4:14 19 Jan '10  
Thanks a lot
Soon I will update the articles and will include your fix with reference to you.

Armen

#define __ARMEN_H__

GeneralLinker Errors
Anur Ravi
8:52 30 Dec '09  
I added FolderDlg.h and FolderDlg.cpp and compiled my MFC Dialog project and i got these two linker errors on Visual C++ 2008.

1>Finished searching libraries
1>LINK : warning LNK4098: defaultlib 'mfc90u.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
1>LINK : warning LNK4098: defaultlib 'mfcs90u.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
1>LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library
1>Finished pass 1
1>Spatial_Vision_DisplayDlg.obj : error LNK2001: unresolved external symbol "public: __thiscall CFolderDialog::CFolderDialog(class ATL::CStringT<char,class StrTraitMFC_DLL<char,class ATL::ChTraitsCRT<char> > > *)" (??0CFolderDialog@@QAE@PAV?$CStringT@DV?$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@@Z)
1>U:\trunk\UI\Spatial_Vision_Display\Release\Spatial_Vision_Display.exe : fatal error LNK1120: 1 unresolved externals
1>Build log was saved at "file://u:\trunk\UI\Spatial_Vision_Display\Release\BuildLog.htm"
1>Spatial_Vision_Display - 2 error(s), 96 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

I rebuilt after a clean and got the same error.

Can you help me out?

Thanks,
GeneralHow to install filter for explorer?
nanfang
4:14 30 Dec '07  
What is the IUnKnown stand for? IShellBrower or IShellView?

Is there a way that filter the folder and file ,not only for CFileDialog?
Questionhow to use custom filter
EdwardChan
15:53 10 Oct '07  
i'm sorry. but i don't know how to use custom filter.
i want to know how can USE_XP_FILTRATION be defined.
i try to define USE_XP_FILTRATION in stdafx.h
but there is an error.
filteredfolderdlg.h(42) : error C2504: 'IFolderFilter' : base class undefined
please help me, thanks.

i'm in vc6.0
GeneralAuto start transfer from camera (MTP) to disk
andygm
0:36 27 Jul '07  
Hello All,

I often capture images from my camera to my PC's hard disk and develop applications to process them. Have you by any chance solved the two problems below that I am really struggling with?

1) I need to browse the contents of my MTP (Media Transport Protocol) supported Camera. Do you have a code exerpt to do that? All I am interested in is getting the list of image files on th camera and dumping them on my harddisk to a specified directory (My Pictures/date-time).

2) As I plug in my SD card or MTP (Media Transport Protocol) supported Camera I just want my application to start, and transfer the files. Do you know how to capture this "plugin" event in tha case of an SD Card and for a MTP (Media Transport Protocol) supported Camera? And read out the drive/device name?

Thanks a lot for your help in automating....

Andrea Smile

QuestionLicense
wjvdh
1:49 10 Jul '07  
Hi there, great class and thank you for writing it.

Is it possible to use this class in a commercial application?

Tnx.
AnswerRe: License
Armen Hakobyan
2:28 10 Jul '07  
Hello

Use it freely in any application but please specify credits if possible.

#define __ARMEN_H__

GeneralRe: License
wjvdh
2:34 10 Jul '07  
That's great. I'll have to look into where to put the credits, but I'm sure I can shoehorn them in somewhere Smile
QuestionStrRetToStr undeclared identifier
ddgsptntea
1:00 5 Jul '07  
Compiling...
FileTreeCtrl.cpp
D:\treecontroll\cobatree\FileTreeDialog\FileTreeCtrl.cpp(546) : error C2065: 'StrRetToStr' : undeclared identifier
Error executing cl.exe.

FileTreeDialog.exe - 1 error(s), 0 warning(s)

I need your help why it happen?

Dadang

Dadang
AnswerRe: StrRetToStr undeclared identifier
Armen Hakobyan
1:24 6 Jul '07  
May be u should get newer Platform SDK ?


#define __ARMEN_H__

GeneralHow to compile in Visual C++ 6.0
cristitomi
23:47 25 Mar '07  
Hi!
In order to successfuly compile the code in Visual C++ 6.0 you must do the following:
In BOOL CDemoDlg::OnInitDialog( VOID ) replace ULONG_PTR with ULONG, ::GetClassLongPtr with ::GetClassLong and ::SetClassLongPtr with ::SetClassLong.
The code should look like this:
BOOL CDemoDlg::OnInitDialog( VOID )
{
CDialog::OnInitDialog();
// Shadow for XP
ULONG ulStyle = ::GetClassLong( GetSafeHwnd(), GCL_STYLE );
if( !( ulStyle & CS_DROPSHADOW ) )
::SetClassLong( GetSafeHwnd(), GCL_STYLE, CS_DROPSHADOW );
........................................................................
That's all.
Best wishes,
Christian.

I am in love with VC++
AnswerRe: How to compile in Visual C++ 6.0
Armen Hakobyan
6:59 29 Mar '07  
May be it is better get newer Platform SDK Smile ?

#define __ARMEN_H__

GeneralRe: How to compile in Visual C++ 6.0
cristitomi
11:38 29 Mar '07  
Hi Armen!
Yes, you might be right. Perhaps it may be better to get the newer platform SDK but my solution was intended to make the code work without installing the new Platform SDK.
Anyway, thanks for the quick reply.
Best wishes,
Christian.

I am in love with VC++
GeneralHidding 'CWnd::m_hWnd' ..
rbid
0:54 4 Dec '06  
Hello,

First thanks for sharing the CFolderDialog code.

I noticed that it has a data member called 'm_hWnd' that "hides" the inherited member 'CWnd::m_hWnd'.

Is this on purpose or mistakeUnsure .



-- Ricky Marek (AKA: rbid) -- "Things are only impossible until they are not" --- Jean-Luc Picard
My articles

GeneralOn folder's content: enable/disable the Ok bttn
Le cosaque
3:00 12 Oct '06  
Enable the Ok button if the folder contains a particular file:


*****************************************************
FolderDlg.cpp
*****************************************************

Fix (CFolderDialog::EnableOK(..)):
*****************************************************
                     - ::SendMessage( m_hWnd, BFFM_ENABLEOK, (LPARAM)bEnable, 0L);
                     -> ::SendMessage( m_hWnd, BFFM_ENABLEOK, 0L, (LPARAM)bEnable);

Replace (in CFolderDialog::CFolderDialog(..)):
*****************************************************
                     -   At the end of CFolderDialog::CFolderDialog(..)
  
                        if( pszSelPath )
                   SetSelectedFolder( pszSelPath );
               By:
                        lstrcpy(m_InitialFolder,_T(""));
                 if ( pszSelPath )
                 {
                   if ( lstrlen(pszSelPath) < MAX_PATH )
                   {
                        lstrcpy( m_InitialFolder, pszSelPath );
                   }
                   SetSelectedFolder( m_InitialFolder );
                 }
                        m_bIsFileRequested = FALSE;

Add (at the end of CFolderDialog::OnSelChanged(..)):
*****************************************************
                     - UpdateOkButton(szSelFol);

Add (in CFolderDialog::OnIUnknown(..)):
*****************************************************
                     - UpdateOkButton(m_InitialFolder);

Add the following methods
*****************************************************
VOID CFolderDialog::UpdateOkButton( IN LPCTSTR szSelFol )
{
     // Look if the request filename exist under this path
     if ( m_bIsFileRequested )
     {
          TCHAR szFullPathName[MAX_PATH];
          if ( (lstrlen(szSelFol) + lstrlen(m_strRequestFileName) + 2) > MAX_PATH )
          {
               //Enable the Ok bttn in any cases
               EnableOK(TRUE);
               return;
          }

          lstrcpy( szFullPathName, szSelFol );
          lstrcat( szFullPathName, _T("\\") );
          lstrcat( szFullPathName, m_strRequestFileName );
          // Try to open the file
          FILE *hFile;
          if ( (hFile = _tfopen(szFullPathName,_T("r"))) != NULL )
          {
               // File exist, enable the Ok bttn!
               EnableOK(TRUE);
               Invalidate();
               RedrawWindow();
               fclose(hFile);
          }
          else
          {
               // File didn't exist, disable the Ok bttn!
               EnableOK(FALSE);
          }
     }
     else
     {
          //Enable the Ok bttn
          EnableOK(TRUE);
     }
}
BOOL CFolderDialog::SetRequestedFileName( IN LPCTSTR pszFileName )
{
     ASSERT( AfxIsValidString( pszFileName, MAX_PATH ) );
     if ( lstrcpy( m_strRequestFileName, pszFileName ) )
     {
          m_bIsFileRequested = TRUE;
          return (TRUE);
     }
     return (FALSE);
}
*****************************************************
FolderDlg.h
*****************************************************
Add private:
                     - BOOL m_bIsFileRequested;
                 - TCHAR m_strRequestFileName[ MAX_PATH ];
                     - TCHAR m_InitialFolder[ MAX_PATH ];
Add public:
                     - BOOL SetRequestedFileName( IN LPCTSTR pszFileName );


Ivan K.
AnswerRe: On folder's content: enable/disable the Ok bttn
Armen Hakobyan
5:36 18 Oct '06  
Thanks, will update the article soon Ivan Krukoff Smile


#define __ARMEN_H__

QuestionScroll flickering
ShiriA
8:25 24 Jul '06  
Is there any way to reduce the scroll flickering? I tried overriding the "OnMouseWheel" handler but it never seems to get called.

This is a great class Smile Thanks!
Questionhow about MTP (Media Transport Protocol) supported device
decang
5:38 11 Nov '05  
Thank you, this is really nice and helpful article .

I am working on a project that needs to browse into portable media devices (set root folder to browse only under particular device).
In general, if the device supports mass storage interface, it will be working perfect as a filesystem folder. However, I encounter problem with the "Portable Media Center" (such as, Creative Zen Portable Media Center) which is supporting MTP (Media Transport Protocol).

1. I have problem first at ParseDisplayName(), where I cannot even get a PIDL to the device root folder. Although I can see "+Zen Portable Media Center" under "My Computer" in Windows XP's File Explorer, but just cannot render it in the SHBrowseForFolder().
I tried to EnumObjects() and GetDisplayNameOf() from IShellFolder of MyComputer or Desktop, I do find the name of "Zen Portable Media Center", but when I use the parsing name (CLSID),
L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\Zen Portable Media Center"
to retrieve a PIDL, it fails all the time(E_INVALIDARG from ParseDisplayName).

2. then I tried to use "Portable Media Devices" under "Control Panel" as a root folder to browse into it. Problem is the SHBrowseForFolder() won't show any devices under "Portable Media Devices". (But the attached devices do show in Windows XP's File Explorer).

I almost gave up with using SHBrowseForFolder() for MTP supported devices. Just want to see if anyone could shed light with it.

Again, appreciate your efforts.

MTP in Windows Media Device Manager 10 SDK
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmdm10/htm/whatisnew.asp[^]
GeneralHow to get the folder path of "My Network Places" on SelChanged
Naru
15:47 21 Oct '05  
Hello,

I want to get network folder path like "\\NetworkPC\ShareFolder", but SHGetPathFromIDList returns string like
"C:\Documents and Settings\UserName\NetHood\ShareFolder - (NetworkPC)NetworkPC" ***OnSelChanged***. Confused

SHBrowseForFolder with BIF_RETURNONLYFSDIRS flag returns "\\NetworkPC\ShareFolder" but I want to get this in callback. Confused

Best Begards

GeneralRe: How to get the folder path of "My Network Places" on SelChanged
Naru
7:53 22 Oct '05  
Hi,

I sloved opening the shortcut file like "C:\Documents and Settings\UserName\NetHood\ShareFolder - (NetworkPC)NetworkPC\target.link" and then retrieve "\\NetworkPC\ShareFolder".

Thanks

GeneralAdaptation for a Matlab DLL
ohad gal
23:37 27 Aug '05  
Hello,

Thanks for the code, I was looking for an option to select a folder using copy-paste, which was never found in the browse-for-folder dialogs.

I ask your permission to post the adaptation of your code into a matlab DLL, in the Mathworks website (of course with credit for you)

Thanks,

Ohad Gal.
AnswerRe: Adaptation for a Matlab DLL
Armen Hakobyan
0:52 29 Aug '05  
Feel free to use it, better with credits Big Grin ).

#define __ARMEN_H__
GeneralRe: Adaptation for a Matlab DLL
Ohad Gal
14:25 31 Aug '05  
Posted:

www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=8391&objectType=FILE

Thanks again,
Ohad.
GeneralI dont see the "New Folder" button
Atewa
13:07 8 Apr '05  
Compiled and added everything alright. But the New Folder button does not show up. Any clues?

Thanks.


Last Updated 17 Feb 2005 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010