Class to select directory

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



Comments

  • Thank you!

    Posted by Legacy on 02/05/2004 12:00am

    Awesome work! I've tried for hours to send those callback messages without any result! Keep the great work!

    Jenya.

    Reply
  • Terrific!

    Posted by Legacy on 12/06/2003 12:00am

    Originally posted by: Tommy S.

    Thanx man!

    You just saved me alot of time that I now intend to spend
    in bed with my girlfriend ;)


    Reply
  • Nice work. Thanks.

    Posted by Legacy on 08/22/2003 12:00am

    Originally posted by: MT

    I appreciate the work.  Easily integrated in my project in just a few minutes.  Easily expandable.  Thanks for the organization.
    
    

    MT

    Reply
  • Great but doesn't show other computers on network

    Posted by Legacy on 01/16/2003 12:00am

    Originally posted by: Standa

    Hi, I use that class and I'm satisfied, but what doesn't work for me, is that I cant browse through computers on network, even when I browse them eg. with Servant Salamander or with Windows Explorer. When I want to expand "Other Computers" (or how is it written in english), it doesn't show me any computer...

    Does anybody know how to solve this ??

    Thanks Standa.

    Reply
  • useful class.. but wrong class design

    Posted by Legacy on 10/23/2002 12:00am

    Originally posted by: Juice

    this class is useful. but had wrong design

    this class have not initial method, too..

    what's wrong?

    for example, I can't specify owner window...

    kkkkk...

    Reply
  • Just to say THANKS for an excellent contribution

    Posted by Legacy on 07/29/2002 12:00am

    Originally posted by: Darren

    Reply
  • very good ,I had made some change too!

    Posted by Legacy on 11/14/2001 12:00am

    Originally posted by: zzg_han

    I want to use this class not use MFC,so I change some thing
    of it.But it had give me some Ideas.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Today's agile organizations pose operations teams with a tremendous challenge: to deploy new releases to production immediately after development and testing is completed. To ensure that applications are deployed successfully, an automatic and transparent process is required. We refer to this process as Zero Touch Deployment™. This white paper reviews two approaches to Zero Touch Deployment--a script-based solution and a release automation platform. The article discusses how each can solve the key …

  • On-demand Event Event Date: October 29, 2014 It's well understood how critical version control is for code. However, its importance to DevOps isn't always recognized. The 2014 DevOps Survey of Practice shows that one of the key predictors of DevOps success is putting all production environment artifacts into version control. In this webcast, Gene Kim discusses these survey findings and shares woeful tales of artifact management gone wrong! Gene also shares examples of how high-performing DevOps …

Most Popular Programming Stories

More for Developers

RSS Feeds