Click here to Skip to main content
Click here to Skip to main content

How to Browse for a Folder

By , 16 Feb 2006
 

Introduction

This article presents a no-frills, cut-n-paste solution to the age-old problem of browsing for a folder. There are several classes out here that offer much more customization and a plethora of features, but I'm sure one more example won't hurt.

When to use this solution

The benefit of this approach over some of the others here is that this implementation is a direct wrapper function for SHBrowseForFolder. As such, you can use it in console applications that don't use MFC, such as unit-testing applications that could benefit from not hard-coding an output location for test results.

So, in short, if you're looking for eye candy, check out XFolderDialog or some of the other folder dialogs here. Otherwise, read on.

Using the code

To use this code, you need to include the following standard files:

#include "shlobj.h"
#include <string>

The GetFolder function

Params

  • folderpath - A reference to the string that will contain the folder path if successful.
  • szCaption - An optional message for the dialog.
  • hOwner - An optional handle to the parent window.

Returns

  • true if successful, false if cancelled or an error occurs.
bool GetFolder(std::string& folderpath, 
               const char* szCaption = NULL, 
               HWND hOwner = NULL)
{
   bool retVal = false;

   // The BROWSEINFO struct tells the shell 
   // how it should display the dialog.
   BROWSEINFO bi;
   memset(&bi, 0, sizeof(bi));

   bi.ulFlags   = BIF_USENEWUI;
   bi.hwndOwner = hOwner;
   bi.lpszTitle = szCaption;

   // must call this if using BIF_USENEWUI
   ::OleInitialize(NULL);

   // Show the dialog and get the itemIDList for the 
   // selected folder.
   LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);

   if(pIDL != NULL)
   {
      // Create a buffer to store the path, then 
      // get the path.
      char buffer[_MAX_PATH] = {'\0'};
      if(::SHGetPathFromIDList(pIDL, buffer) != 0)
      {
         // Set the string value.
         folderpath = buffer;
         retVal = true;
      }

      // free the item id list
      CoTaskMemFree(pIDL);
   }

   ::OleUninitialize();

   return retVal;
}

Conclusion

Well, that's really all there is to it. If this code saves time for even one person out here, then the few minutes spent writing this was well worth it. Enjoy!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Nitron
Software Developer (Senior) Barbnet Investment Co.
United States United States
Member
Walter Storm is currently a principal software engineer doing quantitative research for a private hedge fund. Originally from Tunkhannock, PA., he has a B.S. in Aerospace Engineering from Embry-Riddle Aeronautical University[^], and an M.S. in Systems Engineering from SMU[^]. He has been professionally developing software in some form or another since January of 2001.
 
View Walter Storm's profile on LinkedIn.[^]

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberPhat (Phillip) H. VU17 Jan '13 - 14:54 
Good job.
You saved my effort.
Thanks.
GeneralMy vote of 5memberMember 14304116 Jul '10 - 20:07 
very tiny and cute code.
GeneralMFC - UNICODE Versionmemberexp2lnt19 Oct '08 - 17:20 
bool GetFolder(CString& csFolder, CString csCaption = NULL, HWND hWndOwner = NULL)
{
bool bSuccess = false;

// The BROWSEINFO struct tells the shell
// How it should display the dialog.
BROWSEINFO browseInfo;
memset(&browseInfo, 0, sizeof(browseInfo));
 
browseInfo.ulFlags = BIF_USENEWUI;
browseInfo.hwndOwner = hWndOwner;
browseInfo.lpszTitle = csCaption;
 
// Must call this if using BIF_USENEWUI
::OleInitialize(NULL);
 
// Show the dialog and get the itemIDList for the selected folder.
LPITEMIDLIST pIDL = ::SHBrowseForFolder(&browseInfo);
 
if(pIDL != NULL)
{
// Create a buffer to store the path, then get the path.
TCHAR lpzTempFolder[MAX_PATH + 1];
if(::SHGetPathFromIDList(pIDL, lpzTempFolder) != 0)
{
bSuccess = true;
}
 
// Free the item id list
CoTaskMemFree(pIDL);
csFolder = lpzTempFolder;
}
 
::OleUninitialize();
 
return bSuccess;
}
 
Hope this helps,
theme
GeneralThanksmemberpapa_coder18 Mar '06 - 8:41 
The code was just what I wanted - simple to use and works great. Your time in doing the article and code helped me and I appreciate it! I programmed from Fortran through many languages - a lot of code - but always non-GUI data-in > data-out type tasks. As an engineer that took up Visual C++ and MFC and GUI tasks after retirement, I rely on the WEB for a lot of help ... and The Code Project (and others) come through again and again.
GeneralRe: ThanksmemberNitron4 Apr '06 - 5:12 
papa_coder wrote:
Your time in doing the article and code helped me and I appreciate it!

 
well for that it's worth it! glad it helped!
 
~Nitron.
ññòòïðïðB A
start

Questionbigger path?membereXplodus16 Feb '06 - 19:54 
what about a path longer then MAX_PATH?
like unc network pathes?
 
is there also a solution?
AnswerRe: bigger path?memberNitron17 Feb '06 - 5:13 
That should work, just make the char buffer big enough to take it. I used MAX_PATH just for convienence.
 
~Nitron.
ññòòïðïðB A
start

GeneralRe: bigger path?membereXplodus19 Feb '06 - 20:53 
uhm, i thought i tried it with MAX_PATH*2 buffer size and it doesnt make any sense...
i think shbrowseforfolder works only with a MAX_PATH size...
GeneralRe: bigger path?memberGalatei22 Feb '06 - 7:43 
As MSDN states, the path buffer must be at least MAX_PATH characters in size.
Use TCHAR instead of char in order to allocate output buffer.
You can also allocate it dynamically in order to be more polite to the memory.
 
Regards
QuestionPossible to preset a specific folder?memberChristof Schardt16 Feb '06 - 11:38 
I couldn't yet find a way to preset the box to a specific folder. If you have deep nested folders and want to go ub/down just one or two levels, it is annoying to have to walk down rather than starting at a certain folder.
 
Does anyone know a possibility to achieve this?
 
Thanks
Christof
 


General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 16 Feb 2006
Article Copyright 2006 by Nitron
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid