Browse for Multiple Files and Folders
An article on a Browse Dialog which helps you to select multilple files and folders.
Introduction
This code snippet will show you how to select multiple files and folders by adding a custom dialog box to your project. There are built-in controls in MFC to select a folder (SHBrowseForFolder
) or a file (CFileDialog
), but you cannot select multiple folders or files using these controls. Here, I am giving you a dialog box; you can call it from your application, and can select multiple files and folders at a time.
This article will also give you an idea about:
- How to edit your resource (.rc and Resource.h) file
- How to extract the system icon list
- How to traverse through the folder structure of Windows
How to use the code
Here, you have to do a little job. It is an MFC application and uses a dialog, so you have to manually edit your .rc and Resource.h files, and also your App class. So, let's start to use the code..
- Copy the BrowseDlg.h and BrowseDlg.cpp files to your project folder.
- Change the project header file of BrowseDlg.cpp from
#include "BrowseForFiles.h"
to your project header file. - Change the name of the App class that is used in the BrowseDlg.cpp from
extern CBrowseForFilesApp theApp;
to your App class. Repeat it wherever it occurs. - Open your project header file, and add the following lines as public members:
CImageList m_ImgList; CList<CString,CString&> MainDirList;
- Then, open your project .cpp file and add the following lines to
InitInstance()
before beginning the execution of your code:HIMAGELIST hSystemSmallImageList; SHFILEINFO ssfi; //get a handle to the system small icon list hSystemSmallImageList = (HIMAGELIST)SHGetFileInfo( (LPCTSTR)_T("c:\\"), 0, &ssfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX | SHGFI_SMALLICON); m_ImgList.Attach(hSystemSmallImageList);
- Then, open your Resource.h file and take care while editing. Add the following lines to the list of
#define
s:#define IDD_BROWSE 129 #define IDC_PATH 1002 #define IDC_DRIVE 1003 #define IDC_FILES 1004 #define IDC_UP 1005
Here, you must take care to avoid duplication of constants. For example, if 129 or 1003 or any of the above numbers already exists, then you must modify the numbers to a new one that is not allocated by any other controls. Here, the best idea is to find the highest three digit number from your file and give it to
IDD_BROWSE
. And find the highest four digit number and assign it toIDC_PATH
, and assign the numbers to the above controls with an increment of one. For example, if 1023 is the highest number assigned to controls, then modify the above values as follows:#define IDC_PATH 1024 #define IDC_DRIVE 1025 #define IDC_FILES 1026 #define IDC_UP 1027
So you have added controls to the Resource file. Now, modify the
APISTUDIO
defined constants also, as follows:Give the highest three digit value plus one (+1) to the following variable:
#define _APS_NEXT_RESOURCE_VALUE 130
Give the highest four digit value plus one (+1) to the following variable:
#define _APS_NEXT_CONTROL_VALUE 1028
These variables are used by
APISTUDIO
when you add new controls to the project. - Then, open your .rc file in text mode and add the following code to the Dialog section:
IDD_BROWSE DIALOG DISCARDABLE 0, 0, 212, 214 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Add Files and Folders" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,112,188,50,14 PUSHBUTTON "Cancel",IDCANCEL,48,187,50,14 EDITTEXT IDC_PATH,7,165,200,16, ES_AUTOHSCROLL | ES_READONLY COMBOBOX IDC_DRIVE,76,13,29,125, CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP CONTROL "List1",IDC_FILES,"SysListView32", LVS_REPORT | WS_BORDER | WS_TABSTOP,7,29,200,122 LTEXT "Drive",IDC_STATIC,51,16,18,8 LTEXT "Path",IDC_STATIC,7,155,16,8 PUSHBUTTON "UP",IDC_UP,114,13,20,14 END
And also add the following code to the
DESIGNINFO
section:IDD_BROWSE, DIALOG BEGIN LEFTMARGIN, 7 TOPMARGIN, 7 BOTTOMMARGIN, 207 END
So the BrowseDlg
is ready to use. Call the dialog wherever you want as follows:
CBrowseDlg dlgBrowse; dlgBrowse.DoModal();
After completing execution of the dialog, you will get the selected list of files in the app variable named MainDirList
. You can retrive the contents of the CList
as follows:
POSITION position; // Your App class extern CTestBrwsApp theApp; int iCnt = theApp.MainDirList.GetCount(); position = theApp.MainDirList.GetHeadPosition(); for(i = 0; i < iCnt; i++ ) { //m_SelectedList is simply a CListCtrl m_SelectedList.AddString((CString) theApp.MainDirList.GetNext(position)); }
So we completed the job. If you have any doubts, please refer to the sample project provided with this article.