Tutorial: Adding a Custom Place to CFileDialog

Posted by Matt | Filed under , , , ,

Earlier versions of Microsoft Windows and Microsoft Office introduced the idea of "Places":  shortcuts along the left side of the File Open and File Save dialogs.

Windows Vista completely changed the common file dialogs and when they did that, they moved the common file dialogs to be COM objects.  If you look at the CFileDialog class which comes with Visual Studio 2008 (and maybe Visual Studio 2005 with the Vista service pack), you'll notice that internally it attempts to use the COM object if it's present, and if the COM object is not present, it reverts to the old mechanism.

The Vista COM object allows customization of the common file dialogs, including adding a custom "Place" to the shortcuts on the left side of the dialog.

  1. First, you need to get the IFileOpenDialog interface from the CFileDialog object.
    CFileDialog dlg(TRUE);
    IFileOpenDialog *p = dlg.GetIFileOpenDialog();
  2. Next, you need to create (or have available) an IShellItem-derived object.  Depending on what type of place you want to add, you could use SHCreateItemInKnownFolder, SHCreateItemFromParsingName, or any number of other functions.
    IShellItem *pItem = NULL;
    HRESULT hr = SHCreateItemInKnownFolder(FOLDERID_Documents, 
        0, L"My Place", IID_PPV_ARGS(&pItem));
  3. Then you need to add your IShellItem to the dialog as a place.
    p->AddPlace(pItem, FDAP_TOP);

The following sample adds a sub-directory of the user's Documents folder to the top of the Places on the File Open dialog in Vista (note that I am using CComPtr as smart pointers for my COM objects):

// Create your dialog and get the COM interface
CFileDialog dlg(TRUE);
IFileOpenDialog *p = dlg.GetIFileOpenDialog();
if (p != NULL)
{
    CComPtr<IFileOpenDialog> pDlg;
    pDlg.Attach(p);

    // Create the item we want to add
    // In this case, Documents\My Place
    CComPtr<IShellItem> pItem;
    HRESULT hr = SHCreateItemInKnownFolder(FOLDERID_Documents, 
        0, L"My Place", IID_PPV_ARGS(&pItem));
    if (SUCCEEDED(hr))
        pDlg->AddPlace(pItem, FDAP_TOP);
}

// Run the dialog normally
int result = dlg.DoModal();

Some additional notes:

  • Your place must exist in the file system otherwise it won't be added.
  • You can add a place to the File Save dialog by getting the IFileSaveDialog interface instead, but otherwise, it's the same code.
  • You can add a place relative to a known folder with SHCreateItemInKnownFolder.
  • You can add any place in the file system using SHCreateItemFromParsingName.
  • The CFileDialog constructor has an additional parameter to specify whether to attempt to use the Vista dialog.  This must be set to True.

Comments

August 6, 2008 18:01

trackback

Trackback from DotNetKicks.com

DotNetKicks.com

Comments are closed