VSPackage Tutorial 2: How to Create a Tool Window
Tool windows are common in the Visual Studio integrated development environment (IDE). Some examples of tool windows that are included in Visual Studio are Solution Explorer, Task List, Error List, and the Output window. All tool windows have some features in common, for example, each can be docked in the IDE in the same manner. Predictable docking lets users manage their tasks and information efficiently.
This tutorial teaches how to create a tool window in the Visual Studio IDE by using the following steps:
Create a tool window.
Embed a control in the tool window.
Add a toolbar to a tool window.
Add commands to the toolbar.
Implement the commands.
Set the default position for the tool window.
This tutorial is part of a series that teaches how to extend the Visual Studio IDE. For more information, see Tutorials for Customizing Visual Studio By Using VSPackages.
Create a Tool Window
To create a tool window
On the File menu, point to New and then click Project. In the left pane, expand Other Project Types and then click Extensibility. In the right pane, click Visual Studio Integration Package. Name your project. For this example, use the name FirstToolWin. You can also create a directory for the solution. Click OK.
On the welcome page of the Visual Studio Integration Package Wizard, click Next.
On the Select a Programming Language page, click Visual C#. Click Generate a new key file to sign the assembly, and then click Next.
Take a moment to examine the Basic VSPackage Information page. The value in the Company Name box is used as the namespace for all classes in the project. The VSPackage name box provides a name for the final compiled package and the VSPackage version box provides version information. Minimum Visual Studio edition specifies which Visual Studio editions the package should run on. The contents of the Detailed information box will appear on the properties page of the finished package. The Change Icon… button lets you select an icon to represent the package.
For this tutorial, just accept the default values by clicking Next.
On the Select VSPackage Options page, select Menu Command and Tool Window, and then click Next.
Note
The Menu Command option is required in the next tutorial, VSPackage Tutorial 3: How to Extend the Tool Window, which builds on this project.
In the Menu Command Options page, click Next.
In the Tool Window Options page, in the Window name box, type Windows Media Player. In the Command ID field, type a valid identifier, such as cmdidWindowsMediaWin, and then click Next.
In the Select Test Project Options page, uncheck Integration Test Project and Unit Test Project, and then click Finish.
In Solution Explorer, double-click MyControl.cs.
MyControl.cs opens in the designer.
Click the Click Me! button, and then press DEL to delete it so that the control resembles the following illustration.
Embed a Control in the Tool Window
Next, add the Windows Media Player control to the Toolbox and then add it to the tool window.
To embed a control in the tool window
In the Toolbox, right-click the section where you want to add the Windows Media Player control, for example, the General section, and then click Choose Items.
In the Choose Toolbox Items dialog box, click COM Components. Scroll to Windows Media Player and select it, and then click OK.
A Windows Media Control tool appears in the Toolbox.
To add the Media Player to your tool window, drag the Media Player control from the Toolbox to the MyControl.cs form. Notice that it appears small, as shown in the following illustration.
In MyControl.cs, select the Media Player control and then examine the available properties in the Properties window. Some of the properties are standard in all Windows Forms controls. However, others are supplied by the control, for example, URL, which is used to load a file at run time.
In the Properties window, set the Dock property to Fill (the central rectangle).
On the File menu, click Save All.
Add a Toolbar to the Tool Window
By adding a toolbar in the following way, you guarantee that its gradients and colors are consistent with the rest of the IDE.
To add a toolbar to the tool window
In Solution Explorer, open FirstToolWin.vsct. The .vsct file defines the graphical user interface (GUI) elements in your tool window by using XML.
In the <Symbols> section, find the <GuidSymbol> node whose name attribute is guidFirstToolWinCmdSet. Add the following two <IDSymbol> elements to the list of <IDSymbol> elements in this node to define a toolbar and a toolbar group.
<IDSymbol name="ToolbarID" value="0x1000" /> <IDSymbol name="ToolbarGroupID" value="0x1001" />
Just above the <Groups> section, create an empty <Menus> section.
In the <Menus> section, create the following <Menu> element to define the toolbar that you declared in step 2.
<Menus> <Menu guid="guidFirstToolWinCmdSet" id="ToolbarID" priority="0x0000" type="ToolWindowToolbar"> <Parent guid="guidFirstToolWinCmdSet" id="ToolbarID" /> <Strings> <ButtonText>Tool Window Toolbar</ButtonText> <CommandName>Tool Window Toolbar</CommandName> </Strings> </Menu> </Menus>
All containers for commands are defined as different kinds of menus. By its type attribute, this one is set to appear as a toolbar in a tool window. The guid and id settings make up the fully qualified ID of the toolbar. Typically, the <Parent> of a menu refers to the containing group. However, a toolbar is defined as its own parent. Therefore, the same identifier is used for the <Menu> and <Parent> elements. The priority attribute is just '0'.
Toolbars resemble menus in many ways. For example, just as a menu may have groups of commands, toolbars may also have groups. (On menus, the command groups are separated by horizontal lines. On toolbars, the groups are not separated by visual dividers.)
Add a new <Group> element to the <Groups> section to define the group that you declared in the <Symbols> section.
<Group guid="guidFirstToolWinCmdSet" id="ToolbarGroupID" priority="0x0000"> <Parent guid="guidFirstToolWinCmdSet" id="ToolbarID"/> </Group>
By setting the parent guid and id to the guid and id of the toolbar, you put the group in the toolbar.
Save the file.
Add Commands to the Toolbar
Next, add commands to the toolbar. The commands will be displayed as buttons and controls.
To add commands to the toolbar
In FirstToolWin.vsct, in the <Symbols> section, declare four commands just after the toolbar and toolbar group declarations.
<IDSymbol name="cmdidWindowsMedia" value="0x130" /> <IDSymbol name="cmdidWindowsMediaOpen" value="0x132" /> <IDSymbol name="cmdidWindowsMediaFilename" value="0x133" /> <IDSymbol name="cmdidWindowsMediaFilenameGetList" value="0x134" />
Notice that the command cmdidWindowsMediaWin was already declared by the Visual Studio Integration Package Wizard.
In the <Buttons> section, a <Button> element is already present and it contains a definition forthe cmdidWindowsMediaWin command. Add two more <Button> elements to define the cmdidWindowsMedia and cmdidWindowsMediaOpen commands.
<Button guid="guidFirstToolWinCmdSet" id="cmdidWindowsMedia" priority="0x0100" type="Button"> <Parent guid="guidFirstToolWinCmdSet" id="MyMenuGroup"/> <Icon guid="guidImages" id="bmpPic1" /> <Strings> <CommandName>cmdidWindowsMedia</CommandName> <ButtonText>WindowsMedia</ButtonText> </Strings> </Button> <Button guid="guidFirstToolWinCmdSet" id="cmdidWindowsMediaOpen" priority="0x0101" type="Button"> <Parent guid="guidFirstToolWinCmdSet" id="ToolbarGroupID"/> <Icon guid="guidImages" id="bmpPic1" /> <Strings> <CommandName>cmdidWindowsMediaOpen</CommandName> <ButtonText>Load File</ButtonText> </Strings> </Button>
Notice that the priority of the second button is 0x0101. The combo box that is added in the next step has the priority 0x0100. Therefore, the combo box will appear in the first position and the button will appear in the second position.
To provide a place for the user to type some text, add a combo box. Adding a combo box is like adding a button, except that you define the combo box in a <Combos> section.
Create a <Combos> section, just after the </Buttons> tag, with a single entry to define your combo box.
<Combos> <Combo guid="guidFirstToolWinCmdSet" id="cmdidWindowsMediaFilename" priority="0x0100" type="DynamicCombo" idCommandList="cmdidWindowsMediaFilenameGetList" defaultWidth="130"> <Parent guid="guidFirstToolWinCmdSet" id="ToolbarGroupID" /> <CommandFlag>IconAndText</CommandFlag> <CommandFlag>CommandWellOnly</CommandFlag> <CommandFlag>StretchHorizontally</CommandFlag> <Strings> <CommandName>Filename</CommandName> <ButtonText>Enter a Filename</ButtonText> </Strings> </Combo> </Combos>
Save and close FirstToolWin.vsct.
In Solution Explorer, in the project folder, open PkgCmdID.cs and then add the following lines in the class just after the existing members.
public const uint cmdidWindowsMedia = 0x130; public const int cmdidWindowsMediaOpen = 0x132; public const int cmdidWindowsMediaFilename = 0x133; public const int cmdidWindowsMediaFilenameGetList = 0x134; public const int ToolbarID = 0x1000;
Doing this makes your commands available in code.
Save and close the file.
Implement the Commands
Now write the code that implements the commands.
To implement the commands
In Solution Explorer, open MyToolWindow.cs, which contains the class for the tool window itself. Add the following code just after the existing using statements.
using System.ComponentModel.Design;
This line lets you use the CommandID class without having to fully qualify it.
Add the following code to the constructor, just before the line that says control = new MyControl().
// Create the toolbar. this.ToolBar = new CommandID(GuidList.guidFirstToolWinCmdSet, PkgCmdIDList.ToolbarID); this.ToolBarLocation = (int)VSTWT_LOCATION.VSTWT_TOP; // Create the handlers for the toolbar commands. var mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; if (null != mcs) { var toolbarbtnCmdID = new CommandID( GuidList.guidFirstToolWinCmdSet, PkgCmdIDList.cmdidWindowsMediaOpen); var menuItem = new MenuCommand(new EventHandler( ButtonHandler), toolbarbtnCmdID); mcs.AddCommand(menuItem); // Command for the combo itself var menuMyDynamicComboCommandID = new CommandID( GuidList.guidFirstToolWinCmdSet, (int)PkgCmdIDList.cmdidWindowsMediaFilename); var menuMyDynamicComboCommand = new OleMenuCommand( new EventHandler(ComboHandler), menuMyDynamicComboCommandID); mcs.AddCommand(menuMyDynamicComboCommand); // Command for the combo's list var comboListCmdID = new CommandID( GuidList.guidFirstToolWinCmdSet, PkgCmdIDList.cmdidWindowsMediaFilenameGetList); var comboMenuList = new OleMenuCommand( new EventHandler(ComboListHandler), comboListCmdID); mcs.AddCommand(comboMenuList); }
This code adds three commands, one for the button and two for the combo box. The combo box requires two commands, one for when the user makes an entry, and one to fill the drop-down list.
From the event handlers for the toolbar controls, your code must be able to access the Media Player control, which is a child of the MyControl class.
In Solution Explorer, right-click MyControl.cs, click View Code, and add the following code to the end of the file, just before the final two closing braces.
public AxWMPLib.AxWindowsMediaPlayer MediaPlayer { get { return axWindowsMediaPlayer1; } }
Save and close MyControl.cs.
Return to MyToolWindow.cs, and add the following code at the end of the class, just before the two final closing braces.
private void ButtonHandler(object sender, EventArgs arguments) { if (comboValue != null && comboValue.Trim().Length != 0) { LoadFile(comboValue); } } private void ComboHandler(object sender, EventArgs arguments) { var eventArgs = arguments as OleMenuCmdEventArgs; if (eventArgs != null) { IntPtr output = eventArgs.OutValue; object input = eventArgs.InValue; if (input != null) { comboValue = input.ToString(); } else if (output != IntPtr.Zero) { Marshal.GetNativeVariantForObject(comboValue, output); } } } public void LoadFile(string comboValue) { control.MediaPlayer.URL = comboValue; } private void ComboListHandler(object sender, EventArgs arguments) { }
Notice that menuMyDynamicComboCommand and menuItem share the same event handler. Therefore, the tool window can play the file that is specified in the combo box. In this tutorial, you do not provide code for the ComboListHandler function. In the next tutorial, VSPackage Tutorial 3: How to Extend the Tool Window, you add code that fills the drop-down list by using playlist names.
The combo handler saves whatever is typed into it in a member variable. To add that variable, add the following code at the top of the class.
string comboValue = "";
When the button is clicked, the button reads the value of this local variable and loads it in the Media Player.
Set the Default Position for the Tool Window
Next, specify a default location in the IDE for the tool window. Configuration information for the tool window is in the FirstToolWinPackage.cs file.
To set the default position for the tool window
In Solution Explorer, open FirstToolWinPackage.cs. In this file, find the following line (about 45 lines down).
[ProvideToolWindow(typeof(MyToolWindow))]
ProvideToolWindowAttribute is an attribute class. This code is passing the MyToolWindow type to the constructor. To specify a default position, you must add more parameters to the constructor.
Replace the line with the following one.
[ProvideToolWindow(typeof(MyToolWindow), Style = Microsoft.VisualStudio.Shell.VsDockStyle.Tabbed, Window = "3ae79031-e1bc-11d0-8f78-00a0c9110057")]
The first named parameter is Style and its value is Tabbed, which means that the window will be a tab in an existing window. The window is given by the Window named parameter; its value is a GUID. In this case, the GUID is the one for Solution Explorer.
Note
For more information about the GUIDs for windows in the IDE, see vsWindowKind Constants on the MSDN Web site.
Save your work.
Testing the Tool Window
To test the tool window
Press F5 to open a new instance of the Visual Studio experimental build.
On the View menu, point to Other Windows and then click Windows Media Player.
The media player tool window should open in the same window as Solution Explorer.
In the combo box in the media player tool window, enter the full path and file name of a supported sound or video file, for example, c:\windows\media\chimes.wav, press Enter, and then click the adjoining button.
Note
You have to enter a file name in the text box because the media player tool window does not have a File Open dialog box. In Tutorial 4, you can add a File Open dialog box.
What's Next
In VSPackage Tutorial 3: How to Extend the Tool Window, you can learn how to add more controls to the tool window. You add a button that displays a File Open dialog box, which you can use to select a file to play in the Media Player. You also add a drop-down list of playlists so that you can select one of them to play.
See Also
Tasks
Walkthrough: Adding a Toolbar to the IDE
Walkthrough: Adding a Toolbar to a Tool Window (C#)