Customize VS Toolbar in VSPackage (CSVSPackageToolbars)

Introduction

VSPackages are software modules that make up and extend the Visual Studio integrated development environment (IDE) by providing UI elements, services, projects, editors, and designers. VSPackages are the principal architectural unit of Visual Studio, and are the unit of deployment, licensing, and security also. Visual Studio itself is written mostly as a collection of VSPackages. This sample demonstrates how to use the Visual Studio Integration Package Wizard to create a simple VSPackage with a toolbar.

Building the Sample

VS 2008 SP1 SDK must be installed on the machine. You can download it from:

Visual Studio 2008 SDK 1.1

Set the Start Action and Start Options of Debug.

Start Action: C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe (32bit OS) or C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe (64bit OS)

Start Option: /ranu /rootsuffix Exp

Running the Sample

1.       Press F5 to debug this project.

2.       In the new instance of Visual Studio, right click the non-populated portion of the toolbar docking window and selecting the "My Toolbar" toolbar. Or select the Tools=>Customize menu item, and from the Customize dialog, then can select the "My Toolbar" entry to display the toolbar.

3.       This toolbar supports Dropdown, you can click the buttons in the toolbar, and it will show the related messages.

Using the Code

A: How to Create a VSPackage

1.       Create a new project using Visual Studio Integration Package as template(New Project dialog box -> Other Project Types -> Extensibility).

2.       In the Location box, type the file path for your VSPackage.

3.       In the Name box, type the name for the solution and then click OK to startthe wizard.

4.       On the Select a Programming Language page, select Visual C# and have the wizard generate a key.snk file to sign the assembly, then click Next.

5.       In the Basic VSPackage Information page, specify details about your VSPackage(Brand the VSPackage) and click Next.

6.       Select the Menu Command option to create a new command for the VSPackage. Then click Next.

7.       Type the name(All-In-One) and ID(cmdidMyCommand) for the new menu command in the text boxes, then click Next. The command ID is the name of a constant that represents this menu command in the generated code.

8.       Uncheck the Intergration Test Project and Unit Test Project, then click Finish.

B: Add a Toolbar to VS IDE

1.       In Solution Explorer, open CSVSToolbars.vsct.

VSCT file stands for Visual Studio Command Table. This is an XML based file that  describes the layout and appearance of command items for a VSPackage. Command  items include buttons, combo boxes, menus, toolbars, and groups of command items.     

2.       In the <Symbols> section, find the <GuidSymbol> node whose name attribute is guidCSVSToolbarsCmdSet. Add the following two <IDSymbol> elements to the list of <IDSymbol> elements in this node to define a toolbar and a toolbar group.

XML
Edit|Remove
<IDSymbol name="ToolbarID" value="0x1000" />
<IDSymbol name="ToolbarGroupID" value="0x1001" />

 

3.       Just above the <Groups> section, create an empty <Menus> section, and create the following <Menu> element to define the toolbar that you declared in step 2.

XML
Edit|Remove
<Menus>
 <Menu guid="guidCSVSToolbarsCmdSet" id="ToolbarID"
       priority="0x0000" type="Toolbar">
   <Parent guid="guidCSVSToolbarsCmdSet" id="ToolbarID" />
   <Strings>
     <ButtonText>My Toolbar</ButtonText>
     <CommandName>My Toolbar</CommandName>
   </Strings>
 </Menu>
</Menus> 

 

4.       Add a new <Group> element to the <Groups> section to define the group that you declared in the <Symbols> section.

XML
Edit|Remove
<Group guid="guidCSVSToolbarsCmdSet" id="ToolbarGroupID"
       priority="0x0000">
  <Parent guid="guidCSVSToolbarsCmdSet" id="ToolbarID"/>
</Group>

 

5.       In the Buttons Element, change the parent of the existing Button Elementto the toolbar group so that the toolbar will be displayed.      

XML
Edit|Remove
<Parent guid="guidCSVSToolbarsCmdSet" id="ToolbarGroupID" />

 

