Class to select directory

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

. 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.

Download file (2KB)

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read