File tree control allowing selection of multiple files and folders






4.90/5 (57 votes)
MFC tree control showing the files in a manner similar to the left-hand side of Windows Explorer, but allowing selection of multiple files and folders for further processing in your program
Introduction
The provided CFileTreeCtrl is the MFC tree control, showing files in a manner similar to the left-hand side of Windows Explorer. Contrary to Windows Explorer, however, it allows the selection of multiple files and folders for further processing in your program. You can do this using the check boxes to the left of every file and folder. When selecting a folder, you can specify whether to include or not include the files from the subfolders. At any time, you can request that the control give you the lists of selected files and folders. You can also get information on how many files are selected in any folder.
States of check boxes
The following states of check boxes are supported:
the folder does not contain any files
the folder or file is not selected
the file is selected
all the files from the folder are selected, including the files of some subfolders
all the files from the folder are selected, including the files from all subfolders
all the files from the folder are selected, excluding the files from all subfolders
some files in the folder are selected, files from subfolders are not
some files in the folder are selected, as well as from all subfolders
some files in the folder are selected, as well as from some subfolders
the files from all subfolders are selected, but no files in the folder itself
the files from some subfolders are selected, but no files in the folder itself
You can toggle through the states of check boxes, clicking on the item with a mouse.
Implementation of CFileTreeCtrl
- Add the standard Tree Control to your dialog box or form view. Make sure it has check boxes style enabled. Use the More Styles tab in Tree Control properties.
- Add a new bitmap resource into your project and name it
IDB_STATE
. The BMP file for this resource is included with the source files. It includes 16 images for different states of check boxes. 5 of them are empty, though. - Then you can derive a new class from
CFileTreeCtrl
if you don't want to include all of the files into the control, but only the files of a specific type. To do this, in your derived class you need to override the virtual functionMatchExtension.
See below for details. - After this, you need to use the Class Wizard to add a member variable for the Tree Control resource to your dialog class. Then go to the header file for the dialog and change the type of this variable in the
AFX_DATA
section fromCTreeCtrl
to the name of yourCFileTreeCtrl
derived class.
CFileTreeCtrl class members
Here, I will describe only the public members of CFileTreeCtrl
and the virtual function MatchExtension
. The function of others you can guess from the source code.
BOOL DisplayTree()
Call this function to fill your file tree control with files. Usually, it is done in OnInitDialog()
or in OnInitialUpdate()
. The function returns true
, if successful.
void AddHidFolder(int nFolder, CString strPath="")
Call this function before calling DisplayTree()
to tell the control not to display certain folders. You can specify either the CSIDL
identifier of the special folder (using nFolder
), or the full path to the folder (using strPath
; in this case, nFolder
should be 0
). Usually, you don't want to show the Recycle Bin and the Control Panel. So, add these lines to your program before calling DisplayTree()
:
// m_FileTree is the member variable for the Tree Control
m_FileTree.AddHidFolder(CSIDL_BITBUCKET);
m_FileTree.AddHidFolder(CSIDL_CONTROLS);
CString GetInfo(HTREEITEM hItem)
Gets the string of information on how many files and folders are selected in the folder. This is indicated by hItem
, the handle to the item of Tree Control. The string is returned in this format: "Files: 15; Dirs: 22; SelFiles: 0; SelDirs: 0; PartDirs: 3", where Files
is the total number of files in a folder, Dirs
is the total number of subfolders, SelFiles
is the number of selected files, SelDirs
is the number of fully selected subfolders and PartDirs
is the number of partially selected subfolders. If the item is a file or folder that has not been expanded yet, all the elements are -1
. For example, to get the info on the currently selected folder, you can use:
m_strText = m_FileTree.GetInfo(m_FileTree.GetSelectedItem());
int GetSelectedFiles(CString* &SelFiles)
Returns the number of the selected files. The SelFiles
parameter points to the array of strings containing the full names of all selected files. The memory for the array is allocated inside the GetSelectedFiles
, but you need to delete it yourself using delete[] SelFiles
.
int GetSelectedFolders(CString* &SelFolders)
Returns the number of the selected folders that have not been expanded yet. The SelFolders
parameter points to the array of strings containing the full names of the selected folders without the closing "\". The first character of the returned strings indicate the type of the selection: "f" means only files within the folder (), "F" means only subfolders (
) and "A" means all the files and all the subfolders (
). The memory for the array is allocated inside
GetSelectedFolders
, but you need to delete it yourself using delete[] SelFolders
.
CString GetSelectedFile()
Returns the string containing the full name of the currently selected item in the File Tree Control.
virtual bool MatchExtension(CString file)
Override this virtual function in your CFileTreeCtrl
derived class in case you don't want to include all the files into the control, but only the files of a specific type. The function gets the name of the file; it should return true
if the file should be included and false
otherwise. For example, if you want to show only EXE files, do the following:
bool CMyFileTreeCtrl::MatchExtension(CString file)
{
CString strTemp = file.Right(4);
if (!strTemp.CollateNoCase(".EXE")) return TRUE;
return FALSE;
}
If you do not want to show files at all, but only folders, override the function as follows:
bool CMyFileTreeCtrl::MatchExtension(CString file)
{
return FALSE;
}
Acknowledgement
I would like to thank Johnson Zhou and PJ Naughter. I used some portions of their code in my class. I have also used one of the samples in MSDN and took the major portions of code from there, but now, unfortunately, I do not remember exactly which sample I used. I could have probably used the code of some other members of CodeProject, too. If you see your code in my source, tell me and I will include you in the Acknowledgement section. Thanks to all the members and the staff of the Code Project! You are all doing the wonderful job of making programming fun!
History
- 19 January, 2006 -- Original version posted
- 4 June, 2007 -- Article edited and posted to the main CodeProject.com article base