Click here to Skip to main content
13,835,388 members
Click here to Skip to main content
Add your own
alternative version


38 bookmarked
Posted 26 Apr 2003
Licenced CPOL

Selecting a Subfolder from a Particular Folder

, 23 Feb 2010
Rate this:
Please Sign up or sign in to vote.
Restricting the user to browse and select from a particular folder
Sample Image - BrowsePF.jpg


The Shell API function SHBrowseForFolder displays a dialog box that enables the user to select a Shell folder. The dialog box allows the user to select any folder because its root folder is Desktop (which contains My Documents, My Computer and My Network Places). Some applications need to restrict the user in the selection of folders. Restricting the selection for My Computer or My Network Places is easier. But restricting the user for a particular folder requires little manipulation.


The function SHBrowseForFolder takes a pointer to the structure BROWSEINFO. This structure has eight members. One of the members,  pidlRoot, is a pointer to the structure ITEMIDLIST. If pidlRoot is NULL, the root folder is Desktop. One can use pre-defined CSIDL values such as CSIDL_MYDOCUMENTS, CSIDL_NETWORK, etc. If any other arbitrary folder is to be used as root folder, it should be appropriately converted to the structure ITEMIDLIST

The class CFoldersDialog puts the whole code for SHBrowseForFolder dialog. The function ConvertPathToLpItemIdList converts an arbitrary folder into ITEMIDLIST. This class can be used in MFC as well as SDK without making any changes. It can also be used in VC++.NET.

The function ConvertPathToLpItemIdList takes an arbitrary folder as string type input parameter. It first converts the string to OLECHAR. Then SHGetDesktopFolder function retrieves IShellFolder interface and calls the method ParseDisplayName. This method puts the OLECHAR form of root folder into ITEMIDLIST structure.

Using the Code

The function BrowseFolder is called from any other class by creating an object of CFoldersDialog. It first uses the function ConvertPathToLpItemIdList for converting string to ITEMIDLIST and then use its callback function BrowseCallbackProc.

LPITEMIDLIST ConvertPathToLpItemIdList(const char *pszPath)
	OLECHAR       olePath[MAX_PATH];
	ULONG         chEaten;
	HRESULT       hr;

	if (SUCCEEDED(SHGetDesktopFolder(&pDesktopFolder)))
		MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszPath, -1, 
					olePath, MAX_PATH);
		hr = pDesktopFolder->ParseDisplayName(NULL, NULL, 
					olePath, &chEaten, &pidl, NULL);
		return pidl;
	return NULL;

int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pData) 
		   // Set the status window to the currently selected path.
		   if (SHGetPathFromIDList((LPITEMIDLIST) lp, szDir)) 
			  SendMessage(hwnd,BFFM_SETSTATUSTEXT, 0, (LPARAM)szDir);
        case BFFM_INITIALIZED:
            SendMessage(hwnd, BFFM_SETSELECTION, 1,(LPARAM) szDir);

	return 0;

int CFoldersDialog::BrowseFolder(HWND hWnd, CString RootPath)
	LPMALLOC pMalloc;
	int nRet = 0;

	if (SUCCEEDED(SHGetMalloc(&pMalloc))) 
		bi.hwndOwner = hWnd;
		bi.pszDisplayName = 0;
		bi.lpszTitle = 0;
        char *pszRootPath = new char[RootPath.GetLength() + 1];
        wcstombs(pszRootPath, RootPath, RootPath.GetLength());
		bi.pidlRoot = ConvertPathToLpItemIdList(pszRootPath);
		if (bi.pidlRoot == NULL)
			nRet = 1;
		bi.lpfn = BrowseCallbackProc;

		pidl = SHBrowseForFolder(&bi);
		if (pidl) 
			nRet = 2;
	return nRet;

Points of Interest

The callback function displays the user selected subfolder at the top of the dialog. Once the user click the OK button, the folder value is transferred to the second text box in the first dialog box. The variable szDir is accessed from both CFoldersDialog and the calling class.


  • First version 1.0: April 27, 2003
  • Second version 2.0: February 22, 2010
    • Fixed bugs
    • Added Unicode support
    • Compiled demo project with Visual Studio 6, 2005, 2008 and 2010


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


About the Author

Ahamad Alisha
India India
Ahamad has done M.Tech. in Information Technology. He has 15 years software development experience. He started learning programming with GW-BASIC. He learnt COBOL, Pascal, Fortran, C, C++, Java and C#. He worked with DOS, Unix, Novel Netware and Windows platforms. He has been working on Microsoft technologies for the last 10 years. He worked with .NET, Visual C++, ATL COM/DCOM, Win SDK, MFC, WTL, Visual Basic, ASP, JavaScript, XML, OOAD and Rational Rose. He has written three books on Computer Science:

1. Programming in GW-BASIC, BPB Publications, New Delhi, 1993
2. Computer Science with C++, Allied Publishers, New Delhi, 1997
3. Introduction to C++, Allied Publishers, New Delhi. 1998

He enjoys playing badminton and musical keyboards in his spare time. He also participates in community activities. He can be reached by

You may also be interested in...

Comments and Discussions

QuestionSet initial dir, and still be able to browse to parent folders. Pin
JPB77721-Sep-07 5:47
memberJPB77721-Sep-07 5:47 
AnswerRe: Set initial dir, and still be able to browse to parent folders. Pin
jpm24729-Nov-07 22:38
memberjpm24729-Nov-07 22:38 
GeneralFinding a digital camera folder Pin
Alex Evans13-Feb-05 20:44
memberAlex Evans13-Feb-05 20:44 
GeneralHelp with accessing folder Pin
vgandhi13-Jun-03 9:33
membervgandhi13-Jun-03 9:33 
GeneralSome bugs Pin
Anders Dalvander27-Apr-03 10:03
memberAnders Dalvander27-Apr-03 10:03 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web06 | 2.8.190114.1 | Last Updated 24 Feb 2010
Article Copyright 2003 by Ahamad Alisha
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid