. Lot of you may recognize
him from the lots of helpful posts on the mfc usenet groups.
CDirDialog : this class encapsulates the SHBrowseForFolder API. You can
use this class to browse for folders. I had seen many posting asking this
question. So, I put together this small wrapper class. In order to use it ,
Set the title by setting the text in m_strTitle. If you dont set this the
title will have “Open”.
Set the initial directory to start from using m_strInitDir. If you dont set
this, it will start from desktop.
Then call DoBrowse (). If it returns TRUE, you can see the m_strPath for
the selected directory. If it returns FALSE, user has dismissed the dialog
with a cancel OR there was some problem retrieving the folder. I have not
put in any error code. If, somebody wants to they are welcome to do it.
//////////////////////////////////////////////////////////////////////// // DirDialog.h: interface for the CDirDialog class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_DIRDIALOG_H__62FFAC92_1DEE_11D1_B87A_0060979CDF6D__INCLUDED_) #define AFX_DIRDIALOG_H__62FFAC92_1DEE_11D1_B87A_0060979CDF6D__INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 class CDirDialog { public: CDirDialog(); virtual ~CDirDialog(); int DoBrowse (); CString m_strPath; CString m_strInitDir; CString m_strTitle; int m_iImageIndex; }; #endif // !defined(AFX_DIRDIALOG_H__62FFAC92_1DEE_11D1_B87A_0060979CDF6D__INCLUDED_) /////////////////////////////////////////////////////////////////////////// // DirDialog.cpp: implementation of the CDirDialog class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "DirDialog.h" #include "shlobj.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CDirDialog::CDirDialog() {//////////////////////////////////////////// } CDirDialog::~CDirDialog() {/////////////////////////////////////////// } int CDirDialog::DoBrowse () {///////////////////////////////////////// LPMALLOC pMalloc; if (SHGetMalloc (&pMalloc)!= NOERROR) { return 0; } BROWSEINFO bInfo; LPITEMIDLIST pidl; ZeroMemory ( (PVOID) &bInfo,sizeof (BROWSEINFO)); if (!m_strInitDir.IsEmpty ()) { OLECHAR olePath[MAX_PATH]; ULONG chEaten; ULONG dwAttributes; HRESULT hr; LPSHELLFOLDER pDesktopFolder; // // Get a pointer to the Desktop's IShellFolder interface. // if (SUCCEEDED(SHGetDesktopFolder(&pDesktopFolder))) { // // IShellFolder::ParseDisplayName requires the file name be in Unicode. // MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, m_strInitDir.GetBuffer (MAX_PATH), -1, olePath, MAX_PATH); m_strInitDir.ReleaseBuffer (-1); // // Convert the path to an ITEMIDLIST. // hr = pDesktopFolder->ParseDisplayName(NULL, NULL, olePath, &chEaten, &pidl, &dwAttributes); if (FAILED(hr)) { pMalloc ->Free (pidl); pMalloc ->Release (); return 0; } bInfo.pidlRoot = pidl; } } bInfo.hwndOwner = NULL; bInfo.pszDisplayName = m_strPath.GetBuffer (MAX_PATH); bInfo.lpszTitle = (m_strTitle.IsEmpty()) ? "Open":m_strTitle; bInfo.ulFlags = BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS; if ((pidl = ::SHBrowseForFolder (&bInfo)) == NULL) { return 0; } m_strPath.ReleaseBuffer (); m_iImageIndex = bInfo.iImage; if (::SHGetPathFromIDList(pidl,m_strPath.GetBuffer (MAX_PATH)) == FALSE) { pMalloc ->Free (pidl); pMalloc ->Release (); return 0; } m_strPath.ReleaseBuffer (); pMalloc ->Free (pidl); pMalloc ->Release (); return 1; }
Enhancement
This enhancement was sent by Lars Klose.
I downloaded Girish Bharadwaj’s wrapper class for SHBrowseForFolder,
CDirDialog, a few days ago. Because it seems useful to me to set the
selected folder to a default value other than ‘desktop’ when the
dialog opens, I extended Girish Bharadwaj’s implementation with a
callback function that sets the selected folder when the dialog is
initialized. It’s set to the value stored in the new member variable
m_strSelDir or defaults to ‘desktop’ if m_strSelDir was not set.
The attached zip contains the changed files DirDialog.h and .cpp.