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.