Click here to Skip to main content
15,880,972 members
Articles / Desktop Programming / MFC
Article

CYABFFW: Yet Another BrowseForFolder Wrapper

Rate me:
Please Sign up or sign in to vote.
2.97/5 (10 votes)
12 Jun 20073 min read 73K   1.2K   11   14
Yet another wrapper for the ::BrowseForFolder function

CYABFFW in action

Introduction

YABFFW (Yet Another BrowseForFolder Wrapper) is a CWnd subclass wrapping the Shell API SHBrowseForFolder() in an MFC-friendly way. There are certainly others out there, but the approach taken here (in my opinion) integrates more cleanly into MFC apps. I also believe that it makes it easier to customize the appearance and behavior of the dialog box.

Background

Sooner or later, we all need to display a dialog allowing the user to select a directory. A search in MSDN turns up the function ::SHBrowseForFolder() (<shlobj.h>). The next step is usually to either write or steal a C++ class that wraps up the C-style function call in a more MFC-friendly way.

At least, that's what happened to me. In my case, I needed to customize the dialog a bit, too. Specifically, I wanted to add a little checkbox to it labeled "Recurse" and retrieve that checkbox's value after the user dismissed the dialog. So, I started surfing the web looking for examples. I found several -- C++ wrappers, as well as examples of customizing the "Browse for Folder" dialog -- and happily started copying them. However, as I implemented the code I began to see a cleaner and more extensible way to accomplish my task. CYABFFW is the product of that process.

Using the code

What makes CYABFFW different is that it is a CWnd that subclasses the "Browse for Folder" dialog right after creation. This gives the class access to things like Message Maps, CObject diagnostics, DDX/DDV and so on. It also gets us out of calling ::SetWindowLong, writing a WndProc and suchlike. Of course, it commits you to MFC. If you're not using MFC, CYABFFW won't be of much use to you. The source code is shown below, although you can of course download it along with a sample project.

How do I use it?

In the simplest case, CYABFFW looks and acts just like most MFC dialog classes. You instantiate it on the stack, call DoModal() and then check the return value to see what the user did. Once the user hits "OK," you can retrieve the item they selected by calling either GetPath() or GetItemIdList(), depending on whether you want the selection as a path or an ITEMIDLIST. For example:

C++
CYABFFW dlg();
if (IDOK == dlg.DoModal())
{
    CString s = dlg.GetPath();
    // Do something with `s' ...

SHBrowseForFolder() allows quite a bit of customization of the dialog's appearance and behavior. You do this by filling out a BROWSEINFO struct that is passed to the function. I've tried to expose all of the functionality provided by SHBrowseForFolder() in a way more familiar to C++ programmers. The first point of extension is the CYABFFW constructor. There are several constructors, each taking an array of parameters that control the resulting dialog. For a full list, refer to the source code. Here's an example, however:

C++
CYABFFW dlg(_T("Please select a directory"), // Hint to user
            BIF_USE_NEWUI,                   // Flags for the dlg
            this,                            // Parent window
            CSIDL_DRIVES);                   // Root of search
if (IDOK == dlg.DoModal())
{
    CString s = dlg.GetPath();
    // Do something with `s' ...

If you want to customize the dialog beyond what you can do with arguments to the constructor, you'll need to subclass CYABFFW. CYABFFW defines three virtual functions that can be overridden: OnInitBFFDialog(), OnBFFSelChanged() and OnBFFValidateFailed(). These correspond to the custom messages that SHBrowseForFolder() sends to its optional callback function BFFM_INITIALIZED, BFFM_SELCHANGED, BFFM_VALIDATEFAILED. Of course, you can also Message Map entries to your subclass and process any Windows messages you're interested in. The demo project includes an example of doing this to add my "Recurse" checkbox.

Setting the initial selection

One question that came up after I posted the first version of this article was how to set the initial selection for the dialog. Microsoft KB article 179378 recommends handling the BFFM_INITIALIZED notification and sending yourself the BFFM_SETSELECTION message. I decided to build out the support for this: CYABFFW constructors now take an optional default selection and CYABFFW::OnInitBFFDialog() will handle setting the selection appropriately. Therefore, if you subclass CYABFFW and override OnInitBFFDialog, make sure you call the base class implementation, too.

History

  • Date posted: May 7, 2005.
  • Date first update: May 10, 2005.
  • Date second update: June 12, 2007.

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.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
flute99910-Oct-19 7:04
flute99910-Oct-19 7:04 
GeneralCompile Time Error...error C2039: error C2065: Pin
wasif_Muhammad12-Feb-07 21:19
wasif_Muhammad12-Feb-07 21:19 
GeneralRe: Compile Time Error...error C2039: error C2065: Pin
Sp1ff13-Feb-07 6:57
Sp1ff13-Feb-07 6:57 
Generaldefault selection Pin
Tibi_Kron15-Dec-06 4:36
Tibi_Kron15-Dec-06 4:36 
GeneralRe: default selection Pin
Sp1ff14-Jan-07 11:43
Sp1ff14-Jan-07 11:43 
Generali like it... Pin
sps-itsec466-Dec-06 7:17
sps-itsec466-Dec-06 7:17 
Generalfounder of SHGetFolderLocation Pin
Anonymous30-May-05 23:16
Anonymous30-May-05 23:16 
GeneralRe: founder of SHGetFolderLocation Pin
Sp1ff4-Jun-05 12:47
Sp1ff4-Jun-05 12:47 
QuestionPlagiarism? Pin
Rasqual Twilight19-May-05 7:01
Rasqual Twilight19-May-05 7:01 
AnswerRe: Plagiarism? Pin
Sp1ff19-May-05 7:08
Sp1ff19-May-05 7:08 
GeneralRe: Plagiarism? Pin
Rasqual Twilight19-May-05 15:53
Rasqual Twilight19-May-05 15:53 
AnswerRe: Plagiarism? Pin
Panic2k32-Jul-05 7:45
Panic2k32-Jul-05 7:45 
Generalwon't compile Pin
Stober17-May-05 3:01
Stober17-May-05 3:01 
GeneralRe: won't compile Pin
Sp1ff17-May-05 3:34
Sp1ff17-May-05 3:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.