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

CXSBrowseFolder - A Simple Class to Encapsulate SHBrowseForFolder

By , 19 May 2002
 

Sample Image

Introduction

As most of you probably know the shell function SHBrowseForFolder is easy to use, but there are a few things that have to be done every time that hardly ever change. One example is having to free the ITEMIDLIST pointer returned by the shell after the folder/file path is queried with SHGetPathFromIDList. My class takes care of that for you, and it automatically sets up default values for other parameters. 

Here's an example of using CXSBrowseFolder taken from the demo application:

        
// Create class 
CXSBrowseFolder foo; 

// Use the new style dialog
foo.ModifyStyle(BIF_NEWDIALOGSTYLE, 0);

// Set the dialog's title text
foo.SetTitle("This is the title text. Use CXSBrowseFolder::SetTitle() to set it:");

// Buffer for the returned path
char path[MAX_PATH];

// Display the dalog and check the return code
switch (foo.Show(GetSafeHwnd(), path)) {

    // Success
    case CXSBrowseFolder::RET_OK:
    MessageBox(path, "You Selected", MB_ICONINFORMATION | MB_TOPMOST);
    break;

    // User clicked cancel
    case CXSBrowseFolder::RET_CANCEL:
    MessageBox("Operation cancelled.", "Info", MB_ICONINFORMATION | MB_TOPMOST);
    break;

    // The shell did not return a path for the selection
    case CXSBrowseFolder::RET_NOPATH:
    MessageBox("The shell did not return a path for the selected item!", 
               "Uh Oh", MB_ICONSTOP | MB_TOPMOST);
    break;

}

This class is very simple, but here is an overview of the methods:

 

DWORD CXSBrowseFolder::GetStyle()

Description:
Returns the current style of the dialog

Paramerters:
None

Return:
The current style of the dialog (refer to the SHBrowseForFolder docs for style information)

 

DWORD CXSBrowseFolder::ModifyStyle(DWORD add, DWORD remove = 0)
Description:
Adds and/or removes styles from the dialog. (See shell docs for available styles)

Parameters:
add
style(s) to add
remove (optional)
style(s) to remove

Return:
Current style (after modifications)

 

void CXSBrowseFolder::SetTitle(LPSTR title)

Description:
Sets the text displayed above the tree view in the dialog.

Parameters:
title
The text to be displayed

Return:
None

 

CXSBrowseFolder::retCode CXSBrowseFolder::Show(HWND parent, LPSTR pathBuffer)

Description:
Shows the folder/file browse dialog with the current settings.

Parameters:
parent
HWND of a parent for the dialog
pathBuffer
Buffer that will be filled with the path information of the selected file/folder

Return:
CXSBrowseFolder::RET_CANCEL
User clicked the dialog's cancel button
CXSBrowseFolder::RET_NOPATH
The shell did not return a valid path for the selection
CXSBrowseFolder::RET_OK
The OK button was pressed and pathBuffer should contain a valid path

 

This class doesn't support customizing the dialog, but Microsoft doesn't recommend that with the new dialog style anyway because it's resizeable.

Well, that's about it for this article. I hope you find this simple class as useful and time saving as I have.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Dana Holt
Software Developer (Senior) Xenos Software LLC
United States United States
Member
I started learning C and 68K assembly language on an Atari ST around 1985 or so using the Mark Williams compiler. I was instantly hooked.
 
My favorite languages are: C/C++, C#, Ruby, and Python.
 
My first PC clone was a 386SX-25MHz with 4MB of RAM. OMG | :OMG:

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   
GeneralThank you, very usefulmemberLeifUK1 Jan '11 - 11:42 
Title says it all.
QuestionHow to add starting folder....memberpige3 May '07 - 22:34 
Hi,
 
If you need like me to add a starting folder, you have to add these few lines.
 
First, in XSBrowseFolder.h, you have to change the class like this:
 
class CXSBrowseFolder
{
public:
// Displays the dialog
CXSBrowseFolder::retCode Show(HWND parent, LPSTR pathBuffer, LPCTSTR pathDirSel=NULL);
 
private:
static INT CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};
 

Then, in XSBrowseFolder.cpp:
 
