Writing Add-Ins for Visual Studio .NET

 < Free Open Study > 


A Simple UI: DTE Menu Items

If your add-in does not have many different functions, you may be able to get away with using the simplest type of UI, the DTE menu item. Although you have only used one menu item in this book's add-ins thus far, it is certainly possible to add more than one, as you will see in this section.

Note 

I call these menu items "DTE menu items" because I am using DTE command methods to create the menus. Later in this chapter I show you how to create menus and toolbars using the Microsoft Office command bar controls.

To create another new add-in for the creation of multiple menus, go to the Add-in Wizard once again. By now, you should be adept at creating add-ins with the wizard, so I'll simply tell you the options to use, without illustrating the process with figures.

First, open Visual Studio and click the New Project button. Expand the Other Projects node on the TreeView, and then click the Extensibility Projects folder. Single-click the Visual Studio .NET Add-in icon. Enter UIMenus into the Name text box, and choose a path where you want this new add-in project saved.

I always choose a directory that I've set up for my projects, so I don't have to remember where Visual Studio saves projects by default. Click the OK button to start the wizard.

In Step 1, select the Visual Basic Add-in option. In Step 2, check only the Visual Studio .NET Add-in check box. In Step 3, enter UIMenus in the Name box. Enter a description such as Testing multiple menu items.

In Step 4, check the first, third, and fourth check boxes. In other words, check all boxes except the one that says your add-in won't display a modal UI. You will be displaying a modal UI, even if only in the form of a message box. Do not check the box in Step 5-just click Next to move to Step 6. If you are satisfied with the options that you have selected, as displayed in Step 6, click the Finish button to create the add-in.

When the wizard creates the add-in, your code should look like Listing 7-1.

Note 

The code generated by the Add-in Wizard will not be automatically continued. I did that manually so that the code would fit onto the book's pages.

Listing 7-1: Add-in Code Created by the Add-in Wizard

Imports Microsoft.Office.Core imports Extensibility imports System.Runtime.InteropServices Imports EnvDTE #Region " Read me for Add-in installation and setup information. " ' When run, the Add-in wizard prepared the registry for the Add-in. ' At a later time, if the Add-in becomes unavailable for reasons such as: ' 1) You moved this project to a computer other than ' the one it was originally created on. ' 2) You chose 'Yes' when presented with a message asking ' if you wish to remove the Add-in. ' 3) Registry corruption. ' you will need to re-register the Add-in by building the UIMenusSetup project ' by right-clicking the project in the Solution Explorer, then choosing install. #End Region <GuidAttribute("A1DD20DF-FC66-4E5D-B0C3-1831FF589E42"), _ ProgIdAttribute("UIMenus.Connect")> _ Public Class Connect Implements Extensibility.IDTExtensibility2 Implements IDTCommandTarget Dim applicationObject As EnvDTE.DTE Dim addInInstance As EnvDTE.AddIn Public Sub OnBeginShutdown(ByRef custom As System.Array) _ Implements Extensibility.IDTExtensibility2.OnBeginShutdown End Sub Public Sub OnAddInsUpdate(ByRef custom As System.Array) _ Implements Extensibility.IDTExtensibility2.OnAddInsUpdate End Sub Public Sub OnStartupComplete(ByRef custom As System.Array) _ Implements Extensibility.IDTExtensibility2.OnStartupComplete End Sub Public Sub OnDisconnection(ByVal RemoveMode As _ Extensibility.ext_DisconnectMode, _ ByRef custom As System.Array) Implements _ Extensibility.IDTExtensibility2.OnDisconnection End Sub Public Sub OnConnection(ByVal application As Object, _ ByVal connectMode As Extensibility.ext_ConnectMode, _ ByVal addInInst As Object, _ ByRef custom As System.Array) Implements _ Extensibility.IDTExtensibility2.OnConnection applicationObject = CType(application, EnvDTE.DTE) addInInstance = CType(addInInst, EnvDTE.AddIn) If connectMode = Extensibility.ext_ConnectMode.ext_cm_UISetup Then Dim objAddIn As AddIn = CType(addInInst, AddIn) Dim CommandObj As Command ' When run, the Add-in wizard prepared the registry for the Add-in. ' At a later time, the Add-in or its commands may become ' unavailable for reasons such as: ' 1) You moved this project to a computer other than the ' one it was originally created on. ' 2) You chose 'Yes' when presented with a message asking ' if you wish to remove the Add-in. ' 3) You add new commands or modify commands already defined. ' You will need to re-register the Add-in by building the ' UIMenusSetup project, ' right-clicking the project in the Solution Explorer, and then ' choosing install. ' Alternatively, you could execute the ReCreateCommands.reg ' file the Add-in Wizard generated in ' the project directory, or run 'devenv /setup' from a command prompt. Try CommandObj = applicationObject.Commands. AddNamedCommand(objAddIn, _ "UIMenus", "UIMenus", "Executes the command for UIMenus", _ True, 59, Nothing, 1 + 2) _ '1+2 == vsCommandStatusSupported+vsCommandStatusEnabled CommandObj.AddControl(applicationObject.CommandBars.Item("Tools")) Catch e As System.Exception End Try End If End Sub Public Sub Exec(ByVal cmdName As String, _ ByVal executeOption As vsCommandExecOption, _ ByRef varIn As Object, _ ByRef varOut As Object, _ ByRef handled As Boolean) _ Implements IDTCommandTarget.Exec handled = False If (executeOption = vsCommandExecOption.vsCommandExecOptionDoDefault) Then If cmdName = "UIMenus.Connect.UIMenus" Then handled = True Exit Sub End If End If End Sub Public Sub QueryStatus(ByVal cmdName As String, _ ByVal neededText As vsCommandStatusTextWanted, _ ByRef statusOption As vsCommandStatus, _ ByRef commandText As Object) _ Implements IDTCommandTarget.QueryStatus If neededText = _ EnvDTE.vsCommandStatusTextWanted.vsCommandStatusTextWantedNone Then If cmdName = "UIMenus.Connect.UIMenus" Then statusOption = CType(vsCommandStatus.vsCommandStatusEnabled + _ vsCommandStatus.vsCommandStatusSupported, vsCommandStatus) Else statusOption = vsCommandStatus.vsCommandStatusUnsupported End If End If End Sub End Class

As you have seen in earlier chapters, the Add-in Wizard creates one menu item for you. Now, you need to make some modifications to the code to add two more menu items. Actually, you can add as many menu items as you want to, but practically speaking, that would not make for an ideal UI. Any number of menu items beyond four or five might border on the ridiculous. The changes you make will accomplish the following:

Listing 7-2 shows the code generated by the wizard after the specified changes are made. The changes appear in boldface.

Listing 7-2: Code Modified to Add Menus

