Folder/Drive Picker Combo Box



There are three main things that this CFolderComboBox class does. First, the class displays text with bitmap images in a hierarchical display. Second, the class gets all of the drives on a system using _chdrive to determine if a drive is present. Finally, the CFolderComboBox returns the relative path of a selected folder or drive.

SETUP

In order to use this class in your own project, you must be sure to add the bitmap resources (one for normal and one for disabled) for the different folders to your project. You will have to name the file Folders.bmp as IDB_FOLDERS in the resource file and you will have to name Folders_Disabled.bmp as IDB_FOLDERS_DISABLED in the resource file as well. When adding a combo box to your project, please make sure the following styles are set:

1) Has Strings should be checked.
2) Set to Owner Draw Fixed
3) Turn off sort

The rest of the defaults should be OK. In addition, please be sure to define the following resource strings which are loaded to fill up the combo box.

IDS_DOCUMENTFOLDERS	Document Folders
IDS_PERSONAL		My Documents
IDS_FAVORITES		My Favorites
IDS_PATH		System Path
IDS_DESKTOP		Desktop
IDS_FONTS		Fonts
IDS_MYCOMPUTER		My Computer
IDS_SYSTEMFOLDERS	System Folders
IDS_LOCALHARDRIVES	Local Hard Drives

After that, add the source files (FolderCombo.h and FolderCombo.cpp) to your project. Next, add the #include FolderCombo.h directive to your source file. Then create a class variable of type CFolderComboBox. The only actual code you will have to call is GetSelectedPathName which will return a CString with the pathname of the selected folder. If no item is selected, an empty CString will be returned. If you selected a folder that contains subfolders (for example, My Computer), this will return all paths separated by semicolons (e.g. C:\;D:\;E:\, etc.). By the way, if you want to disable the control, the painting for this is handled automatically.

This code was compiled with Visual C++ 6.0. I didn't test it with UNICODE, but it should work. Also, I didn't test this on anything but Windows 98, but it should work on Windows 95. If you modify this code at all to support some of the 5.0 version of the Shell CSIDL constants, please note that this won't work on systems that don't have this Shell version. The Visual C++ documentation has the definitions of all of the different CSIDL constants.

BACKGROUND

The internal structure of the CFolderComboBox is shown here:

typedef struct SFolder
{
  int m_iImageIndex;      // Index of picture in image list
  int m_iIndent;          // Indentation index
  CString m_sFolderName;  // Descriptive name of folder
  CString m_sPathName;    // Actual full pathname of folder(s)

} SFOLDER, *LPSFOLDER;

To determine if a Windows 95/98 standard folder exists, the following code fragment was used:

if(SUCCEEDED(SHGetSpecialFolderPath(NULL, szPath,
CSIDL_PERSONAL, FALSE)))
{
// Do something now that we have the
// "My Documents" directory
}

To get the actual relative pathname of the selected item, a call to GetSelectedPathName() is all that is needed. This will return a CString with the relative pathname of the selected folder location.

AFTERTHOUGHTS

Please note that this class could definitely be upgraded. There are still some features that are missing, and some that could be enhanced, such as the following:

1) Ability to get actual network names instead of just drive letters. That is, every item in Network Neighborhood that doesn't necessarily have a drive attached. Maybe specify by a flag how it should handle network drives.

2) Ability to draw the bitmap in the text box area of the combo box as well as in the drop-down list.

3) Create a special highlite bitmap in addition to the standard and disabled bitmaps that shows the correct masked image when and item is selected. In fact, using only one standard bitmap, and then masks for different states could also be done.

4) Unlike Windows, this class does not no if the hardware changed (i.e. disk insert or remove). It could be upgraded to rescan the drives when the hardware changes, or it could be continually done in a background thread.

5) I didn't use all of the CSIDL constants for standard Windows folders. Some more could be added, as well as the shell32 5.0 specific constants.

6) And of course, it could always be optimized. When the CFolderComboBox is initialized, it attempts to _chdrive to the floppies, which of course makes an annoying sound if no floppy is in the drive. The drives could be added without really scanning them.

Download demo project - 32 KB

Download source - 6 KB