6.       Save CSVSToolbars.vsct.

C: Add a icon to the command:

1.       Create a bitmap with a color depth of 32-bits. An icon is always 16 x 16 so this bitmap must be 16 pixels high and a multiple of 16 pixels wide.In this sample, it is camera.png, which is a 32bits png image.       

2.       Add the bitmap to the resource of this project

3.       Open the .vsct file in the editor.

4.       In the Symbols Element, find the GuidSymbol Element that contains your existing  bitmap entries. By default, it is named guidImages. And add new Symbols Element next to the existing one.

XML
Edit|Remove
<GuidSymbol name="guidMyImages" value="{4056cc26-4a2f-432c-a816-e6694e673abb}">
  <IDSymbol name="bmpMyPic" value="1" />
</GuidSymbol>

 

5.       Add an IDSymbol Element for each icon in your bitmap. The name attribute is the icon's ID, and the value indicates its position on the strip.

XML
Edit|Remove
<IDSymbol name="bmpMyPic" value="1" />

 

6.       Create a Bitmap Element in the <Bitmaps> section of the .vsct file to represent the bitmap containing the icons.

XML
Edit|Remove
<Bitmap guid="guidMyImages" href="Resources\camera.png"/>

 

7.       Change the Toolbar button to use the new icon

XML
Edit|Remove
<Icon guid="guidMyImages" id="bmpMyPic" />

 

8.       Save all the files.

D: Add a menu controller

1.       Open the .vsct file in the editor.

2.       In the Symbols Element, in the GuidSymbol Element named "guidCSVSToolbarsCmdSet",  declare your menu controller, menu controller group, and three menu items.

XML
Edit|Remove
<IDSymbol name="TestMenuController" value="0x1300"/>
<IDSymbol name="TestMenuControllerGroup" value="0x1060"/>
<IDSymbol name="cmdidMCItem1" value="0x0130"/>
<IDSymbol name="cmdidMCItem2" value="0x0131"/>
<IDSymbol name="cmdidMCItem3" value="0x0132"/>

 

3.       In Menus Element,after the last menu entry, define the menu controller as a menu.

XML
Edit|Remove
<Menu guid="guidCSVSToolbarsCmdSet" id="TestMenuController"
    priority="0x0100" type="MenuController">
  <Parent guid="guidCSVSToolbarsCmdSet" id="ToolbarGroupID"/>
  <CommandFlag>IconAndText</CommandFlag>
  <CommandFlag>TextChanges</CommandFlag>
  <CommandFlag>TextIsAnchorCommand</CommandFlag>
  <Strings>
    <ButtonText>Test Menu Controller</ButtonText>
    <CommandName>Test Menu Controller</CommandName>
  </Strings>
</Menu>

 

4.       In the Groups Element, after the last group entry, add the menu controller group

XML
Edit|Remove
<Group guid="guidCSVSToolbarsCmdSet" id="TestMenuControllerGroup"
 priority="0x000">
  <Parent guid="guidCSVSToolbarsCmdSet" id="TestMenuController"/>
</Group>

 

         

5.       In the Buttons Element, after the last button entry, add a Button Element for each of  your menu items.

XML
Edit|Remove
<Button guid="guidCSVSToolbarsCmdSet" id="cmdidMCItem1"
priority="0x0000" type="Button">
  <Parent guid="guidCSVSToolbarsCmdSet" id="TestMenuControllerGroup"/>
  <Icon guid="guidImages" id="bmpPic1"/>
  <CommandFlag>IconAndText</CommandFlag>
  <Strings>
    <ButtonText>MC Item 1</ButtonText>
    <CommandName>MC Item 1</CommandName>
  </Strings>
</Button>
<Button guid="guidCSVSToolbarsCmdSet" id="cmdidMCItem2"
      priority="0x0100" type="Button">
  <Parent guid="guidCSVSToolbarsCmdSet" id="TestMenuControllerGroup"/>
  <Icon guid="guidImages" id="bmpPic2"/>
  <CommandFlag>IconAndText</CommandFlag>
  <Strings>
    <ButtonText>MC Item 2</ButtonText>
    <CommandName>MC Item 2</CommandName>
  </Strings>
