Custom Items For the Folder Options Dialog Box

Have you ever had the need to make persistent some settings of your shell extensions? A shell extension is an extremely dynamic object and, as such, its user interface must be visible and affect the way you interact with Explorer. However, some of your users might find it sometimes too intrusive and would like to toggle it on and off at will. For example, consider infotip shell extensions. They prompt you with a tooltip window showing some sort of hopefully useful information about a certain file. Although useful, this information might not be something you want to appear each time your mouse hesitates over a certain file in a folder. Wouldn’t it be great, instead, if you could store somewhere a boolean flag to enable and disable some features of the shell extension?

How do you store persistent settings for shell extensions? Databases, XML streams,
INI or proprietary files may be all good approaches. But how do you make
them interactive and easily available to users without a made-to-measure
application? The main issue is not how you store the persistent information but how you check and uncheck that flag interactively. Using the Registry Editor or Notepad is certainly fine, but a bit impractical as it requires your users a certain degree of familiarity with those tools. Not to mention that editing the registry is the just kind of action that even many renowned programmers are afraid of.

If the shell extension is part of an application then the preferences dialog of the application would also be an excellent solution. But how many shell extensions are part of an application or could be easily integrated with it? My personal experience leads me to think rather that shell extensions are written to extend applications, not the contrary. You usually write shell extensions to extend the capability of some applications and not always can afford to modify the preference dialog of the application to meet shell extensions needs.

The Folder Options Dialog Box

Don’t think, however, you are the only one who has to face this problem. In the past, Microsoft itself had to figure out an easily accessible place to store all the customizable settings for Explorer’s folders.
They came out with a dialog box called the Folder Options dialog box. (See Figure 1).



Figure 1 – The Windows Explorer Folder Options dialog box

It is available from the Explorer’s Tools menu and lets you view and edit Explorer-wide settings.

Officially, you can only read those settings through an API function called SHGetSettings. Microsoft never made available a companion function (say, SHSetSettings) to set values. Even worse, they never thought to expose a more powerful function providing you with the ability to add custom settings to the dialog.

So much for the officially documented stuff. In this article, I’m just going to unveil the internal data schema they used to populate the treeview of Figure 1. By exploiting this “undocumented” information, you can arrange a programmable interface to modify existing settings as well as add and manage your own ones.

The whole hierarchy displayed by the Folder Options dialog is stored in the registry according to a simple pattern. Thus, to edit current values, or insert new custom settings, you have just to edit some registry entries or create new keys being respectful of that schema!
Figure 2 illustrates the registry status for a hierarchy like the one in Figure 1.



Figure 2 – The values entered into the Folder Options dialog box are stored in the registry

Start by looking at the registry content under the following key:

HKLM
  \SOFTWARE
    \Microsoft
      \Windows
        \CurrentVersion
          \Explorer
            \Advanced

Normally, the Advanced key contains just one subkey named Folder. More in general, any key created at this level corresponds to a group of first-level items in the dialog box. A node can have four properties: type, bitmap, text and helpID. Of these, only type is mandatory. The other three can help you to shape the node at will by specifying the icon, the descriptive text and a help topic.

Creating a New Group of Properties

Create a new key under Advanced. Any name is fine, but it’s recommendable that you give it an evocative, single-word name. For example, let’s give it the extremely fancy name of MyShellSettings. Create now a REG_SZ attribute called type and assign it the string ‘group’ as the value. Save and open the Folder Options dialog box. What you see should similar to Figure 3.



Figure 3 – Example of displaying custom properties via the Folder Options dialog box

You can set the display text for the group by creating a new REG_SZ entry named text. For example, assign the value of “My Shell Settings”. If you want the same icon as the Folder group (the gray folder you can see in Figure 3), then create a REG_SZ entry called bitmap and set it to

c:\winnt\system32\shell32.dll,4

Of course, feel free to choose the icon at your best leisure. Just make sure you specify the icon through a comma-separated string including path name and index. The icon index is the ordinal, 0-based position of the icon in the module’s resources. If you’re going to select an .ico file, then the index is 0. In alternative to the index, you can identify the icon through its resource ID. To inform Explorer that you want it to retrieve the icon by ID, just multiply it by -1. In case of negative numbers, in fact, the icon is determined by taking the absolute value and using it as the resource ID. Notice that this rule applies to all the registry items that require an icon index. Now your Folder Options dialog box should look like the one in Figure 4.



Figure 4 – You can specify any icon to be associated with your custom settings

It’s an empty tree, though. Let’s see how to fill it with custom properties representing the persistent settings of your shell extension.

Adding New Properties

A child property is subkey. It can be of three types:

  • A single checkbox
  • A group of radio button
  • A child group of properties

Properties are characterized by a name. Once again, the name of the property defaults to the display name unless you specify a display text through the text entry. To add a new property, start by choosing a name for it. For example, MyCheckbox. You assign a type by the means of the type entry. Feasible values are group, checkbox, radio.

A checkbox must have the following entries: CheckedValue, UncheckedValue and DefaultValue. All of them are of type REG_DWORD and mandatory. Their meaning is rather self-explanatory. Basically, you use them to set the default value and the value to be returned when the property is checked (normally, 1) or unchecked (normally, 0). The default value is used only when Explorer isn’t able to read the currently set value.

The HelpID plays the same role it played for property groups. It is an optional entry representing a page on some help file. Its typical content looks like the following

shell.hlp#51104

where the trailing number is the topic ID of the HLP file to invoke, should help be requested.

If you want to expose a group of mutually exclusive properties then you should create a new group first and then all of its child properties and mark them of type ‘radio’. Radio items don’t need the UncheckedValue entry, while CheckedValue and DefaultValue are still mandatory. Figure 5 shows how your Folder Options dialog looks now.



Figure 5 – The Folder Options dialog box allows you to create a series of checkboxes and radio buttons to represent the options you want saved

Code in Listing 1, instead, demonstrates a REG file you can run to automatically create the tree of Figure 5. (To remove all those settings, just delete the MyShellSettings subtree.)

Storing the Current Status

So far, I’ve just extended the property tree shown through the Folder Options dialog box. The structure of this tree is considered one the machine-specific settings and, as you may have noticed, is stored under the HKEY_LOCAL_MACHINE (HKLM) hive. However, none of the entries and subkeys I’ve created in the meantime is supposed to contain the current value for the various properties.

The actual value for each property is considered as a user-specific information and should be stored under the HKEY_CURRENT_USER (HKCU) hive. This is reasonable as such values may change on a per-user basis. Any property just contains some extra attributes which identify the registry path where the information must be safely kept. Three properties lets you completely identify this point. They are: HKeyRoot, RegPath and ValueName. They aren’t mandatory but are an absolute necessity if you really want to make settings persistent.

HKeyRoot contains just the DWORD value that identifies the HKEY_CURRENT_USER hive. This value is 0x80000001. While you could store the values for your own settings wherever throughout the registry, it’s recommendable that you always use HKCU. Consider, in fact, that some of your users might not have the rights to access the HKLM hive for writing.

RegPath and ValueName point to the path under HKeyRoot where the settings is stored. Put another way, they form the registry entry from where you can read the status of a custom option. They also allow you to programmatically retrieve and update a standard, system-provided option. Of course, you must use the same ValueName for all of the properties part of the same radio group. Normally, you assign the ValueName entry the name of the node that represents the property. For example, MyCheckbox for the first checkbox item I created earlier. Also the registry path obeys to some non-written but practical rules. Normally, you store the property value under

\Software
  \Microsoft
    \Windows
      \CurrentVersion
        \Explorer
          \Advanced
            \<Your Custom Node>

Listing 2 shows the full REG file that creates and makes persistent the hierarchy of custom properties shown in Figure 5.

Setting Values Programmatically

As a final note, bear in mind that you cannot read back a custom setting through the SHGetSettings API function. The reason is that such a function utilizes a fixed structure to accept the identifiers of the settings to retrieve. As you can easily imagine, such a structure includes only the standard folder settings. See the function’s MSDN documentation for more information.

Reading and writing values for folder attributes is as easy as editing the proper registry entries. For example, the following is a simply JScript batch file that disables infotips altogether throughout the shell.

HKCU_WIN = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\";
FOLDER_OPTIONS = "Explorer\\Advanced\\";
SetFolderSetting("ShowInfoTip", 0);
function SetFolderSetting(propName, v)
{
 var shell;
 shell = new ActiveXObject("WScript.Shell");
 shell.RegWrite(HKCU_WIN + FOLDER_OPTIONS + propName,
                v, "REG_DWORD");
}

To revert the setting simply replace the previous call to SetFolderSetting with

SetFolderSetting("ShowInfoTip", 1);

With similar code you can read or set your own custom properties from within your shell extensions.

Notice that any change you apply through code doesn’t apply immediately because the shell must be notified of such an event. From compiled code, you can do this through the SHChangeNotify API function. If you’re working with JScript and VBScript batch files you need to wrap a call to this function in a COM object that the script invokes.

Final Disclaimer

All that I explained in this article is totally undocumented and I figured it out by spying on the registry. As all the undocumented stuff, there’s no guarantee that it will continue working this way across different future versions of Windows. Anyway, at this time such a code works on Windows 98, Windows Millennium, plus any flavor of Windows 2000. It also works on Windows 95 and Windows NT 4.0 with Active Desktop installed. Let me know if you test it under Whistler

Downloads

Download demo code – 2 Kb

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read