Creating Shortcut Menu Handlers
Shortcut menu handlers, also known as context menu handlers or verb handlers, are a type of file type handler. These handlers may be implemented in a way that causes them to load in their own process or in the explorer, or other 3rd party processes. Take care when creating in-process handlers as they can cause harm to the process that loads them.
Note
There are special considerations for 64-bit based versions of Windows when registering handlers that work in the context of 32-bit applications: when invoked in the context of an application of different bitness, the WOW64 subsystem redirects file system access to some paths. If your .exe handler is stored in one of those paths, it is not accessible in this context. Therefore, as a work around, either store your .exe in a path that does not get redirected, or store a stub version of your .exe that launches the real version.
This topic is organized as follows:
- Canonical Verbs
- Extended Verbs
- Programmatic Access Only Verbs
- Customizing a Shortcut Menu Using Static Verbs
- Activating Your Handler Using the IDropTarget Interface
- Specifying the Position and Order of Static Verbs
- Positioning Verbs at the Top or Bottom of the Menu
- Creating Static Cascading Menus
- Getting Dynamic Behavior for Static Verbs by Using Advanced Query Syntax
- Deprecated: Associating Verbs with Dynamic Data Exchange Commands
- Completing Verb Implementation Tasks
- Related topics
Canonical Verbs
Applications are generally responsible for providing localized display strings for the verbs they define. However, to provide a degree of language independence, the system defines a standard set of commonly used verbs called canonical verbs. A canonical verb is never displayed to the user, and can be used with any UI language. The system uses the canonical name to automatically generate a properly localized display string. For instance, the open verb's display string is set to Open on an English system, and to the German equivalent on a German system.
Canonical verb | Description |
---|---|
Open | Opens the file or folder. |
Opennew | Opens the file or folder in a new window. |
Prints the file. | |
Printto | Permits the user to print a file by dragging it to a printer object. |
Explore | Opens Windows Explorer with the folder selected. |
Properties | Opens the object's property sheet. |
Note
The Printto verb is also canonical, but it is never displayed. Its inclusion enables the user to print a file by dragging it to a printer object.
Shortcut menu handlers can provide their own canonical verbs through IContextMenu::GetCommandString with GCS_VERBW, or GCS_VERBA. The system will use the canonical verbs as the second parameter (lpOperation) passed to ShellExecute, and is the CMINVOKECOMMANDINFO.lpVerb member passed to the IContextMenu::InvokeCommand method.
Extended Verbs
When the user right-clicks an object, the shortcut menu displays the default verbs. You might want to add and support commands on some shortcut menus that are not displayed on every shortcut menu. For example, you could have commands that are not commonly used or that are intended for experienced users. For this reason, you can also define one or more extended verbs. These verbs are similar to normal verbs, but are distinguished from normal verbs by the way they are registered. To have access to extended verbs, the user must right-click an object while pressing the SHIFT key. When the user does so, the extended verbs are displayed in addition to the default verbs.
You can use the registry to define one or more extended verbs. The associated commands will be displayed only when the user right-clicks an object while also pressing the SHIFT key. To define a verb as extended, add an "extended" REG_SZ value to the verb's subkey. The value should not have any data associated with it.
Programmatic Access Only Verbs
These verbs are never displayed in a context menu. These can be accessed by using ShellExecuteEx and specifying the lpVerb field of the pExecInfo parameter (a SHELLEXECUTEINFO object). To define a verb as programmatic access only, add a "ProgrammaticAccessOnly" REG_SZ value to the verb's subkey. The value should not have any data associated with it.
You can use the registry to define one or more extended verbs. The associated commands will be displayed only when the user right-clicks an object while also pressing the SHIFT key. To define a verb as extended, add an "extended" REG_SZ value to the verb's subkey. The value should not have any data associated with it.
Customizing a Shortcut Menu Using Static Verbs
After Choosing a Static or Dynamic Verb for your Shortcut Menu you can extend the shortcut menu for a file type by registering a static verb for the file type. To do so, add a Shell subkey below the subkey for the ProgID of the application associated with the file type. Optionally, you can define a default verb for the file type by making it the default value of the Shell subkey.
The default verb is displayed first on the shortcut menu. Its purpose is to provide the Shell with a verb it can use when the ShellExecuteEx function is called, but no verb is specified. The Shell does not necessarily select the default verb when ShellExecuteEx is used in this fashion.
The Shell uses the first available verb in the following order:
- The default verb
- The first verb in the registry, if the verb order is specified
- The Open verb
- The Open With verb
If none of the verbs listed is available, the operation fails.
Create one subkey for each verb you want to add under the Shell subkey. Each of these subkeys must have a REG_SZ value set to the verb's display string (localized string). For each verb subkey, create a command subkey with the default value set to the command line for activating the items. For canonical verbs, such as Open and Print, you can omit the display string because the system automatically displays a properly localized string. For noncanonical verbs, if you omit the display string, the verb string is displayed.
In the following registry example, note that:
- Because Doit is not a canonical verb, it is assigned a display name, which can be selected by pressing the D key.
- The Printto verb does not appear on the shortcut menu. However, its inclusion in the registry enables the user to print files by dropping them on a printer icon.
- One subkey is shown for each verb. %1 represents the file name and %2 the printer name.
HKEY_CLASSES_ROOT
.myp-ms
(Default) = MyProgram.1
MyProgram.1
(Default) = My Program Application
Shell
(Default) = doit
doit
(Default) = &Do It
command
(Default) = c:\MyDir\MyProgram.exe /d "%1"
open
command
(Default) = c:\MyDir\MyProgram.exe /d "%1"
print
command
(Default) = c:\MyDir\MyProgram.exe /p "%1"
printto
command
(Default) = c:\MyDir\MyProgram.exe /p "%1" "%2"
The following diagram illustrates the extension of the shortcut menu in accordance with the registry entries above. This shortcut menu has Open, Do It, and Print verbs on its menu, with Do It as the default verb.
Activating Your Handler Using the IDropTarget Interface
Dynamic Data Exchange (DDE) is deprecated; use IDropTarget instead. IDropTarget is more robust and has better activation support because it uses COM activation of the handler. In the case of multiple item selection, IDropTarget is not subject to the buffer size restrictions found in both DDE and the CreateProcess. Also, items are passed to the application as a data object that can be converted to an item array by using the SHCreateShellItemArrayFromDataObject function. Doing so is simpler, and does not lose namespace information as occurs when the item is converted to a path for command-line or DDE protocols.
For more information about IDropTarget and Shell queries for file association attributes, see Perceived Types and Application Registration.
Specifying the Position and Order of Static Verbs
Normally verbs are ordered on a shortcut menu based on how they are enumerated; enumeration is based first on the order of the association array, and then on the order of the items in the association array, as defined by the sort order of the registry.
Verbs can be ordered by specifying the default value of the Shell subkey for the association entry. This default value can include a single item, which will be displayed at the top position of the shortcut menu, or a list of items separated by spaces or commas. In the latter case, the first item in the list is the default item, and the other verbs are displayed immediately below it in the order specified.
For example, the following registry entry produces shortcut menu verbs in the following order:
- Display
- Gadgets
- Personalization
HKEY_CLASSES_ROOT
DesktopBackground
Shell
Display
Gadgets
Personalization
Similarly, the following registry entry produces shortcut menu verbs in the following order:
- Personalization
- Gadgets
- Display
HKEY_CLASSES_ROOT
DesktopBackground
Shell = "Personalization,Gadgets"
Display
Positioning Verbs at the Top or Bottom of the Menu
The following registry attribute can be used to place a verb at the top or bottom of the menu. If there are multiple verbs that specify this attribute then the last one to do so gets priority:
Position=Top | Bottom
Creating Static Cascading Menus
In Windows 7 and later, cascading menu implementation is supported through registry settings. Prior to Windows 7, the creation of cascading menus was possible only through the implementation of the IContextMenu interface. In Windows 7 and later, you should resort to COM code-based solutions only when the static methods are insufficient.
The following screen shot provides an example of a cascading menu.
In Windows 7 and later, there are three ways to create cascading menus:
- Creating Cascading Menus with the SubCommands Registry Entry
- Creating Cascading Menus with the ExtendedSubCommandsKey Registry Entry
- Creating Cascading Menus with the IExplorerCommand Interface
Creating Cascading Menus with the SubCommands Registry Entry
In Windows 7 and later, you can use the SubCommands entry to create cascading menus by using the following procedure.
To create a cascading menu by using the SubCommands entry
Create a subkey under HKEY_CLASSES_ROOT\ProgID\shell to represent your cascading menu. In this example, we give this subkey the name CascadeTest. Ensure that the default value of the CascadeTest subkey is empty, and shown as (value not set).
HKEY_CLASSES_ROOT * shell CascadeTest (Default)
To your CascadeTest subkey, add a MUIVerb entry of type REG_SZ and assign it the text that will appear as its name on the shortcut menu. In this example, we assign it "Test Cascade Menu".
HKEY_CLASSES_ROOT * shell CascadeTest (Default) MUIVerb = Test Cascade Menu
To your CascadeTest subkey, add a SubCommands entry of type REG_SZ that is assigned list, delimited by semi-colons, of the verbs that should appear on the menu, in the order of appearance. For example, here we assign a number of system-provided verbs:
HKEY_CLASSES_ROOT * Shell CascadeTest SubCommands Windows.delete;Windows.properties;Windows.rename;Windows.cut;Windows.copy;Windows.paste
In the case of custom verbs, implement them using any of the static verb implementation methods and list them under the CommandStore subkey as shown in this example for a fictional verb VerbName:
HKEY_LOCAL_MACHINE Software Microsoft Windows CurrentVersion Explorer CommandStore Shell VerbName command (Default) = notepad.exe %1
Note
This method has the advantage that the custom verbs can be registered once and reused by listing the verb name under the SubCommands entry. However, it requires the application to have permission to modify the registry under HKEY_LOCAL_MACHINE.
Creating Cascading Menus with the ExtendedSubCommandsKey Registry Entry
In Windows 7 and later, you can use the ExtendedSubCommandKey entry to create extended cascading menus: cascading menus within cascading menus.
The following screen shot is an example of an extended cascading menu.
Because HKEY_CLASSES_ROOT is a combination of HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE, you can register any custom verbs under the HKEY_CURRENT_USER\Software\Classes subkey. The main advantage of doing so is that elevated permission is not required. Also, other file associations can reuse this entire set of verbs by specifying the same ExtendedSubCommandsKey subkey. If you do not need to reuse this set of verbs, you can list the verbs under the parent, but ensure that the Default value of the parent is empty.
To create a cascading menu by using an ExtendedSubCommandsKey entry
Create a subkey under HKEY_CLASSES_ROOT\ProgID\shell to represent your cascading menu. In this example, we give this subkey the name CascadeTest2. Ensure that the default value of the CascadeTest subkey is empty, and shown as (value not set).
HKEY_CLASSES_ROOT * shell CascadeTest2 (Default)
To your CascadeTest subkey, add a MUIVerb entry of type REG_SZ and assign it the text that will appear as its name on the shortcut menu. In this example, we assign it "Test Cascade Menu".
HKEY_CLASSES_ROOT * shell CascadeTest (Default) MUIVerb = Test Cascade Menu 2
Under the CascadeTest subkey you have created, add an ExtendedSubCommandsKey subkey, and then add the document subcommands (of REG_SZ type); for example:
HKEY_CLASSES_ROOT txtfile Shell Test Cascade Menu 2 (Default) ExtendedSubCommandsKey Layout Properties Select all
Ensure that the default value of the Test Cascade Menu 2 subkey is empty, and shown as (value not set).
Populate the subverbs using any of the following static verb implementations. Note that the CommandFlags subkey represents EXPCMDFLAGS values. If you want to add a separator before or after the cascade menu item, use ECF_SEPARATORBEFORE (0x20) or ECF_SEPARATORAFTER (0x40). For a description of these Windows 7 and later flags, see IExplorerCommand::GetFlags. ECF_SEPARATORBEFORE works only for the top level menu items. MUIVerb is of type REG_SZ, and CommandFlags is of type REG_DWORD.
HKEY_CLASSES_ROOT txtile Shell Test Cascade Menu 2 (Default) ExtendedSubCommandsKey Shell cmd1 MUIVerb = Notepad command (Default) = %SystemRoot%\system32\notepad.exe %1 cmd2 MUIVerb = Wordpad CommandFlags = 0x20 command (Default) = "C:\Program Files\Windows NT\Accessories\wordpad.exe" %1
The following screen shot is an illustration of the previous registry key entry examples.
Creating Cascading Menus with the IExplorerCommand Interface
Another option for adding verbs to a cascading menu is through IExplorerCommand::EnumSubCommands. This method enables data sources that provide their command module commands through IExplorerCommandProvider to use those commands as verbs on a shortcut menu. In Windows 7 and later, you can provide the same verb implementation using IExplorerCommand as you can with IContextMenu.
The following two screen shots illustrate the use of cascading menus in the Devices folder.
The following screen shot illustrates another implementation of a cascading menu in the Devices folder.
Note
Because IExplorerCommand supports in-process activation only, it is recommended for use by Shell data sources that need to share the implementation between commands and shortcut menus.
Getting Dynamic Behavior for Static Verbs by Using Advanced Query Syntax
Advanced Query Syntax (AQS) can express a condition that will be evaluated using properties from the item that the verb is being instantiated for. This system works only with fast properties. These are properties that the Shell data source reports as fast by not returning SHCOLSTATE_SLOW from IShellFolder2::GetDefaultColumnState.
Windows 7 and later support canonical values that avoid problems on localized builds. The following canonical syntax is required on localized builds to take advantage of this Windows 7 enhancement.
System.StructuredQueryType.Boolean#True
In the following example registry entry:
- The AppliesTo value controls whether the verb is displayed or hidden.
- The DefaultAppliesTo value controls which verb is the default.
- The HasLUAShield value controls whether a User Account Control (UAC) shield is displayed.
In this example the DefaultAppliesTo value makes this verb the default for any file with the word "exampleText1" in its file name. The AppliesTo value enables the verb for any file with "exampleText1" in the name. The HasLUAShield value displays the shield for files with "exampleText2" in the name.
HKEY_CLASSES_ROOT
txtile
shell
test.verb
DefaultAppliesTo = System.ItemName:"exampleText1"
HasLUAShield = System.ItemName:"exampleText2"
AppliesTo = System.ItemName:"exampleText1"
Add the Command subkey, and a value:
HKEY_CLASSES_ROOT
txtile
shell
test.verb
Command
(Default) = %SystemRoot%\system32\notepad.exe %1
In the Windows 7 registry, see HKEY_CLASSES_ROOT\drive as an example of bitlocker verbs that employ the following approach:
- AppliesTo = System.Volume.BitlockerProtection:=2
- System.Volume.BitlockerRequiresAdmin:=System.StructuredQueryType.Boolean#True
For more information about AQS, see Advanced Query Syntax.
Deprecated: Associating Verbs with Dynamic Data Exchange Commands
DDE is deprecated; use IDropTarget instead. DDE is deprecated because it relies on a broadcast window message to discover the DDE server. A DDE server hang stalls the broadcast window message and thus hangs DDE conversations for other applications. It is common for a single stuck application to cause subsequent hangs all across the user's experience.
The IDropTarget method is more robust and has better activation support because it uses COM activation of the handler. In the case of multiple item selection, IDropTarget is not subject to the buffer size restrictions found in both DDE and the CreateProcess. Also, items are passed to the application as a data object that can be converted to an item array by using the SHCreateShellItemArrayFromDataObject function. Doing so is simpler, and does not lose namespace information as occurs when the item is converted to a path for command-line or DDE protocols.
For more information about IDropTarget and Shell queries for file association attributes, see Perceived Types and Application Registration.
Completing Verb Implementation Tasks
The following tasks for implementing verbs are relevant to both static and dynamic verb implementations. For more information on dynamic verbs, see Customizing a Shortcut Menu Using Dynamic Verbs.
Customizing the Shortcut Menu for Predefined Shell Objects
Many predefined Shell objects have shortcut menus that can be customized. Register the command in much the same way that you register typical file types, but use the name of the predefined object as the file type name.
A list of predefined objects is in the Predefined Shell Objects section of Creating Shell Extension Handlers. Those predefined Shell objects whose shortcut menus can be customized by adding verbs in the registry are marked in the table with the word Verb.
Extending a New Submenu
When a user opens the File menu in Windows Explorer, one of the commands displayed is New. Selecting this command displays a submenu. By default, the submenu contains two commands, Folder and Shortcut, that enable users to create subfolders and shortcuts. This submenu can be extended to include file creation commands for any file type.
To add a file-creation command to the New submenu, your application's files must have an associated file type. Include a ShellNew subkey under the file name. When the File menu's New command is selected, the Shell adds the file type to the New submenu. The command's display string is the descriptive string that is assigned to the program's ProgID.
To specify the file creation method, assign one or more data values to the ShellNew subkey. The available values are listed in the following table.
ShellNew subkey value | Description |
---|---|
Command | Executes an application. This REG_SZ value specifies the path of the application to be executed. For example, you could set it to launch a wizard. |
Data | Creates a file containing specified data. This REG_BINARY value specifies the file's data. Data is ignored if either NullFile or FileName is specified. |
FileName | Creates a file that is a copy of a specified file. This REG_SZ value specifies the fully qualified path of the file to be copied. |
NullFile | Creates an empty file. NullFile has no assigned a value. If NullFile is specified, the Data and FileName registry values are ignored. |
The following registry key example and screen shot illustrate the New submenu for the .myp-ms file type. It has a command, MyProgram Application.
HKEY_CLASSES_ROOT
.myp
(Default) = MyProgram.1
MyProgram.1
ShellNew
NullFile
The screen shot illustrates the New submenu. When a user selects MyProgram Application from the New submenu, the Shell creates a file named New MyProgram Application.myp-ms and passes it to MyProgram.exe.
Creating Drag-and-Drop Handlers
The basic procedure for implementing a drag-and-drop handler is the same as for conventional shortcut menu handlers. However, shortcut menu handlers normally use only the IDataObject pointer passed to the handler's IShellExtInit::Initialize method to extract the object's name. A drag-and-drop handler could implement a more sophisticated data handler to modify the behavior of the dragged object.
When a user right-clicks a Shell object to drag an object, a shortcut menu is displayed when the user attempts to drop the object. The following screen shot illustrates a typical drag-and-drop shortcut menu.
A drag-and-drop handler is a shortcut menu handler that can add items to this shortcut menu. Drag-and-drop handlers are typically registered under the following subkey.
HKEY_CLASSES_ROOT
Directory
shellex
DragDropHandlers
Add a subkey under the DragDropHandlers subkey named for the drag-and-drop handler, and set the subkey's default value to the string form of the handler's class identifier (CLSID) GUID. The following example enables the MyDD drag-and-drop handler.
HKEY_CLASSES_ROOT
Directory
shellex
DragDropHandlers
MyDD
(Default) = {MyDD CLSID GUID}
Suppressing Verbs and Controlling Visibility
You can use Windows policy settings to control verb visibility. Verbs can be suppressed through policy settings by adding a SuppressionPolicy value, or a SuppressionPolicyEx GUID value to the verb's registry subkey. Set the value of the SuppressionPolicy subkey to the policy ID. If the policy is turned on, the verb and its associated shortcut menu entry are suppressed. For possible policy ID values, see the RESTRICTIONS enumeration.
Employing the Verb Selection Model
Registry values must be set for verbs to handle situations where a user can select a single item, multiple items, or a selection from an item. A verb requires separate registry values for each of these three situations that the verb supports. The possible values for the verb selection model are as follows:
- Specify the MultiSelectModel value for all verbs. If the MultiSelectModel value is not specified, it is inferred from the type of verb implementation you have chosen. For COM-based methods (such as DropTarget and ExecuteCommand) Player is assumed, and for the other methods Document is assumed.
- Specify Single for verbs that support only a single selection.
- Specify Player for verbs that support any number of items.
- Specify Document for verbs that create a top level window for each item. Doing so limits the number of items activated and helps avoid running out of system resources if the user opens too many windows.
When the number of items selected does not match the verb selection model or is greater than the default limits outlined in the following table, the verb fails to appear.
Type of verb implementation | Document | Player |
---|---|---|
Legacy | 15 items | 100 items |
COM | 15 items | No limit |
The following are example registry entries using the MultiSelectModel value.
HKEY_CLASSES_ROOT
Folder
shell
open
= MultiSelectModel = Document
HKEY_CLASSES_ROOT
ProgID
shell
verb
= MultiSelectModel = Single | Document | Player
Using Item Attributes
The SFGAO flag values of the Shell attributes for an item can be tested to determine whether the verb should be enabled or disabled.
To use this attribute feature, add the following the REG_DWORD values under the verb:
- The AttributeMask value specifies the SFGAO value of the bit values of the mask to test with.
- The AttributeValue value specifies the SFGAO value of the bits that are tested.
- The ImpliedSelectionModel specifies zero for item verbs, or nonzero for verbs on the background shortcut menu.
In the following example registry entry, the AttributeMask is set to SFGAO_READONLY (0x40000).
HKEY_CLASSES_ROOT
txtfile
Shell
test.verb2
AttributeMask = 0x40000
AttributeValue = 0x0
ImpliedSelectionModel = 0x0
command
(Default) = %SystemRoot%\system32\notepad.exe %1
Implementing Custom Verbs for Folders through Desktop.ini
In Windows 7 and later, you can add verbs to a folder through Desktop.ini. For more information about Desktop.ini files, see How to Customize Folders with Desktop.ini.
Note
Desktop.ini files should always be marked System + Hidden so they won't be displayed to users.
To add custom verbs for folders through a Desktop.ini file, perform the following steps:
Create a folder that is marked Read-only or System.
Create a Desktop.ini file that includes a [.ShellClassInfo] DirectoryClass=Folder ProgID.
In the registry create HKEY_CLASSES_ROOT\Folder ProgID with a value of CanUseForDirectory. The CanUseForDirectory value avoids the misuse of ProgIDs that are set not to participate in implementing custom verbs for folders through Desktop.ini.
Add verbs under the FolderProgID subkey, for example:
HKEY_CLASSES_ROOT CustomFolderType Shell MyVerb command (Default) = %SystemRoot%\system32\notepad.exe %1\desktop.ini
Note
These verbs can be the default verb, in which case double-clicking the folder activates the verb.
Related topics