Thursday, August 25, 2011

<Strings> Element in VSCT files – ButtonText, CommandName, CanonicalName, MenuText, oh my!


If you ever added a Button definition in VSCT files for Visual Studio menus, you may have wondered what are all the ButtonText, MenuText, CommandName, etc. elements associated with the button.

When you create a new Visual Studio Extensibility project and tell it to create a menu item, accepting the default values, the result is a generated vsct file containing code like this:

      <Button guid="guidVSPackage1CmdSet" id="cmdidMyCommand" priority="0x0100" type="Button">
        <Parent guid="guidVSPackage1CmdSet" id="MyMenuGroup" />
        <Icon guid="guidImages" id="bmpPic1" />
          <ButtonText>My Command name</ButtonText>

I’m going to tell you upfront it’s indicated to change the format of the <CommandName> element – the project template generator gets it wrong how the value should look like.

So,  where do these values appear in UI?  There is a MSDN article for the Strings Element description, but is a bit confusing, and as writing this article, it contains a couple of mistakes.

To better exemplify where all these elements appear, let’s start by defining a Button command with each child element specified, like so:


Now let’s build the project and see where these strings appear in Visual Studio.

Let’s start with ButtonText. This is a mandatory string, and, if any other strings are omitted, this string will be used to generate the other optional values. This means this string can appear in all places 

As the MSDN page describes, ButtonText is used in UI when the button is placed in a menu controller (such as the dropdown menu of the NewProject button):


However, the same ButtonText string is used when the button is placed:

- in the Visual Studio’s Main Menu

- in a toolbar (e.g. in the Standard toolbar)


In the same picture, notice also that when the button is placed in a menu (e.g. under the File menu), a different string is used – this time MenuText is used.

A button can be easily added to other menus and toolbars by using the Tools/Customize dialog. However, using the dialog it may be a bit confusing because it displays a different string. Neither ButtonText nor MenuText will appear in this dialog, despite the dialog mimicking the looks of menus and toolbars. Here, in the Controls list, is used the CommandName string.


The CommandName also appears in the Add Command dialog that can be invoked from the Customize dialog, in the Commands list.


Now you may see why it’s recommended to change the format of the CommandName generated by the project wizard. It may be hard for users to figure out that cmdidMyCommand is actually related to what the user usually sees in the UI for that command, more like “Command Name”. Use a descriptive string for your command names, use spaces and no funky “cmdid” prefixes. Or simply don’t define at all this string, and let the shell display instead the ButtonText string – this is probably what you’ll want in most cases.

The MSDN article indicates CommandName is also used in the Tools/Options dialog in the Keyboard page. This is incorrect. The Keyboard dialog displays the LocCanonicalName string (or in it’s absence, the ButtonText string), after stripping unwanted characters such as spaces, ellipses, ampersands, etc.


The LocCanonicalName string  is also displayed in the Command tool window, in the Intellisense/autocomplete popups.


Again, the MSDN page is a bit misleading here, as it seem to suggest that CanonicalName string appears in the Command Window (after being stripped of ampersands, spaces, etc).

While the autocomplete popup only displays the LocCanonicalName string,  both CanonicalName and LocCanonicalName can be used for command execution, but you have to type the canonical name string. Notice that execution succeeded no matter which of these strings was typed, whereas trying to execute an inexistent command displayed an error message.


Again, if one of these strings (or both) is omitted from the button’s definition, the ButtonText is used instead to generate a canonical name for command execution and/or the autocomplete popup.

And finally, the ToolTipText string is used for the button’s tooltip, when the button is placed:

- in the Visual Studio’s main menu, as a top-level button

- in a toolbar (in this case the keyboard shortcut, if any, is also displayed in the tooltip)

The tooltip is not displayed when the button is placed as a menu item (e.g. in the File menu) as the MSDN page indicates.



Bill Menees said...

Thanks for writing this article. It helped me out, and it's a huge improvement over the "Strings Element" documentation on MSDN (which is still wrong for VS 11).

Steve Cadwallader said...

Thanks Alin, I found this article very helpful. :)

Anonymous said...

Thanks, exactly what I was looking for.

Anonymous said...

Thanks very much. Very helpful! MSFT's own docs on the subject is (as usual) very poor.