article

Browse for folder with a Quick Pick

Email
Submitted on: 1/8/2015 4:38:00 AM
By: Lars Werner (from psc cd)  
Level: Intermediate
User Rating: By 2 Users
Compatibility: C++ (general), Microsoft Visual C++
Views: 2682
 
     Customized version of the "Browse for folder" dialog. It creates quick picks to your selected directories.

This article has accompanying files

 
				

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 to customize 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 a MFC project or Win32. (The project has only been tested with the VS6.0 environment. I don't know if it would work on the never 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="");
Funcition Show results 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 
int APIENTRY WinMain(HINSTANCE hInstance,
 HINSTANCE hPrevInstance,
 LPSTR lpCmdLine,
 intnCmdShow)
{
 	// TODO: Place code here.
	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 are the defines list:
//#1
#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
//#2
//This is the message that we start with
#define BROWSE_MESSAGE			10101
//#3
//The name of our hypertext class
#define STATIC_HYPERTEXT_WINDOW_CLASS	"STATIC_HYPERTEXT"
//#4
//This is the font & size we use for showing the info
#define BROWSE_FONTNAME			"Verdana"
#define BROWSE_FONTSIZE			12
//#5
//The colors used
#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)
//#6
//The registry variables
#define BROWSE_REGISTRY_ROOT		HKEY_CURRENT_USER
#define BROWSE_REGISTRY_PATH		"Software\\DirBrowser"
//#7
//Strings used
#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" //Must not exceed 79 chars!!!
Each group are explained below:
Group #1
Defines Description Default value
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 is 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. Splitted 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 your 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 on 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 on 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;
	}
It shouldn't be any errors on this, but after some research I noticed that the first part of the if-sentence is the only one that get called. I needed to split them to avoid this bug like this:
	if(pMe->MessageIsOdd == FALSE)
	{
		//...
	}
	if(pMe->MessageIsOdd == TRUE)
	{
		//...
	}
If someone have a good answer on this, please let me know. I'm using VS6.0 C++ with SP5 + UINT64 Processor pack Patch.

History

v1.0 - Inital release

winzip iconDownload article

Note: Due to the size or complexity of this submission, the author has submitted it as a .zip file to shorten your download time. Afterdownloading it, you will need a program like Winzip to decompress it.Virus note:All files are scanned once-a-day by Planet Source Code for viruses, but new viruses come out every day, so no prevention program can catch 100% of them. For your own safety, please:
  1. Re-scan downloaded files using your personal virus checker before using it.
  2. NEVER, EVER run compiled files (.exe's, .ocx's, .dll's etc.)--only run source code.

If you don't have a virus scanner, you can get one at many places on the net including:McAfee.com


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this article (in the Intermediate category)?
(The article with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments


 There are no comments on this submission.
 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular article, please click here instead.)
 

To post feedback, first please login.