// Displays the dialog
CXSBrowseFolder::retCode CXSBrowseFolder::Show(HWND parent, LPSTR pathBuffer, LPCTSTR pathDirSel)
{
// Passed in a NULL pointer (!)
ASSERT(pathBuffer);

// Return value for the function
retCode ret = RET_OK;
 
LPITEMIDLIST itemIDList;
 
// Set up the params
BROWSEINFO browseInfo;
 
// The dialog must have a parent
ASSERT(parent);
 
browseInfo.hwndOwner = parent;
browseInfo.pidlRoot = m_root;
browseInfo.pszDisplayName = m_displayName;
browseInfo.lpszTitle = m_title;
browseInfo.ulFlags = m_style;
if (pathDirSel!=NULL)
{
browseInfo.lpfn = (BFFCALLBACK) BrowseCallbackProc;
browseInfo.lParam = (LPARAM)pathDirSel;
}
else
{
browseInfo.lpfn = NULL;
browseInfo.lParam = 0;
}

// Show the dialog
itemIDList = SHBrowseForFolder(&browseInfo);
 
// Did user press cancel?
if (!itemIDList)
ret = RET_CANCEL;
 
// Is everything so far?
if (ret != RET_CANCEL) {

// Get the path from the returned ITEMIDLIST
if (!SHGetPathFromIDList(itemIDList, pathBuffer))
ret = RET_NOPATH;

// Now we need to free the ITEMIDLIST the shell allocated
LPMALLOC shellMalloc;
HRESULT hr;
 
// Get pointer to the shell's malloc interface
hr = SHGetMalloc(&shellMalloc);
 
// Did it work?
if (SUCCEEDED(hr)) {
 
// Free the shell's memory
shellMalloc->Free(itemIDList);
 
// Release the interface
shellMalloc->Release();
 
}
}

return ret;
}
 

INT CALLBACK CXSBrowseFolder::BrowseCallbackProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case BFFM_INITIALIZED:
SendMessage(hWnd, BFFM_SETSELECTION, TRUE, lParam);
break;
}
return 0;
}
 
With these few lines, you can now when you call CXSBrowseFolder, you have just to add in third parameter the folder name... like this:
 
CString message("Select your directory"));
CString pathDirSelection("C:\\WINDOWS\\SYSTEM32"));
 

// Create class
CXSBrowseFolder foo;
 
// Use the new style dialog
foo.ModifyStyle(BIF_NEWDIALOGSTYLE, 0);
 
// Set the dialog's title text
foo.SetTitle((char*)(LPCTSTR)message);
 
// Buffer for the returned path
char path[MAX_PATH];
 
// Display the dialog and check the return code
// Start at the folder specified (pathDirSelection)
if (foo.Show(GetSafeHwnd(), path, (LPCTSTR) pathDirSelection) == CXSBrowseFolder::RET_OK)
{
UpdateData(TRUE);
 
UpdateData(FALSE);
}
 

 
Adil TIADI
 
Adil TIADI
adil.tiadi@hotmail.fr
GeneralRegarding CXSBrowseFoldermemberjk403205 Apr '07 - 1:42 
Excellent .......... nothing to say other than this....
GeneralWinCememberJoe ce00113 Dec '05 - 20:07 
Is this portable to wince?
GeneralWindows 2000memberluniv040418 Oct '05 - 4:44 
I have used this in windows 2000 on Visual Studio 6 and it work. The only thing is i get a generic folder locator dialog. I didnt get that nice dialog shown above.
 
Chris
GeneralRe: Windows 2000memberThe_Mega_ZZTer24 Oct '05 - 12:07 
Perhaps all the features in the current Folder Browser weren't incorporated until XP. Check the MSDN docs on SHBrowseForFolder?
GeneralNew Dialog StylememberCasper7022 Jan '03 - 7:43 
An enhancement might be added checking the Shell32.dll version for the
CXSBrowseFolder::ModifyStyle function.
The BIF_NEWDIALOGSTYLE flag requires Version 5.0 or greater.
GeneralRe: New Dialog StylememberDana Holt10 May '03 - 13:50 
I'll try to get that in the next update, but I have no idea how long that will be as I am super-busy at the moment.
 
--
Dana Holt
Xenos Software
GeneralWorked...goodsussAnonymous26 Aug '02 - 8:20 
Confused | :confused:
 
that class worked..but after i removed a line from it...
but one thing...why it is slow..????..
it takes some time to read from hard disk...also it takes about 5,382 KB of RAM...
GeneralRe: Worked...goodmemberDana Holt28 Aug '02 - 15:11 
Anonymous wrote:
that class worked..but after i removed a line from it...
but one thing...why it is slow..????..
it takes some time to read from hard disk...also it takes about 5,382 KB of RAM...

 
Which line did you have to remove? I have only tested it with XP Pro so far. I plan to add some more enhancements. The class is pretty bare now.
 
This is just a wrapper class for the Window's Shell API, so any slowness is coming from Windows.
 
As to the RAM question, as I said before, I am just wrapping the shell's API, so Windows is the one eating all the memory. Also, the task manager is not an accurate guage of process memory usage.
 
Check out this article:
http://codeproject.com/system/howbig.asp[^]
 

 
--
Dana Holt
Xenos Software

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

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 20 May 2002
Article Copyright 2002 by Dana Holt
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid