Customize Places Bar in Common File Dialog

Since Windows 2000, the file common dialog was modified to display, on the left, a bar with shortcuts to different default directories. The good part is that this list can be modified, and modifying it does not involve any COM object, only some simple Registry tweaking. In this article, I will explain how to programmatically modify the Registry to display your own list of shortcuts in places bar of the file dialog.

System Settings

It turns out that the folders listed in the Places Bar are specified in Registry, under the HKEY_CURRENT_USER key. The path is:

Software\Microsoft\Windows\CurrentVersion\Policies\ComDlg32\PlacesBar

Folders can be specified in two ways:

  • Full path of the folder (type of value is REG_SZ, and data is a string with the path)
  • By IDs for a predefined list of folders (type of value is REG_DWORD, and data is an integer representing the ID of the predefined folder)

In the following image, you can see three entries: two integers indicating the Desktop (0) and My Documents (5) and a custom folder "D:\Cilu".

The name of the values must be of the form PlaceX , where X can have a value from 0 to 4, because a maximum of only five shortcuts are displayed on the Places Bar.

This key does not exist by default. The operating system tries to read this key before displaying a file dialog. If it doesn't find the key, it loads a default list of folders, the one you probably see on your file dialog. If, however, it finds it, the custom list is used.

This key is system wide. All the applications, except for the ones in the Microsoft Office suite, are affected. If you change (create, delete) this Registry key, all applications displaying a file dialog will have the Places Bar with those folders.

Note: To change the Places Bar for the Microsoft Office application, follow this Knowledge Base article, 826214.

List of IDs for Pre-Defined Folders

The following table displays the list of IDs of the pre-defined folders:

ID (hex) Predefined Folder
0Desktop
1Internet Explorer
2Start Menu\Programs
3My Computer\Control Panel
4My Computer\Printers
5My Documents
6<user name>\Favorites
7Start Menu\Programs\Startup
8<user name>\Recent
9<user name>\SendTo
a<desktop>\Recycle Bin
b<user name>\Start Menu
clogical "My Documents" desktop icon
d"My Music" folder
e"My Videos" folder
10<user name>\Desktop
11My Computer
12Network Neighborhood (My Network Places)
13<user name>\nethood
14Windows\Fonts
16All Users\Start Menu
17All Users\Start Menu\Programs
18All Users\Startup
19All Users\Desktop
1a<user name>\Application Data
1b<user name>\PrintHood
1c <user name>\Local Settings\Applicaiton Data (nonroaming)0x001d // nonlocalized startup
1eNonlocalized common startup
1fCommon favorites
20Internet Cache
21Cookies
22History
23All Users\Application Data
24GetWindowsDirectory()
25GetSystemDirectory()
26C:\Program Files
27C:\Program Files\My Pictures
28USERPROFILE
29x86 system directory on RISC
2ax86 C:\Program Files on RISC
2bC:\Program Files\Common
2cx86 Program Files\Common on RISC
2dAll Users\Templates
2eAll Users\Documents
2fAll Users\Start Menu\Programs\Administrative Tools
30<user name>\Start Menu\Programs\Administrative Tools
31Network and Dial-up Connections
35All Users\My Music
36All Users\My Pictures
37All Users\My Video
38Resource Directory
39Localized Resource Directory
3aLinks to All Users OEM specific apps
3bUSERPROFILE\Local Settings\Application Data\Microsoft\CD Burning

Application-Specific Change of Places Bar

As explained earlier, changing the Registry key Software\Microsoft\Windows\CurrentVersion\Policies\ComDlg32\PlacesBar affects all applications installed on a machine (except for the Office applications). If you only want a modified Places Bar for a specific application, a small hack into the Registry can be temporarily done to achieve that.

The Windows API function RegOverridePredefKey allows a programmer to map a pre-defined Registry key to a specified key. Thus, you can do the following:

  • Create a temporary key and map it for the HKEY_CURRENT_USER
  • Put the file dialog places there under Software\Microsoft\Windows\CurrentVersion\Policies\ComDlg32\PlacesBar
  • Display the file dialog
  • At the end, restore the predefined HKEY_CURRENT_USER and delete the temporary key

I have put all this together into a sample applications that allows you to select five custom places from the predefined folders list or any folder on disk. The application looks like the one in this screenshot:

Note: To select a custom folder, use the Browse... item at the bottom of each combo box item list.

Creating a temporary key and mapping it on HKEY_CURRENT_USER

The SnatchRegistry() function creates a temporary Registry key (in my application, called "MariusBancila") and calls RegOverridePredefKey to map it on HKEY_CURRENT_USER. It returns a handle to that key:

HKEY CDemoOpenFileDlg::SnatchRegistry()
{
   HKEY hTempKey;
   // create a temporary Registry key
   RegCreateKey(HKEY_CURRENT_USER, TEMP_REG_KEY, &hTempKey);
   // override the current user with the new created key
   RegOverridePredefKey(HKEY_CURRENT_USER, hTempKey);

   return hTempKey;
}

Customize Places Bar in Common File Dialog

Setting places and displaying the file dialog

The next step consists of creating the following path under the newly mapped key:

Software\Microsoft\Windows\CurrentVersion\Policies\ComDlg32\PlacesBar

Under this key, the places must be added—Place0, Place1, and so forth—either as integer values or strings. The implementation of this function is application dependent, but it should be quite straightforward:

void CDemoOpenFileDlg::SetPlacesAndDisplayDialog()
{
   // create a surrogate Registry key
   HKEY hKey = SnatchRegistry();

   // create the sub-key Software\Microsoft\Windows\CurrentVersion\
   // Policies\ComDlg32\PlacesBar
   HKEY hSubKey;
   long result = RegCreateKey(hKey, KEY_PLACES_BAR, &hSubKey);

   // add places only if the creation succeeded
   if(result == ERROR_SUCCESS)
   {
      int place = 0;
      // iterate over all combos
      for(int i = 0; i < 5; i++)
      {
         CComboBox* pCombo =
            (CComboBox*)GetDlgItem(IDC_COMBO_PLACE0 + i);

         // nothing is selected, ignore the combo
         int sel = pCombo->GetCurSel();
         if(CB_ERR == sel)
            continue;

         // set the name of the new entry
         CString strPlace; strPlace.Format(_T("Place%d"), place++);

         int value = (int)pCombo->GetItemData(sel);
         ASSERT(value != BROWSE);
         CString item;
         pCombo->GetLBText(sel, item);

         // the associated item value indicates a predefined place
         if(value >= 0)
         {
            int number = m_defplaces.Places[tstring
               (item.GetBuffer(item.GetLength()+1))];

            RegSetValueEx(hSubKey, strPlace, 0, REG_DWORD,
                          (LPBYTE)&value, sizeof(int));
         }
         // a custom folder was selected
         else
         {
            RegSetValueEx(hSubKey,
               strPlace,
               0,
               REG_SZ,
               (LPBYTE)(LPCTSTR)item,
               sizeof(TCHAR) * (item.GetLength()+1));
         }
      }
   }
   else
   {
      AfxMessageBox(_T("Cannot create registry key ")TEMP_REG_KEY);
   }

   // close the sub-key
   RegCloseKey(hSubKey);

   // display the dialog
   CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY,
                   _T("All Files (*.*)|*.*||"), this);
   dlg.DoModal();

   // restore the HKEY_CURRENT_USER and delete the temporary key
   RedeemRegistry(hKey);
}

Restoring predefined HKEY_CURRENT_USER

After closing the file dialog, the Registry should be brought back to the previous state. The RedeemRegistry() function restores the predefined HKEY_CURRENT_USER by calling RegOverridePredefKey with NULL for the second argument, and then closes the temporary key and deletes it. SHDeleteKey is used because it can delete a key recursively.

void CDemoOpenFileDlg::RedeemRegistry(HKEY hKey)
{
   // restore the default mapping of the predefined current user key
   RegOverridePredefKey(HKEY_CURRENT_USER, NULL);
   // close the temporary Registry key
   RegCloseKey(hKey);
   // delete the temporary Registry key (recursively)
   SHDeleteKey(HKEY_CURRENT_USER, TEMP_REG_KEY);

   return;
}

The Places Bar of the file dialog with the folders selected as shown in the previous image looks like this:

[customplaces.png]

For implementation details, download the demo application. The method is easily portable to any application.

References

For displaying the browse for folder dialog, I used a MFC wrapper for SHBrowseForFolder, written by Kenneth M. Reed, and available for download here.



About the Author

Marius Bancila

Marius Bancila is a Microsoft MVP for VC++. He works as a software developer for a Norwegian-based company. He is mainly focused on building desktop applications with MFC and VC#. He keeps a blog at www.mariusbancila.ro/blog, focused on Windows programming. He is the co-founder of codexpert.ro, a community for Romanian C++/VC++ programmers.

Downloads

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: August 20, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT When you look at natural user interfaces as a developer, it isn't just fun and games. There are some very serious, real-world usage models of how things can help make the world a better place – things like Intel® RealSense™ technology. Check out this upcoming eSeminar and join the panel of experts, both from inside and outside of Intel, as they discuss how natural user interfaces will likely be getting adopted in a wide variety …

  • Java developers know that testing code changes can be a huge pain, and waiting for an application to redeploy after a code fix can take an eternity. Wouldn't it be great if you could see your code changes immediately, fine-tune, debug, explore and deploy code without waiting for ages? In this white paper, find out how that's possible with a Java plugin that drastically changes the way you develop, test and run Java applications. Discover the advantages of this plugin, and the changes you can expect to see …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds