c++winapicontextmenuwindows-shellshell-extensions

How to show localized text and custom icons in context menu shell extensions using IExecuteCommand and verbs?


I was considering developing a context menu shell extension following the new Windows 7+ approach based on IExecuteCommand, as described in this blog post:

Simplifying context menu extensions with IExecuteCommand

instead of the classic IContextMenu approach I'm more familiar with.

I have a couple of questions about this new method:

  1. How can I show localized text (for example, loaded from resources) in the customized menu items? In the old model, this can be simply done invoking InsertMenu in the IContextMenu::QueryContextMenu implementation, and passing a string loaded from resources.

  2. How can I associate and show an icon with my custom menu items? Again, this can be done in the old IContextMenu-based model, for example invoking SetMenuItemBitmaps. Are there specific image formats required for the menu icons?


Solution

  • IExecuteCommand is used for shell verbs that are registered statically in the Registry and have a "DelegateExecute"="{clsid}" value associated with them. The menu text for a static verb is taken from the display text that is registered for the verb, and that text is displayed as-is, it cannot be localized, as there is simply no option provided to specify an alternate source for the text. Only a real shell extension based on IContextMenu or IExplorerCommand has the option to localize text and provide icons for its custom verbs. IExecuteCommand does not provide that functionality.

    UPDATE: On Windows XP and later, the display text for static verbs are MUI-aware, so you can provide display text that refers to a localized resource. This is documented:

    Using Registry String Redirection

    Provide Resources for Shell Verb Action Strings

    Action strings for certain verbs, for example, "open" and "edit", are shown in the pop-up menu displayed when the user right-clicks a file in Windows Explorer. Your application does not have to specify strings for common shell verbs, as the shell has its own MUI-enabled defaults for these verbs. However, you should provide localizable string resources for strings representing uncommon verbs.

    On pre-Windows XP operating systems, strings for shell verbs in the registry are rendered using the following syntax, where verb specifies the actual verb name:

    HKCR\<progid>\shell\<verb>
    @ = <friendly-name>
    

    Here's an example:

    HKCR\Sample.app\shell\Disc
    @ = "Disconnect"
    

    On Windows XP and later, you can use a level of indirection to make an action string depend on user interface language. These operating systems support a MUIVerb value for definition of a MUI-compatible string. Here's an example of a registry entry for an uncommon verb:

    HKCR\Sample.app\shell\Disc
    @ = "Disconnect"
    "MUIVerb" = "@%systemroot%\system32\sample.exe,-9875"
    

    Your MUI application should also be able to register the old default value as a localizable string, as shown below:

    HKCR\Sample.app\shell\Disc
    @ = "@%systemroot%\system32\sample.exe,-9875"
    

    Note Registration of the old default value is not recommended because it requires a different setup on Windows XP and later from the setup used on earlier operating systems.

    AFAIK, you cannot provide an icon for a static verb to display in the context menu, though. You do need a shell extension based on IContextMenu or IExplorerCommand for that.