Imports Microsoft.Office.Core imports Extensibility imports System.Runtime.InteropServices Imports EnvDTE #Region " Read me for Add-in installation and setup information. " ' When run, the Add-in wizard prepared the registry for the Add-in. ' At a later time, if the Add-in becomes unavailable for reasons such as: ' 1) You moved this project to a computer other than the one it was ' originally created on. ' 2) You chose 'Yes' when presented with a message asking if you ' wish to remove the Add-in. ' 3) Registry corruption. ' you will need to re-register the Add-in by building the UIMenusSetup project ' by right-clicking the project in the Solution Explorer, then choosing install. #End Region <GuidAttribute("A1DD20DF-FC66-4E5D-B0C3-1831FF589E42"), _ ProgIdAttribute("UIMenus.Connect")> _ Public Class Connect Implements Extensibility.IDTExtensibility2 Implements IDTCommandTarget ' shortened applicationObject to oVB for ease of reading Dim oVB As EnvDTE.DTE Dim addInInstance As EnvDTE.AddIn ' CommandObjs moved to module level so Disconnect can see them Dim CommandObj As Command Dim CommandObj2 As Command Dim CommandObj3 As Command Public Sub OnBeginShutdown(ByRef custom As System.Array) _ Implements Extensibility.IDTExtensibility2.OnBeginShutdown End Sub Public Sub OnAddInsUpdate(ByRef custom As System.Array) _ Implements Extensibility.IDTExtensibility2.OnAddInsUpdate End Sub Public Sub OnStartupComplete(ByRef custom As System.Array) _ Implements Extensibility.IDTExtensibility2.OnStartupComplete End Sub Public Sub OnDisconnection(ByVal RemoveMode As _ Extensibility.ext_DisconnectMode, _ ByRef custom As System.Array) Implements _ Extensibility.IDTExtensibility2.OnDisconnection Try CommandObj.Delete() CommandObj2.Delete() CommandObj3.Delete() Catch e As System.Exception MsgBox("Error deleting menus: " & e.Message) End Try End Sub Public Sub OnConnection(ByVal application As Object, _ ByVal connectMode As Extensibility.ext_ConnectMode, _ ByVal addInInst As Object, _ ByRef custom As System.Array) Implements _ Extensibility.IDTExtensibility2.OnConnection oVB = CType(application, EnvDTE.DTE) addInInstance = CType(addInInst, EnvDTE.AddIn) ' test for type startup, first or subsequent If connectMode = _ Extensibility.ext_ConnectMode.ext_cm_UISetup Or _ connectMode = _ Extensibility.ext_ConnectMode.ext_cm_Startup _ Then Dim objAddIn As AddIn = CType(addInInst, AddIn) ' When run, the Add-in wizard prepared the registry ' for the Add-in. ' At a later time, the Add-in or its commands may ' become unavailable ' for reasons such as: ' 1) You moved this project to a computer other ' than the one it was created on ' 2) You chose 'Yes' when presented with a message ' asking if you wish to remove the add-in ' 3) You add new commands or modify commands ' already defined. ' You will need to re-register the Add-in by building the ' UIMenusSetup project, ' right-clicking the project in the Solution Explorer, ' and then choosing install. ' Alternatively, you could execute the ' ReCreateCommands.reg ' file the Add-in ' Wizard generated in ' the project directory, or run 'devenv /setup' ' from a command prompt. Try CommandObj = oVB.Commands.AddNamedCommand(objAddIn, _ "UIMenus", "UIMenus One", _ "Executes the command for UIMenus", _ True, 59, Nothing, 1 + 2) _ '1+2 == vsCommandStatusSupported+ vsCommandStatusEnabled CommandObj.AddControl(oVB.CommandBars.Item("Tools")) CommandObj2 = oVB.Commands.AddNamedCommand(objAddIn, _ "UIMenus2", "UIMenus Two", _ "Executes the command for UIMenus", _ True, 60, Nothing, 1 + 2) _ '1+2 == vsCommandStatusSupported+ vsCommandStatusEnabled CommandObj2.AddControl(oVB.CommandBars.Item("Tools")) CommandObj3 = oVB.Commands.AddNamedCommand(objAddIn, _ "UIMenus3", "UIMenus Three", _ "Executes the command for UIMenus", _ True, 62, Nothing, 1 + 2) _ '1+2 == vsCommandStatusSupported+ vsCommandStatusEnabled CommandObj3.AddControl(oVB.CommandBars.Item("Tools")) Catch e As System.Exception MsgBox("Error Adding Menus: " & e.Message) End Try End If End Sub Public Sub Exec(ByVal cmdName As String, _ ByVal executeOption As vsCommandExecOption, _ ByRef varIn As Object, _ ByRef varOut As Object, _ ByRef handled As Boolean) _ Implements IDTCommandTarget.Exec handled = False If (executeOption = vsCommandExecOption. vsCommandExecOptionDoDefault) Then If cmdName = "UIMenus.Connect.UIMenus" Then handled = True MsgBox("Menu one selected.") ElseIf cmdName = "UIMenus.Connect.UIMenus2" Then MsgBox("Menu two selected.") ElseIf cmdName = "UIMenus.Connect.UIMenus3" Then MsgBox("Menu three selected.") End If End If End Sub Public Sub QueryStatus(ByVal cmdName As String, _ ByVal neededText As vsCommandStatusTextWanted, _ ByRef statusOption As vsCommandStatus, _ ByRef commandText As Object) _ Implements IDTCommandTarget.QueryStatus If neededText = _ EnvDTE.vsCommandStatusTextWanted.vsCommandStatusTextWantedNone Then If cmdName = "UIMenus.Connect.UIMenus" Or _ cmdName = "UIMenus.Connect.UIMenus2" Or _ cmdName = "UIMenus.Connect.UIMenus3" _ Then statusOption = CType(vsCommandStatus. vsCommandStatusEnabled + _ vsCommandStatus.vsCommandStatusSupported, vsCommandStatus) Else statusOption = vsCommandStatus.vsCommandStatusUnsupported End If End If End Sub End Class

