Introduction
I was working on the SizeMe project when a user requested a feature. He asked for a predefined list over directories that he wanted to scan. I just finished reading the article Customizing the "Browse for folder" dialog and I got the idea of just customizing the common dialog. Here is the result.
Remember that the common dialogs are shown in the installed language of Windows. The picture shows the dialog with my language Norwegian. I also want to thank Hans Dietrich for his article XBrowseForFolder - Wrapper for SHBrowseForFolder. Some of the code used in the project has been inspired by his work.
Using the Code
The project can be used in either an MFC project or Win32. (The project has only been tested with the Visual Studio 6.0 environment. I don't know if it would work on the newer versions of Visual Studio, but I guess so).
First add the files Dirbrowse.cpp and DirBrowse.h to your project, then include the DirBrowse.h. There are two public functions that you need to use:
BOOL Show(char *szInitDir="");
Function Show
results in TRUE
if the user pressed OK, and FALSE
on cancel/close. The szInitDir
is optional and selects the startdir for the browser.
char* GetSelectedDir();
Function GetSelectedDir
returns a string
with the selected path.
Sample
Here is the quick win32 sample I wrote for handling the class:
#include "stdafx.h"
#include "..\DirBrowse.h"
#include <stdio.h>
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
CDirBrowse m_dirbrowser(NULL, hInstance);
if(m_dirbrowser.Show()==TRUE)
{
char Text[MAX_PATH*2];
sprintf(Text, "You selected folder: %s", m_dirbrowser.GetSelectedDir());
MessageBox(NULL, Text, "Browse for folder", MB_OK);
}
else
{
MessageBox(NULL, "You pressed the cancel button!", "Browse for folder", MB_OK);
}
return 0;
}
It is as simple as that. Take a look at the project to check out the MFC version of the same.
Header Customization
When I create classes that can be reused, I always create a lot of #defines
. This class is no exception. Here is the define
s list:
#define BROWSE_WIDTH 640
#define BROWSE_HEIGHT 420
#define BROWSE_LISTVIEW_SIZE 0.65
#define BROWSE_BORDER_VERT 4
#define BROWSE_BORDER_HORI 2
#define BROWSE_MAXENTRIES 20
#define BROWSE_MESSAGE 10101
#define STATIC_HYPERTEXT_WINDOW_CLASS "STATIC_HYPERTEXT"
#define BROWSE_FONTNAME "Verdana"
#define BROWSE_FONTSIZE 12
#define BROWSE_SELECTCOLOR RGB(0,0,255)
#define BROWSE_SELECTCOLORHOVER RGB(50,105,255)
#define BROWSE_DIRCOLOR RGB(0,0,200)
#define BROWSE_DIRCOLORHOVER RGB(100,100,250)
#define BROWSE_REGISTRY_ROOT HKEY_CURRENT_USER
#define BROWSE_REGISTRY_PATH "Software\\DirBrowser"
#define BROWSE_TEXT_SHORTCUTS "Shortcuts"
#define BROWSE_TEXT_HELP "Please select a folder in the list and press the
arrow to save the directory for a quickpick later on"
#define BROWSE_TEXT_HELP_CAPTION "Browse for folder help"
#define BROWSE_TEXT_HELP_TOOLTIP "Press this to save selected path as a shortcut"
Each group is explained below:
Defines |
Description |
Default value |
Group #1 |
BROWSE_WIDTH , BROWSE_HEIGHT , BROWSE_LISTVIEWSIZE |
The WIDTH /HEIGHT is the size of the window. The ListView -size is the percentage of the width of the dirlist . |
640, 420, 0.65 (percentage of the width!) |
BROWSE_BORDER_VERT , BROWSE_BORDER_HORI |
The border variables are pixels between controls in vertical and horizontal direction. |
4,2 |
BROWSE_MAXENTRIES |
MaxEntries is the size of quick picks we can show on the screen (shouldn't be more entries than the screen can show) |
20 (should be enough for everybody) |
Group #2 |
BROWSE_MESSAGE |
Message is the internal message that we use for the controls. It is used increased, so it start on 10101 then 10102 and so on |
10101 |
Group #3 |
STATIC_HYPERTEXT_WINDOW_CLASS |
The Hypertext window class is just the internal name of the class handling the hypertext-class. Just change this if you have duplicated names in the project. |
"STATIC_HYPERTEXT " |
Group #4 |
BROWSE_FONTNAME , BROWSE_FONTSIZE |
This is the font & size used in the hypertext class. It will not check if the font actually exists, so be sure to enter a valid name. |
"Verdana", 12 |
Group #5 |
BROWSE_SELECTCOLOR , BROWSE_SELECTCOLORHOVER , BROWSE_DIRCOLOR , BROWSE_DIRCOLORHOVER |
Colors on the hypertext class. Split into the selector and the actually directory. |
RGB(0,0,255), RGB(50,105,255), RGB(0,0,200), RGB(100,100,250) |
Group #6 |
BROWSE_REGISTRY_ROOT , BROWSE_REGISTRY_PATH |
The path to where you want the config to be saved. This is usually changed since you don't want the dirbrowser to load variables stored in the same place in different projects where you use this. |
HKEY_CURRENT_USER , "Software\\DirBrowser" (This should always be changed!) |
Group #7 |
BROWSE_TEXT_SHORTCUTS , BROWSE_TEXT_HELP , BROWSE_TEXT_HELP_CAPTION , BROWSE_TEXT_HELP_TOOLTIP |
Since I haven't made a "Multilanguage" support in this project, you can change the text used here. |
"Shortcuts", "Please select a folder in the list and press the arrow to save the directory for a quickpick later on", "Browse for folder help", "Press this to save selected path as a shortcut" (Must not exceed 79 chars) |
Points of Interests
I found a little bug while compiling the release version of the project. Take a look at this code:
if(pMe->MessageIsOdd == FALSE)
{
if(nID % 2 == 0)
MsgIsOdd = FALSE;
else
MsgIsOdd = TRUE;
}
else
{
if(nID % 2 == 0)
MsgIsOdd = TRUE;
else
MsgIsOdd = FALSE;
}
There shouldn't be any errors in this, but after some research I noticed that the first part of the if
-sentence is the only one that gets called. I needed to split it to avoid this bug like this:
if(pMe->MessageIsOdd == FALSE)
{
}
if(pMe->MessageIsOdd == TRUE)
{
}
If someone has a good answer to this, please let me know. I'm using Visual Studio 6.0 C++ with SP5 + UINT64 Processor pack Patch.
History