In the last article (Part #13) I promised that I show you real programming examples about how to deal with menus, toolbars and commands. Now it is time to start with these examples. I think one article would be very long if I wanted to show all the code I had found important. In this part I am moving around the .vsct file and related code.
Defining the startup state
In a few of the previous posts—including Part #13—I have mentioned that VSPackages are on-demand loaded, the IDE loads them into the memory when their objects are about to be created or any of their services is are about to be used. However there is one issue to solve: with on-demand loading: If menus and toolbars are defined within a package, how can Visual Studio display them without loading the package into the memory?
When the package is registered (by regpkg.exe) resources representing menus and toolbars are extracted and stored separately. When Visual Studio loads into the memory it reads this resource information and can display the related menu and toolbar items without loading the package binary.
The key for this operation is the .vsct file that is an acronym for Visual Studio Command Table. This file is a new “creature” substituting the .ctc file in the previous version of Visual Studio SDK. The role of command table files is to define commands and their related UI and UI context information. When we compile a package, the command table configuration file is translated into a binary command table output file (called .cto file) and actually this file is added to the package binary as a byte array resource.
In the VS 2005 versions of Visual Studio SDK used a textual format (using files with .ctc extension). Editing and understanding a .ctc file is not a simple task. With the release of Visual Studio 2008 SDK Microsoft created the new XML-based file format with the .vsct extension and a new compiler called to produce the binary .cto format.
The main advantage of using the .vsct file is that it is editable just like other XML files and so has all the great XML editing features like automatic generation of closing tags, or IntelliSense based on the .vsct XML schema. Due to the fact XML format has so many advantage the old .ctc format has been deprecated. Microsoft recommends using the VSCT compiler to generate the .cto files, although CTC is still supported.
In this article I introduce you more details of the .vsct file than in previous articles. First I introduce the basics of a .vsct file and then we assemble the pieces through samples.
Basics of the .vsct file structure
When defining what the elements of an XML file are one alternative is to provide an XSD schema. It tells a lot about the syntax and the semantics and is said to be readable by either a human or a machine. There is no doubt that machines (software) can understand an XSD, but for understanding concepts behind a certain XML file by humans XSD is a quite awful way. To make the structure (and related semantics) of the .vsct file for you I start showing up a few details and examples.
Top of the structure
The root element of a .vsct file is the CommandTable element:
<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/..."
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Content of the command table -->
</CommandTable>
The elements of the command table are defined by the “http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable” namespace. I suppose you will rarely create the startup state of a command table by hand (the VSPackage wizard does it for you when you ask it to create an initial command or tool window). If you do that, do not forget about specifying this namespace otherwise your command table will not compile. In the code illustrations later in this article I am going to omit the namespace information just to make the code shorter.
The CommandTable itself uses a few child elements to define the content of the table:
<CommandTable xmlns="..." xmlns:xs="...">
<Extern/>
<Include/>
<Define/>
<Commands/>
<CommandPlacements>
<VisibilityConstraints/>
<KeyBindings/>
<UsedCommands/>
<Symbols/>
</CommandTable>
For a developer new to VSX, the Extern, Commands and Symbols elements are the most important ones. When the VSPackage wizard creates a package with a simple menu command, we get something similar (the wizard injects a lot of comments to explain the content):
<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="..." xmlns:xs="...">
<Extern href="stdidcmd.h" mce_href="stdidcmd.h"/>
<Extern href="vsshlids.h" mce_href="vsshlids.h"/>
<Extern href="msobtnid.h" mce_href="msobtnid.h"/>
<Commands package="guidSimpleCommandPkg">
<Groups>
<Group guid="guidSimpleCommandCmdSet" id="MyMenuGroup" priority="0x0600">
<Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/>
</Group>
</Groups>
<Buttons>
<Button guid="guidSimpleCommandCmdSet" id="cmdidMyFirstCommand"
priority="0x0100" type="Button">
<Parent guid="guidSimpleCommandCmdSet" id="MyMenuGroup" />
<Icon guid="guidImages" id="bmpPic1" />
<Strings>
<CommandName>cmdidMyFirstCommand</CommandName>
<ButtonText>My First Command</ButtonText>
</Strings>
</Button>
</Buttons>
<Bitmaps>
<Bitmap guid="guidImages" href="Resources\Images_32bit.bmp" mce_href="Resources\Images_32bit.bmp"
usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows"/>
</Bitmaps>
</Commands>
<Symbols>
<GuidSymbol name="guidSimpleCommandPkg"
value="{2291da24-92e5-4ea4-bdb7-72a9b5ac7d59}" />
<GuidSymbol name="guidSimpleCommandCmdSet"
value="{a982b107-4ad4-437e-b2bc-cdf2708aa376}">
<IDSymbol name="MyMenuGroup" value="0x1020" />
<IDSymbol name="cmdidMyFirstCommand" value="0x0100" />
</GuidSymbol>
<GuidSymbol name="guidImages" value="{5c3faf04-8190-48c4-a6e9-71f04f1848e5}" >
<IDSymbol name="bmpPic1" value="1" />
<IDSymbol name="bmpPic2" value="2" />
<IDSymbol name="bmpPicSearch" value="3" />
<IDSymbol name="bmpPicX" value="4" />
<IDSymbol name="bmpPicArrows" value="5" />
</GuidSymbol>
</Symbols>
</CommandTable>
If you feel, the content of the file is not really readable at the first sight, you are not alone. Please, let me help you to read it!
Symbols and IDs
In Part #6 we already treated that objects (like commands and related UI elements) in the .vsct file (and just as in the VS IDE) are uniquely identified. When referencing to elements we use their unique identifiers. IDs of commands and UI-related objects are hierarchical represented by a pair of a GUID and a 32 bit unsigned integer. The GUID represents a logical container the object belongs to and the 32 bit unsigned integer the distinguishing ID of the object within that logical container. (There are a few entities identified by only a GUID, later in this article we’ll meet them).
Since in a .vsct file we generally use an identifier at least twice: once for identifying an object and at least once for referencing it, using (GUID, uint) pairs would not help readability. I am sure I would really hate to find associated objects by GUIDs...
The Symbols section is a central place in the command table file where we can define the identifiers to be used in the other parts of the .vsct file. We can use the GuidSymbol element to define the “logical container GUID” and the nested IDSymbol elements to provide (optional) identifiers within the logical container. The name and the value attribute of these elements do exactly what we expect: associate the symbol name with its value. In the example above we defined three GUID containers. The first is an empty container (with the symbolic name of guidSimpleCommandPkg) the last two contain a few nested ID elements. The identifiers defined here are referenced in the upper parts of the command table definition as in the following extract:
<Commands package="guidSimpleCommandPkg">
<Groups>
<Group guid="guidSimpleCommandCmdSet" id="MyMenuGroup" priority="0x0600">
<!-- ... -->
</Group>
</Groups>
<Buttons>
<Button guid="guidSimpleCommandCmdSet" id="cmdidMyFirstCommand"
priority="0x0100" type="Button">
<!-- ... -->
</Button>
</Buttons>
<Bitmaps>
<Bitmap guid="guidImages" href="Resources\Images_32bit.bmp" mce_href="Resources\Images_32bit.bmp"
usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows"/>
</Bitmaps>
</Commands>
When we define a command or the location of the command, we frequently refer to objects defined by the Visual Studio IDE. For example, when we add a menu item to the Tools menu, somehow we must refer to the Tools menu in a way understood by VSCT compiler. Of course, the Tools menu is identified on the same way as any other (including our own) command:
<Group guid="guidSimpleCommandCmdSet" id="MyMenuGroup" priority="0x0600">
<Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/>
</Group>
Here the Parent element defines the location where the logical command group declared by the Group element should be placed. The guidSHLMainMenu defines the logical container of the main menu bar of the VS IDE and the IDM_VS_MENU_TOOLS is the ID of the Tools menu within the logical container. As you guess, there are thousands of GUIDs and IDs related to VS IDE elements.
The Extern element is the key to access them:
<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="..." xmlns:xs="...">
<Extern href="stdidcmd.h" mce_href="stdidcmd.h"/>
<Extern href="vsshlids.h" mce_href="vsshlids.h"/>
<Extern href="msobtnid.h" mce_href="msobtnid.h"/>
<!-- ... -->
</CommandTable>
When the VSCT compiler processes the .vsct file it can run a preprocessor on its content. This preprocessor by default is the C++ preprocessor that allows including files defining symbols and macros. The Extern element is one directing the preprocessor. The href attribute names the file with .h (standard C++ header file) extension. After the preprocess phase the symbols in the #define pragmas and in the macro definitions of the referenced file those can be used anywhere just like GUID and ID values defined in the Symbols section of the command table.
The files named in the href attributes are searched in the include path passed to the VSCT compiler. This is the VisualStudioIntegration\Common\Inc folder under the root of the VS 2008 SDK by default when you create your package with the VSPackage wizard. The wizard also creates the three Extern elements in the code extract above. These files define lots of IDs:
| File |
Content |
| stdidcmd.h |
This file represents the command IDs for all commands exposed by Visual Studio. IDs include the visible (or hidden) menu command IDs prefixed with cmdid, standard editor commands with ECMD_ prefix and a few others.
|
| vsshlids.h |
This files collects command IDs for the menus provided by the Visual Studio shell.
|
| msobtnid.h |
This file represents IDs of the standard Microsoft Office commands (many of them, like Cut, Copy and Paste also used in VS IDE).
|
If you have the patience to look into the header files, you can find the definitions for guidSHLMainMenu and IDM_VS_MENU_TOOLS in the vsshlids.h file:
...
DEFINE_GUID (guidSHLMainMenu,
0xd309f791, 0x903f, 0x11d0, 0x9e, 0xfc, 0x00, 0xa0, 0xc9, 0x11, 0x00, 0x4f);
...
#define IDM_VS_MENU_TOOLS 0x0085
...
The preprocessor understands both the DEFINE_GUID macro and the #define pragma.
Command definitions
Beyond doubt the most important element is Commands in the .vsct file. This section defines commands, their initial layout and behavior:
<Commands package="...">
<Groups/>
<Menus/>
<Buttons/>
<Combos/>
<Bitmaps/>
</Commands>
Any command in the VS IDE must belong to the IDE itself or to a package. A package assembly can implement one or more packages. To assign a command to the appropriate (owning) VSPackage, the package attribute of the Commands element must name the GUID of the corresponding package. Generally we have only one package in one assembly so we put the package ID generated by the VSPackage wizard into this attribute:
<Commands package="guidSimpleCommandPkg">
<!-- ... -->
</Commands>
Commands can have a few child elements; each has a very specific role.
Groups
This element defines so-called command groups using a nested Group element. A command group is a logical set of related commands that generally stand together. For example, the Build Solution, Rebuild Solution and Clean Solution menu items form a logical group: they stand together in the Build menu and in the context menu of a Solution item:

Instead of putting individual commands to an existing menu we can put a group there. Each command in the logical set formed by the group appears in the related menu. Command groups can be taken into account as a tool for command definition reusability.
Menus
You can nest Menu elements as children of Menus to define a single menu. A single menu is a placeholder for items to put on them and of course, we also can put submenu items there.
Menus can have different appearance and behavior. The most frequent forms are:
Standard menus (for example the File, Edit and View menus in VS IDE)
Context menus: They show up when right-clicking on the object they provide a command context for.
Toolbars: standard toolbars just as we know them, where commands are organized in rows with icons representing them.
Buttons
The Buttons element is a container for nested Button elements. A button represents a piece of user interface element the user can interact with. The name is a bit confusing, since when saying the word “button” we generally associate it with the pushbutton we can place on a form. Here, button rather relates to a menu item. In .vsct we can define a few type of Button:
Standard buttons representing a simple menu item which executes a command.
Menu buttons displaying a submenu.
Dropdown buttons that allows functions like Undo and Redo in VS IDE.
“Swatch” buttons that display color choices such as those in a font color dialog.
Combos
Not surprisingly Combos is a container for Combo elements. A Combo defines a set of commands that appear in a combo box. I guess treating this control assumes a few prerequisites on VSX programming, so I will return to this topic later. The time when I created this article, the VSCT reference information had a subtle mistake: it does state that Combo is the direct child element of Commands. However the element hierarchy is Commands, Combos and Combo. Fortunately, IntelliSense treats it correctly due to the schema file related to the .vsct file.
Bitmaps
Toolbars and menus would be poor without icons helping the user to associate a small image with the function. The Bitmaps section allows defining the visual elements (icons) used in menus. The section describes Bitmap elements that are uniquely identified. A bitmap can come from an external file or from a package resource.
When referencing to bitmaps, we can use a few formats like .bmp, .gif, .png. Right now you cannot use all formats in the same way. For example, I had problems with the 32-bit .bmp formats (alpha channel information for partial transparency). If you use 120 DPI in your display settings, the original 16x16 pixel images will be stretched to a 20x20 pixel size. There is bug in the bitmap handling: when using .bmp format with 120 DPI, the stretching creates some artifacts (colorful pixels in the last row of the icon). If you use .png format, stretching is smooth without disturbing artifacts. In some cases only a few formats are accepted (I do not know, this is bug or feature): for example for icons representing tool windows on their tabs, .png format is not welcomed (no icon appears), only 24-bit .bmp with fuchsia as the transparent color.
If you have problems with icon images, try a few formats and you can generally find the one expected by VS IDE.
Defining commands
To successfully define commands appearing in the VS IDE menus we have to use at least one Group and one Button element. If we want to add icons, we additionally need at least one Bitmap element. If we prefer our own menu instead of just inserting a command group in the middle of a Visual Studio menu, at least one Menu element should be defined. To establish the layout and the relation among the elements we have to look behind their attributes and child elements.
Menu, Group and Button elements have common attributes and child element with very similar semantics. Here is a table of common attributes:
| Attribute |
Description |
| guid |
The GUID part of the element identifier. This attribute is required.
|
| id |
The uint part of the element identifier. This attribute is required.
|
| priority |
An optional numeric value determining the order of the element. The lower this value is, the element is closer to the first element position. Actually, VS IDE sorts elements according to their priority. However, we cannot know the priority value of other elements, so using this attribute it is not guaranteed that we can exactly position the element.
|
| type |
An optional stereotype of the element determining its layout and behavior. The Group element does not have this attribute (as it is a behavior-less element). The possible values and the meaning of this attribute changes according to the element type.
|
There are child elements influencing the relation between elements and adding them properties that fine-tune their layout and behavior. Except of Bitmap all other types of Commands children have the following child elements:
| Child element |
Description |
| Parent |
Optional parent of the element. In the previous article (Part #13) I mentioned that a command element can be attached to one or more menu items. Here you can define zero or one Parent element. If you want to attach a command to more than one menu item, the CommandPlacement element is for you (we treat it later).
The Parent element has the guid and id attribute to uniquely name the parent our element belongs to. For a Button parent element must refer to a command Group. For a Group, the parent must refer to Menu.
|
| Annotation |
This element allows putting optional comment information to the element. Annotation can have either simple text or a nested structure.
|
Menu, Button and Combo have child elements extending the layout and behavior:
| Child element |
Description |
| CommandFlag |
This child element can be applied zero, one or more times for its parent element. As its name indicates an element sets a flag influencing the layout and behavior of its parent. The VSCT reference enumerates all the command flags that can be applied to a particular element. Several flags have effect only when combining with other flags. For example, applying the DynamicVisibility and DefaultInvisible flags causes a menu to be hidden at VS startup time.
|
| Strings |
This element is a container for child elements representing string information related to an element. Any elements must have at least the ButtonText child of Strings to be able to display a caption for the element. Possible child elements include ButtonText, ToolTipText, MenuText, CommandName and others. For details see the VSCT Schema reference.
|
| Icon |
Available only for Button. Optionally defines the icon associated with the button.
|
Working with bitmaps
The Bitmaps section of Commands provides a place to define bitmaps we want to use in menu and toolbar items. Each definition must be in a Bitmap element. The concept of Bitmap element covers one bitmap with a physical size of 16x16 pixels or a bitmap strip that has 16xN pixels where N is a multiple of 16 (number of pixels in a column). Actually Bitmap handles the simple 16x16 pixel bitmap as a bitmap strip, where N equals 1. A Bitmap is identified with a GUID that must be a separate GUID from the package ID, command set IDs, etc. When we refer to a certain item in the bitmap strip we do it by using a one-based index for the bitmap in the strip.
Just as in case of commands, menu IDs we use the Symbols section of the command table to define IDs related to a bitmap. For example when we create a new Tool window package With the VSPackage wizard, we have the following entries related to bitmaps:
<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="..." xmlns:xs="...">
<!-- Extern elements -->
<Commands package="...">
<!-- Menus, Groups and Buttons -->
<Bitmaps>
<Bitmap guid="guidImages" href="Resources\Images_32bit.bmp" mce_href="Resources\Images_32bit.bmp"
usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows"/>
</Bitmaps>
</Commands>
<Symbols>
<GuidSymbol name="guidImages" value="{...}" >
<IDSymbol name="bmpPic1" value="1" />
<IDSymbol name="bmpPic2" value="2" />
<IDSymbol name="bmpPicSearch" value="3" />
<IDSymbol name="bmpPicX" value="4" />
<IDSymbol name="bmpPicArrows" value="5" />
</GuidSymbol>
</Symbols>
</CommandTable>
The Symbols section defines a GUID used only by the Bitmap definition (guidImages) and symbolic names for the one-based bitmap indexes within the strip. In the example above bmpPicSearch is the third picture within the strip.
The Bitmap element’s href attribute names the file where the bitmap strip can be found. This folder is relative to the location of the .vsct file. The usedList attribute enumerates the symbolic indexes that can be used to identify bitmaps in the strip. If we want to set a button icon to the third image in the strip, we use the following Icon child element in a Button:
<Button ...>
<Icon guid="guidImages" id="bmpPicSearch" >
</Button>
A few samples for creating menus
After dealing with the .vsct groups, menus and buttons so much, it is time to look for a few examples to understand how to put together the pieces of the puzzle.
Creating a main menu level command
The VSPackage wizard puts menu items in a fixed place: in the Tools menu if we create a simple command or into the View menu if we create a simple tool window. However, when we create a package we often would like to put our own package-specific menu in the main menu bar of Visual Studio. Now we are going to do that...
We create a new main level menu “HowToPackage” with two menu command items. Assuming that we have already created a VSPackage with a .vsct file, this task requires the following steps:
Step1: Creating a GuidSymbol element with children for the symbols we are going to use. We nest this element in the Symbols section.
Step 2: Creating a Menu element representing the main level menu. We put this item into the Menus section and set up the Parent of this menu to a main menu level menu group.
Step 3: Creating a Group element representing the logical group holding the two menu command items. We set the Parent of this group to the Menu created in the previous step. I am sure you know: we nest it into the Groups section.
Step 4: Creating two Button elements representing the commands and set their Parent to the Group created previously. And where we put them? Yes, of course, into the Buttons section!
Following the steps above I created the following .vsct file:
<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="..." xmlns:xs="...">
<Extern href="stdidcmd.h" mce_href="stdidcmd.h"/>
<Extern href="vsshlids.h" mce_href="vsshlids.h"/>
<Extern href="msobtnid.h" mce_href="msobtnid.h"/>
<Commands package="...">
<Menus>
<Menu guid="guidHowToPackageCmdSet" id="TopLevelMenu" priority="0x100"
type="Menu">
<Parent guid="guidSHLMainMenu" id="IDG_VS_MM_BUILDDEBUGRUN" />
<Strings>
<ButtonText>HowToPackage</ButtonText>
<CommandName>HowToPackage</CommandName>
</Strings>
</Menu>
</Menus>
<Groups>
<Group guid="guidHowToPackageCmdSet" id="TopLevelMenuGroup"
priority="0x0600">
<Parent guid="guidHowToPackageCmdSet" id="TopLevelMenu"/>
</Group>
</Groups>
<Buttons>
<Button guid="guidHowToPackageCmdSet" id="cmdFirstCommand" priority="0x0100"
type="Button">
<Parent guid="guidHowToPackageCmdSet" id="TopLevelMenuGroup" />
<Strings>
<CommandName>cmdidFirstCommand</CommandName>
<ButtonText>First Command</ButtonText>
</Strings>
</Button>
<Button guid="guidHowToPackageCmdSet" id="cmdSecondCommand"
priority="0x0101" type="Button">
<Parent guid="guidHowToPackageCmdSet" id="TopLevelMenuGroup" />
<Strings>
<CommandName>cmdidSecondCommand</CommandName>
<ButtonText>Second Command</ButtonText>
</Strings>
</Button>
</Buttons>
</Commands>
<Symbols>
<GuidSymbol name="guidHowToPackageCmdSet"
value="{8D7B9CB3-3591-47f9-B104-B7EB173E0F03}" >
<IDSymbol name="TopLevelMenu" value="0x0100" />
<IDSymbol name="TopLevelMenuGroup" value="0x0200" />
<IDSymbol name="cmdFirstCommand" value="0x0300" />
<IDSymbol name="cmdSecondCommand" value="0x0301" />
</GuidSymbol>
<!-- Other Guids for the package -->
</Symbols>
</CommandTable>
As you see, we wrote quite a lot for such a simple task. In the menu definition I highlighted the IDs used in the Parent attribute. If you run your package, you can discover the new menu just after the Build menu group and before the Tools menu:
When you open a solution the Debug menu shows up and our menu goes between Build and Debug:
This is due to the Parent definition of our Menu and the priority we assigned to it:
<Menu guid="guidHowToPackageCmdSet" id="TopLevelMenu" priority="0x100"
type="Menu">
<Parent guid="guidSHLMainMenu" id="IDG_VS_MM_BUILDDEBUGRUN" />
<!-- ... -->
</Menu>
The IDG_VS_MM_BUILDDEBUGRUN is the identifier of a logical group representing the Build and Debug menus on the main VS IDE menu bar. The priority value of 0x100 sets our menu to be shown before the Debug menu. If you change priority to 0x700 (and rebuild the package and run) HowToPackage moves after the Debug menu:
Looking into the Button definition you may say we do not need a Group definition: let’s set the Parent attribute of Buttons directly to the Menu item like in the following example:
<Button ...>
<Parent guid="guidHowToPackageCmdSet" id="TopLevelMenu" />
<!-- ... -->
</Button>
When running the package, no HowToPackage menu will appear. The cause of this phenomenon is the fact that buttons cannot have menus as parents. They must have command groups as parents to be displayed in a menu. Since our HowToPackage menu does not have any child, it is not displayed.
Separating command groups in a menu
As we treated, a command group is a logical container for commands belonging together. This kind of grouping also can be used for visual effects. If we put more than one command group in a menu, a separator is created to visually emphasize the separation of command groups. Let’s add two more commands with a separate group to the .vsct file we created above:
Step 1: We add new symbols representing the new buttons and the group
Step 2: We create new Group definition.
Step3: The two new commands are defined.
After the third step we have our new .vsct file (I indicate the changes and the unchanged parts):
<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="..." xmlns:xs="...">
<!-- Extern elements -->
<Commands package="...">
<!-- Menus section unchanged -->
<Groups>
<!-- New group added -->
<Group guid="guidHowToPackageCmdSet" id="TopLevelMenuGroup2"
priority="0x0600">
<Parent guid="guidHowToPackageCmdSet" id="TopLevelMenu"/>
</Group>
</Groups>
<Buttons>
<!-- New buttons added -->
<Button guid="guidHowToPackageCmdSet" id="cmdThirdCommand" priority="0x0102"
type="Button">
<Parent guid="guidHowToPackageCmdSet" id="TopLevelMenuGroup2" />
<Strings>
<CommandName>cmdidThirdCommand</CommandName>
<ButtonText>Third Command</ButtonText>
</Strings>
</Button>
<Button guid="guidHowToPackageCmdSet" id="cmdFourthCommand"
priority="0x0102" type="Button">
<Parent guid="guidHowToPackageCmdSet" id="TopLevelMenuGroup2" />
<Strings>
<CommandName>cmdidFourthCommand</CommandName>
<ButtonText>Fourth Command</ButtonText>
</Strings>
</Button>
</Buttons>
</Commands>
<Symbols>
<GuidSymbol name="guidHowToPackageCmdSet" value="{...}" >
<!-- New IDSymbols added -->
<IDSymbol name="TopLevelMenuGroup2" value="0x0201" />
<IDSymbol name="cmdThirdCommand" value="0x0302" />
<IDSymbol name="cmdFourthCommand" value="0x0303" />
</GuidSymbol>
<!-- Other Guids for the package -->
</Symbols>
</CommandTable>
Running the resulted package we have the HowToPackage menu where the two command groups are separated:

Adding icons to the buttons
If we want to add icons to the buttons, we have to define a Bitmap and assign it to the Button elements with the Icon property:
Step 1: Creating ID for the bitmap strip.
Step 2: Creating the bitmap and setting up the used images.
Step 3: Adding Icon properties to the buttons.
After this change our .vsct file is the following (I indicate the changes):
<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="..." xmlns:xs="...">
<!-- Extern elements -->
<Commands package="...">
<!-- Menus section unchanged -->
<!-- Groups section unchanged -->
<Buttons>
<Button guid="guidHowToPackageCmdSet" id="cmdFirstCommand" priority="0x0100"
type="Button">
<!-- Icon added, other children unchanged -->
<Icon guid="guidImages" id="bmpPic1" />
</Button>
<Button guid="guidHowToPackageCmdSet" id="cmdSecondCommand"
priority="0x0101" type="Button">
<!-- Icon added, other children unchanged -->
<Icon guid="guidImages" id="bmpPic2" />
</Button>
<Button guid="guidHowToPackageCmdSet" id="cmdThirdCommand" priority="0x0102"
type="Button">
<!-- Icon added, other children unchanged -->
<Icon guid="guidImages" id="bmpPicX" />
</Button>
<Button guid="guidHowToPackageCmdSet" id="cmdFourthCommand"
priority="0x0102" type="Button">
<!-- Icon added, other children unchanged -->
<Icon guid="guidImages" id="bmpPicArrows" />
</Button>
</Buttons>
<Bitmaps>
<!-- A new Bitmap added -->
<Bitmap guid="guidImages" href="Resources\Images_24bit.bmp"
usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows"/>
</Bitmaps>
</Commands>
<Symbols>
<!-- New GuidSymbol section added -->
<GuidSymbol name="guidImages" value="{...}" >
<IDSymbol name="bmpPic1" value="1" />
<IDSymbol name="bmpPic2" value="2" />
<IDSymbol name="bmpPicSearch" value="3" />
<IDSymbol name="bmpPicX" value="4" />
<IDSymbol name="bmpPicArrows" value="5" />
</GuidSymbol>
<!-- Other Guids for the package -->
</Symbols>
</CommandTable>
Running our package with this .vsct file result the following menu:

Playing with CommandFlag values
The CommandFlag child elements can set options that influence the behavior of elements. Let’s see a quick example: we add the TextOnly flag to the first command and DefaultDisabled to the second command:
<Buttons>
<Button guid="guidHowToPackageCmdSet" id="cmdFirstCommand" priority="0x0100"
type="Button">
<!-- CommandFlag added, other children unchanged -->
<CommandFlag>TextOnly</CommandFlag>
</Button>
<Button guid="guidHowToPackageCmdSet" id="cmdThirdCommand" priority="0x0102"
type="Button">
<!-- CommandFlag added, other children unchanged -->
<CommandFlag>DefaultDisabled</CommandFlag>
</Button>
The names of the flags tell what they do. You can recognize it when having a look at the resulting menu:

Where we are?
In this file we walked around the .vsct file which represents the command table of Visual Studio. This file declares commands and command related UI. When building the VSPackage project the content of the .vsct file is compiled into a binary form (.cto file). The binary representation is added to the package assembly as an embedded resource. The regpgk.exe registers it with Visual Studio, so at startup time VS knows which menus to display (and how) and exactly knows which package to load when it is time to execute the commands.
The .vsct file is the “XML reincarnation” of an old command table format (.ctc). The file’s most important part is the Commands section where we can define commands and related UI with the nested Menu, Group, Button, Combo and Bitmap elements. Symbolic names for IDs used by commands and UI are declared in the Symbols section.
The VSCT compiler has preprocessing capabilities. With the Extern elements we can define external header files to process in order to obtain symbolic names and values for identifiers. This is the way to obtain the symbols used in the VS Shell.
In the second part of the article we treated a few examples to see how the pieces of a .vsct files go to work together.
This article is just the beginning about commands and menus. There are much more to treat in next articles.
Posted
Mar 02 2008, 06:50 PM
by
inovak