The code shown in Listing 7-2 uses two Command methods: AddNamedCommand and AddControl. Although I illustrated the use of these methods in earlier chapters, I did not explain them. I will do that now.

The AddNamedCommand object creates a named command that is saved by the environment and can be made available the next time the environment starts, even if the add-in is not loaded on environment start-up.

Note 

Because I always delete the command object(s) in the OnDisconnection method of an add-in, the command(s) do not appear unless the add-in is connected.

The AddNamedCommand method returns a Command object and has several parameters, which are shown in Table 7-1.

Table 7-1: AddNamedCommand Parameters

PARAMETER

DESCRIPTION

Addin

Required. Refers to the Addin object that is adding the new command.

Name

Required. The nonunique name for the command.AddNamedCommand adds Addins.Progid to make the command unique.

Button Text

Required. This is the caption that will be displayed on the command.

Tool Tip

Required. This is the tool tip that will be displayed as the mouse hovers over the command.

MSOButton

Required. Indicates whether the named command's button picture is a Microsoft Office picture (True = button).

Bitmap

Optional. The integer ID of the bitmap to display. This is a pointer into Office.DLL.

ContextUIGuids

A SafeArray of GUIDs that determines which environment contexts (i.e., debug mode, design mode, and so on) enable the command. (I use Nothing for this parameter.)

DisableFlags

Determines whether the disabled state of the command is invisible or grey when you supply a ContextUIGUID and none are currently active (e.g., 1+2 == vsCommandStatusSupported + vsCommandStatusEnabled).

Listing 7-3 shows a typical call to the AddNamedCommand method.

Listing 7-3: AddNamedCommand Method Usage

CommandObj = oVB.Commands.AddNamedCommand(objAddIn, _ "UIMenus", "UIMenus One", "Executes the command for UIMenus", _ True, 59, Nothing, 1 + 2) _ '1+2 == vsCommandStatusSupported+vsCommandStatusEnabled CommandObj.AddControl(oVB.CommandBars.Item("Tools"))

The returned Command object has a method called AddControl. It is called to set the new command on the toolbar. In this demonstration, the control or Command object is a menu item that is added to the Tools menu. To run the add-in, simply click the Start button or press F5. If you have no compile errors, a second instance of Visual Studio will be automatically started. The add-in should be automatically connected, and the menus should be visible when you click the Tools menu. If they are not, click the Tools menu and then the Add-in Manager menu item to display the Add-in Manager dialog box. Check both check boxes for the UIMenus add-in. When you click OK to close the dialog box, the add-in will connect. Click each of the add-in's menus to see that the event handler is correctly handling the menu clicks. Figure 7-1 shows the Tools menu with the three menu items that have been added by the add-in.

Figure 7-1: UIMenus add-in menu items

Note 

You can download the code for this book from the Downloads section of the Apress Web site (http://www.apress.com).You can find the code for this chapter in several directories.You will find one for each add-in created for this chapter under the name of the respective UI topic.


 < Free Open Study > 

Категории