</Button>
<Button guid="guidCSVSToolbarsCmdSet" id="cmdidMCItem3"
      priority="0x0200" type="Button">
  <Parent guid="guidCSVSToolbarsCmdSet" id="TestMenuControllerGroup"/>
  <Icon guid="guidImages" id="bmpPicSearch"/>
  <CommandFlag>IconAndText</CommandFlag>
  <Strings>
    <ButtonText>MC Item 3</ButtonText>
    <CommandName>MC Item 3</CommandName>
  </Strings>
</Button>   

 

6.       Save the .vsct file.  

 E: Implement the menu controller

1.       Open PkgCmdID.cs and add the following lines

C#
Edit|Remove
public const int cmdidMCItem1 = 0x130;
public const int cmdidMCItem2 = 0x131;
public const int cmdidMCItem3 = 0x132;

 

2.       At the top of the CSVSToolbarsPackage class, add the following:

C#
Edit|Remove
// The currently selected menu controller command
private int currentMCCommand;

 

3.       In the Initialize method, immediately after the last call to the AddCommand method, add code to route the events for each command through the same handlers.

C#
Edit|Remove
for (int i = PkgCmdIDList.cmdidMCItem1; i <=
   PkgCmdIDList.cmdidMCItem3; i++)
{
    CommandID cmdID = new
    CommandID(GuidList.guidCSVSToolbarsCmdSet, i);
    OleMenuCommand mc = new OleMenuCommand(new
      EventHandler(OnMCItemClicked), cmdID);
    mc.BeforeQueryStatus += new EventHandler(OnMCItemQueryStatus);
    mcs.AddCommand(mc);
    // The first item is, by default, checked.
    if (PkgCmdIDList.cmdidMCItem1 == i)
    {
        mc.Checked = true;
        this.currentMCCommand = i;
    }
}



 

4.       Add the following two event handler defined above

C#
Edit|Remove
private void OnMCItemClicked(object sender, EventArgs e)
{
    OleMenuCommand mc = sender as OleMenuCommand;
    if (null != mc)
    {
        string selection;
        switch (mc.CommandID.ID)
        {
            case PkgCmdIDList.cmdidMCItem1:
                selection = "Menu controller Item 1";
                break;


            case PkgCmdIDList.cmdidMCItem2:
                selection = "Menu controller Item 2";
                break;


            case PkgCmdIDList.cmdidMCItem3:
                selection = "Menu controller Item 3";
                break;


            default:
                selection = "Unknown command";
                break;
        }
        this.currentMCCommand = mc.CommandID.ID;


        IVsUIShell uiShell =
          (IVsUIShell)GetService(typeof(SVsUIShell));
        Guid clsid = Guid.Empty;
        int result;
        uiShell.ShowMessageBox(
                   0,
                   ref clsid,
                   "Test Tool Window Toolbar Package",
                   string.Format(CultureInfo.CurrentCulture,
                                 "You selected {0}", selection),
                   string.Empty,
                   0,
                   OLEMSGBUTTON.OLEMSGBUTTON_OK,
                   OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                   OLEMSGICON.OLEMSGICON_INFO,
                   0,
                   out result);
    }
}

 

5.       Save the all files.

More Information

How to: Create VSPackages (C# and Visual Basic)

How to: Register a VSPackage (C#)

VSPackage Tutorial 1: How to Create a VSPackage

Designing XML Command Table (.Vsct) Files

Commands Element

KeyBindings Element

Walkthrough: Adding a Toolbar to the IDE

How to: Add Icons to Commands on Toolbars

How to: Add Menu Controllers to Toolbars

Walkthrough: Adding a Menu Controller to a Toolbar

Creating a package with a simple command

Menus and comands in VS IDE