Introduction

Usually, when we need to add file/folder-browse features to our projects, we
have to do quite some trivia: first we must create a CEdit which
will display the path name, then we need to create a CButton and
handle its ON_BN_CLICKED event to launch the
CFileDialog and copy the path name to the CEdit.
Furthermore, if we want to make it look nice, we will have to include some icon
or bitmap resources to decorate the CButton. It could cause some
headache if we have multiple dialogs which all need the file/folder-browse
feature on them.

I have been thinking that it would be nice if there was such a control in
MFC, which integrates a CEdit and a CButton on it,
handles the control events, pops up the CFileDialog and updates
CEdit text automatically. And it'd be even nicer if that control
has some built-in images, that is, it has its own drawing capability without
requiring us to provide any image resource to it. And of course, some tooltips
wouldn't hurt... Unfortunately, there's no such control in MFC, but fortunately
we can always make our own.

CBrowseCtrl is made for meeting the exact needs I described in
the above paragraphs. It derives from CButton, has an editbox, a
browse button and a tooltip on it. It can draw some built-in images on the
browse button as well, so you don't need to include any icon or bitmap resources
for this control. It handles button events by itself so whenever the user clicks
on the browse button, a file/folder dialog pops up.

How to Use

You need to add source files BrowseCtrl.h and BrowseCtrl.cpp to
your workspace first, and include BrowseCtrl.h wherever needed. To create
the control, you can either use CBrowseCtrl::Create to create one
at runtime, or draw a CButton on the dialog template and bind it
with a CBrowseCtrl variable.

Code Samples

Specifying Control Styles

You may access the control styles anytime to change its appearance and
behavior. Multiple style flags may be combined using the "|"
operator. The valid style flags are:

Flag

Effects

BC_CTL_ALLOWEDIT

Allows user to type in the editbox

BC_CTL_FOLDERSONLY

Browse for folders instead of files

BC_BTN_LEFT

Display the browse button on the left-side of the
editbox

BC_BTN_FLAT

Use flat button style

BC_BTN_ICON

Use icon, no text will be displayed

BC_ICO_ARROWFOLDER

The arrow-folder icon, must be combined with
BC_BTN_ICON

BC_ICO_FOLDER

The folder icon, must be combined with
BC_BTN_ICON

BC_ICO_EXPLORER

The Windows Explorer icon, must be combined with
BC_BTN_ICON

To set the "Windows Explorer" icon on the browse button, make the button
flat, and finally, make the control "Browse for Folders" only:

Browsing for Files and Folders

CBrowseCtrl handles the button events by itself so whenever the
user clicks on the browse button, a file or folder dialog is popped up
automatically. You can, of course, programmatically handle it in your code also,
usually you may want to initialize the file dialog using whatever you would pass
into the CFileDialog constructor. CBrowseCtrl provides
a set of functions to allow doing the same initialization, you basically can
just treat the control as a dialog:

Notifying the Parent Window

After the file/folder dialog is closed by the user, a notifying message is
sent to the parent window. The wParam is either IDOK
or IDCANCEL, the lParam is a pointer to this
CBrowseCtrl object.

To make the control notify the parent window, you need to provide
CBrowseCtrl a custom window message which is greater than 0. If the
message you provide is 0, the message will not be sent. If you do not provide
any message, no message will be sent either.

May 22, 2004

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Very good control but i have encountered a small problem.
When i open the dialog box with a CBrowseCtrl for first time, ant then i try to change to other application pressing 'Alt'+'Tab', when i push the key 'Alt', the browse control is redrawn like a normal button.
Passing the mouse over the control, it is redrawn again like a browse control.
If i push again 'Alt' key the control remains like a browse control and nothing happens. It only changes at the first push of the 'Alt' key.
Could you test this bug?
Thanks in advance.

Yeah i spent a little while trying to figure that out as well. Easiest way (although kinda ugly....i'm also a newb) is to go to download source and header files to a separate directory, go to the dialogue view, right click and go to class wizard.(Using Visual Studios 6). Click on the add class button, and select new. In the name box type CBrowseCtrl and the file name field should automatically update to BrowseCtrl.cpp. Select Button as the base class and click ok. After this open the downloaded BrowseCtrl cpp and h files, copy all the text and relpace the code in the BrowseCtrl cpp and h files created by the class wizard....and you're done. It should compile. Every time you add a button on the dialog editor you should be able to select either a CButton or CbrowseCtrl variable and you're away.

thanks that got me a little farther definately wouldn't have figured that one out. When I drag a button over to the dialog where should I see an option to change it to a CbrowseCtrl? Also, when creating a button this way does it handle all of the initialization etc or do I still need to insert code to handle any events? I apologize if this sounds idiot. I'm coming from the unix side of the house and anything windows is clear a mud at the moment

I'm using Visual C++ 2008 Express Edition and I can't seem to get this to work. I added the class to the project, copy and pasted all the codes into the right files, typed "Button" into the base class, and whenever I add a button to the Form, it doesn't work. Please help. Thanks.

What do you actually mean by multiple browse buttons? If you refer to having more than one controls on a dialog then all you need to do is creating multiple CBrowseCtrl windows, or drawing multiple buttons on design view and assigning them with CBrosweCtrl type.

I am wondering if there is a small piece of code that acheives the very basic task of exploring files and folders ? I once used the open common dialog,and it was very simple, the problem i don't remember it now. can anyone help me, i need to open files into my project, but don't want complicated code because i'm not very experienced with VC.Thanks in advance

Hi,
I have been using CBrowseCtrl and now when I switch to Release mode. I find that it crashes my program. I know that it is related to this class because if I create and use my own dialog to select a file then, nothing crashes. I'm still trying to figure out what is wrong. Does anyone else have this problem?

I love the control, but am having a problem with the font being too large and bold when using CBrowseCtrl::Create. When I bind a CBrowseCtrl variable to a button, the font is fine. Any help will be appreciated.
Thanks,
Bob

I believe that when you use CWnd::Create to create a window(a CButton object is a window, too) you will need to specify it with your desired font, otherwise it will just use your "system" font, which, usually look big and bold.

There's a small bug in GetNextPathName() which allows the return of an empty string *before* the pos variable is set to NULL. The fix is quite simple. Just replace the GetNextPathName() method as follows:

Very nice control, but I experimented a problem when I try to use it in Visual Studio .NET 2002. In particular, when I use the debug configuration, there is an heap error when pszLargeBuffer is deleted in FileDoModal() and the same for "delete [] m_lpszPathNames".
In release configuration it'a all right.
There is a method to fix it?

I personally do not use VC.net at all so I can't say much about your problem, I rechecked the code in that function but couldn't find any thing that may lead to the error, maybe you could try to add pszLargeBuffer = NULL; and m_lpszPathNames = NULL; after the delete [] statements? Just a guess. Please lemme know if anything new happens.