Now that we have a complete Smart Tag recognizer class, we will create a Smart Tag action class. Right-click the class library project in Solution Explorer, and choose Add and then Class to add a second class to the project. Visual Studio will create a class called Class2 by default. Add a Imports SmartTag = Microsoft.Office.Interop.SmartTag line to the using statements at the top of the class to bring the Smart Tag interfaces into a namespace called SmartTag. Rename Class2 to be a class called Action, and declare the class to implement SmartTag.ISmartTagAction. The class now looks like this: Imports System.Collections.Generic Imports System.Text Imports SmartTag = Microsoft.Office.Interop.SmartTag Public Class Action Implements SmartTag.ISmartTagAction End Class Use the Implement Interface trick again for implementing the ISmartTagAction interface. Visual Studio automatically creates an initial implementation of the ISmartTagAction interface when you press Enter after typing the line Implements SmartTag.ISmartTagAction, as shown in Listing 16.10. Listing 16.10. An Initial Stub Implementation of a Smart Tag Action Class
We must implement ten properties (ProgID, SmartTagCount, Desc, Name, SmartTagCaption, SmartTagName, VerbCaptionFromID, VerbCount, VerbID, and VerbNameFromID) and one method (InvokeVerb). Let's start by implementing the properties. The ProgID property returns Nothing because it is used only for COM Smart Tags: Public ReadOnly Property ProgId() As String _ Implements SmartTag.ISmartTagAction.ProgId Get Return Nothing End Get End Property Now let's implement the SmartTagCount property. As described earlier, for simplicity, it is usually easiest to return just 1. This does not affect how many available "verbs" or menu commands we can provide for a recognized part number: Public ReadOnly Property SmartTagCount() As Integer _ Implements SmartTag.ISmartTagAction.SmartTagCount Get Return 1 End Get End Property The Desc property takes a locale ID as an Integer and returns a String representing the description of the Smart Tag action. You can use the locale ID to provide localized descriptions, if you want to. For our purposes, the code will return a simple description String for all locales: Public ReadOnly Property Desc( _ ByVal LocaleID As Integer) As String _ Implements SmartTag.ISmartTagAction.Desc Get Return "Provides actions for the part number Smart Tag." End Get End Property The Name property takes a locale ID as an Integer and returns a String representing the name of the Smart Tag action. The name should match what you returned for your Recognizer class: Public ReadOnly Property Name( _ ByVal LocaleID As Integer) As String _ Implements SmartTag.ISmartTagAction.Name Get Return "The PN#### Smart Tag" End Get End Property The SmartTagName property takes a Smart Tag ID as an Integer and returns a unique identifier as a String for the Smart Tag. The identifier should match what was returned in the Recognizer class implementation: Public ReadOnly Property SmartTagName( _ ByVal SmartTagID As Integer) As String _ Implements SmartTag.ISmartTagAction.SmartTagName Get Return "http://www.aw-bc.com/VSTO#PartNumberSmartTag" End Get End Property The SmartTagCaption property takes a Smart Tag ID as an Integer and a locale ID as an Integer. It returns a String that will be the caption used in the pop-up menu for the recognized text. It will also be used as the primary name of the Smart Tag in Office's Smart Tag dialog boxes: Public ReadOnly Property SmartTagCaption( _ ByVal SmartTagID As Integer, _ ByVal LocaleID As Integer) As String _ Implements SmartTag.ISmartTagAction.SmartTagCaption Get Return "Part Number Smart Tag" End Get End Property The VerbCount property returns as an Integer how many verbs or menu commands that this Action will provide to the Smart Tag menu. It is passed as a parameter the Smart Tag name for which the verb count is requested; you can ignore this parameter if you returned 1 for the SmartTagCount property. For this example, we provide two verbs or menu commands: one to display the price and the other to open a Web page to the price. So the implementation of VerbCount returns 2: Public ReadOnly Property VerbCount( _ ByVal SmartTagName As String) As Integer _ Implements SmartTag.ISmartTagAction.VerbCount Get Return 2 End Get End Property The VerbID property gets a unique Integer identifier called a verb ID for each verb. This property is passed a verb index as an Integer that will be a number 1 through the number of verbs returned from the VerbCount implementation. For simplicity, we reuse the verbIndex passed into this method as the verb ID: Public ReadOnly Property VerbID(ByVal SmartTagName As String, _ ByVal VerbIndex As Integer) As Integer _ Implements SmartTag.ISmartTagAction.VerbID Get Return VerbIndex End Get End Property The VerbCaptionFromID property is passed a verb ID number as an Integer, the application name showing the Smart Tag as a String, and the locale ID as an Integer. Because we are using the verb index as the verb ID because of how we implemented VerbID, the verb ID passed in will be 1 through the number of verbs returned from VerbCount. The property returns a String for the menu command caption to use for each verb supported by the action class. Within the string, you can use three forward slashes in a row to create submenus and the ampersand (&) characters to tell Office what to use for accelerators in the menus. Here, we have defined the return strings so we will have a Part Number menu with two submenus: Show part price and Show part Web page. We have also indicated that N should be the accelerator for the Part Number menu, P should be the accelerator for the Show part price submenu, and W should be the accelerator for the Show part Web page submenu. Public ReadOnly Property VerbCaptionFromID( _ ByVal VerbID As Integer, ByVal ApplicationName As String, _ ByVal LocaleID As Integer) As String _ Implements SmartTag.ISmartTagAction.VerbCaptionFromID Get Select Case VerbID Case 1 Return "Part &Number///Show part &price..." Case 2 Return "Part &Number///Show part &web page..." Case Else Return Nothing End Select End Get End Property The VerbNameFromID property takes a verb ID as an Integer and returns an identifier String for each verb. We return some unique strings for our two verbs: Public ReadOnly Property VerbNameFromID( _ ByVal VerbID As Integer) As String _ Implements SmartTag.ISmartTagAction.VerbNameFromID Get Select Case VerbID Case 1 Return "ShowPartPrice" Case 2 Return "ShowPartWebPage" Case Else Return Nothing End Select End Get End Property Now we have arrived at the method that does all the work of handling a selected verb: the InvokeVerb method. This method takes the verb ID as an Integer, the name of the application the Smart Tag is being displayed in as a String, the property bag associated with the recognized text as an ISmartTagProperties object, the text that was recognized as a String, and the XML that was recognized as a String. The implementation of InvokeVerb for this example first checks what verb is passed. Because the Smart Tag returned 2 for VerbCount, it will be passed a verb ID of 1 or 2. If the verb ID is 1, the code displays the price of the item by using the ISmartTagProperties object to read the price value the Recognizer class wrote to the property bag when it recognized the text. If the verb ID is 2, the code displays a dialog box threatening to launch a Web page for the part number, which is passed in as the recognized text string. Listing 16.11 shows the complete implementation of our Action class. Because the Action class displays a message box, be sure to add a reference to the System.Windows.Forms library. Listing 16.11. The Final Implementation of a Smart Tag Action Class
|