Home Search Contact us About us
Title Using SHBrowseForFolder.
Summary When the user is required to select a folder or path the SHBrowseForFolder function id a way to do this. This note provides a simple method for using some of its features.
Contributor John McTainsh
Published 30-Sep-2000
Last updated 30-Sep-2000
Page rating   88% for 12 votes Useless Brilliant

Description.

The SHBrosweForFolder is not a simple function to call to this article provides a sample that should cover most requirements. In particular it covers setting the initial path and display the path as the user selects it which not as straight forward as you might expect.

What to do.

Start by adding support for the Shell32 API including the following StdAfx.h

#include <shlobj.h>
Next add the following callback and usage code where the call is to be made.
//////////////////////////////////////////////////////////////////////////////
//The call back is used to set the initial directory and
//display the selected path in thhe top of the box.
int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData) 
{
    TRACE( _T("BrowseCallbackProc(0x%x,%d,%p,%p)\n"), hwnd, uMsg, lp, pData );
    TCHAR szDir[MAX_PATH];
    
    switch(uMsg) 
    {
    case BFFM_INITIALIZED: 
        //Initial directory is set here
        strcpy( szDir, _T("c:\\temp") );
        {
            // WParam is TRUE since you are passing a path.
            // It would be FALSE if you were passing a pidl.
            SendMessage(hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)szDir);
        }
        break;
    case BFFM_SELCHANGED: 
        // Set the status window to the currently selected path.
        if( SHGetPathFromIDList( (LPITEMIDLIST)lp ,szDir ) ) 
        {
            SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);
        }
        break;
    default:
        break;
    }
    return 0;
}



//////////////////////////////////////////////////////////////////////////////
//This is where the file dialog is to be used
void CSHBrowseForFolderDlg::OnButton1() 
{
    LPMALLOC pMalloc;
    
    if( SUCCEEDED( SHGetMalloc( &pMalloc ) ) ) 
    {
        TCHAR szTitle[] = _T("Blah blah... this is quite cool stuff.");
        BROWSEINFO bi;
        ZeroMemory( &bi, sizeof( bi ) );
        bi.hwndOwner = NULL;
        bi.pszDisplayName = NULL;
        bi.lpszTitle = szTitle;
        bi.pidlRoot = NULL;
        bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_EDITBOX;
        bi.lpfn = BrowseCallbackProc;
        
        LPITEMIDLIST pidl = SHBrowseForFolder( &bi );
        if( pidl ) 
        {
            TCHAR szDir[MAX_PATH];
            if( SHGetPathFromIDList( pidl, szDir ) ) 
            {
                MessageBox(szDir,"Picked",MB_OK);
            }
            else
            {
                TRACE( _T("ERROR : SHGetPathFromIDList failed at %s, %d\n"), 
                    __FILE__, __LINE__ );
            }
            pMalloc->Free(pidl); 
            pMalloc->Release();
        }
        else
        {
            TRACE( _T("User selected Cancel\n") );
        }
    }
    else
    {
        TRACE( _T("ERROR : SHGetMalloc failed at %s, %d\n"), 
            __FILE__, __LINE__ );
    }
}
Comments Date
What about the initial path? 1-Dec-2003 Tom Isaacson
This example doesn`t set the initial path because pidlRoot is not set. How do you do this?
Home Search Contact us About us