Creating a Recognizer Class


Let's start by creating a class that implements ISmartTagRecognizer. Our class will be similar to the class we created in Listing 16.7 and will recognize part numbers in a document. In the newly created project, there is already a class created for you, called Class1, in a file called Class1.vb. Add a Imports SmartTag = Microsoft.Office.Interop.SmartTag line to the Imports statements at the top of the class to bring the SmartTag interfaces into a namespace called SmartTag. Rename Class1 to be a class called Recognizer, and declare the class to implement SmartTag.ISmartTagRecognizer. The class now looks like this:

Imports System.Collections.Generic Imports System.Text Imports SmartTag = Microsoft.Office.Interop.SmartTag Public Class Recognizer   Implements SmartTag.ISmartTagRecognizer End Class 


Visual Studio provides a neat trick for implementing the ISmartTagRecognizer interface. After you type the line Implements SmartTag.ISmartTagRecognizer, when you press the Enter key at the end of the line Visual Studio automatically creates an initial implementation of the ISmartTagRecognizer interface, as shown in Listing 16.8.

Listing 16.8. An Initial Stub Implementation of a Smart Tag Recognizer Class

using System; Imports System.Collections.Generic Imports System.Text Imports SmartTag = Microsoft.Office.Interop.SmartTag Public Class Recognizer   Implements SmartTag.ISmartTagRecognizer   Public ReadOnly Property Desc( _     ByVal LocaleID As Integer) As String _     Implements SmartTag.ISmartTagRecognizer.Desc     Get     End Get   End Property   Public ReadOnly Property Name( _     ByVal LocaleID As Integer) As String _     Implements SmartTag.ISmartTagRecognizer.Name     Get     End Get   End Property   Public ReadOnly Property ProgId() As String _     Implements SmartTag.ISmartTagRecognizer.ProgId     Get     End Get   End Property   Public Sub Recognize(ByVal Text As String, _     ByVal DataType As SmartTag.IF_TYPE, _     ByVal LocaleID As Integer, _     ByVal RecognizerSite As SmartTag.ISmartTagRecognizerSite) _     Implements SmartTag.ISmartTagRecognizer.Recognize   End Sub   Public ReadOnly Property SmartTagCount() As Integer _     Implements SmartTag.ISmartTagRecognizer.SmartTagCount     Get     End Get   End Property   Public ReadOnly Property SmartTagDownloadURL(_     ByVal SmartTagID As Integer) As String _     Implements SmartTag.ISmartTagRecognizer.SmartTagDownloadURL     Get     End Get   End Property   Public ReadOnly Property SmartTagName( _     ByVal SmartTagID As Integer) _     As String _     Implements SmartTag.ISmartTagRecognizer.SmartTagName     Get     End Get   End Property End Class 


We must implement six properties (ProgID, SmartTagCount, Desc, Name, SmartTagDownloadURL, and SmartTagName) and one method (Recognize). Let's start by implementing the properties.

The ProgID property is required only for COM Smart Tags. For our Smart Tag, we will return Nothing.

Public ReadOnly Property ProgId() As String _   Implements SmartTag.ISmartTagRecognizer.ProgId   Get     Return Nothing   End Get End Property 


Now let's implement the SmartTagCount property. Normally, this property should return the Integer value 1. This property does not affect how many terms our recognizer can recognize; it affects only how many unique recognizers our Smart Tag recognizer class provides. For simplicity, it usually is easiest to have one Smart Tag recognizer class expose one unique recognizer:

Public ReadOnly Property SmartTagCount() As Integer _   Implements SmartTag.ISmartTagRecognizer.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 recognizer. 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.ISmartTagRecognizer.Desc   Get     Return "Recognizes Part Numbers in PN#### format."   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 recognizer. When the Smart Tag is listed in an Office dialog box, this name will display in parentheses to the right of the string returned by SmartTagCaption in the Action class. Name should return a string no longer than 30 characters. We'll return the string "English" to indicate to the user that our Smart Tag is not localized into other locales:

Public ReadOnly Property Name( _   ByVal LocaleID As Integer) As String _   Implements SmartTag.ISmartTagRecognizer.Name   Get     Return "English"   End Get End Property 


The SmartTagDownloadURL property takes a Smart Tag ID as an Integer and returns a URL as a String where Smart Tag actions associated with this recognizer can be downloaded from. For this example, we will be providing the Smart Tag action class in the same DLL, so we will always return Nothing.

Public ReadOnly Property SmartTagDownloadURL( _   ByVal SmartTagID As Integer) As String _   Implements SmartTag.ISmartTagRecognizer.SmartTagDownloadURL   Get     Return Nothing   End Get End Property 


This is the first property we have seen that is passed a smartTagID as a parameter. A Smart Tag ID is an Integer value that for this recognizer class will always be passed 1 because the code returns 1 for the SmartTagCount property. If the code returned some other number for SmartTagCountsay, 5all methods that are passed a Smart Tag ID parameter in the recognizer class would be called five times, once with smartTagID set to 1, then 2, then 3, and so on. This lets one Smart Tag recognizer class provide multiple Smart Tags recognizers.

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 must be in the form namespaceURI#tagname. A valid namespace URI would be something like a company Web site's URL followed by a unique directory for the Smart Tag name. So in our case, we will use the URL http://www.aw-bc.com/VSTO. For the tag name, we will use our Smart Tag namespace PartNumberSmartTag. The critical thing when constructing your Smart Tag name is to make sure that it will be unique and not conflict with Smart Tags released by other companies or by your company:

Public ReadOnly Property SmartTagName( _   ByVal SmartTagID As Integer) _   As String _   Implements SmartTag.ISmartTagRecognizer.SmartTagName   Get     Return "http://www.aw-bc.com/VSTO#PartNumberSmartTag"   End Get End Property 


Now we have arrived at the method that does all the work of recognizing text in the document: the Recognize method. The method is passed parameters very similar to those passed to Recognize in Listing 16.7. The text to be looked at by our code is passed in as a String. The locale ID is passed in if our recognizer needs to recognize different text depending on the locale. An instance of the ISmartTagRecognizerSite interface is passed in as well. We will use this interface to associate a property bag with any text we recognize in the document.

Text that is recognized is marked with a property bag. The property bag can be emptybut for this example, we will stick a namevalue pair in the property bag to store a price. When we find some text we recognize, we must create a new property bag using ISmartTagRecognizerSite's GetNewPropertyBag method. This method returns an ISmartTagProperties object. We can use this object to write namevalue pairs into the property bag through ISmartTagProperties Write method that takes a key as a String and a value as a String. For this example, we will generate a property with key of "Price" and value being the price of the part identified by the part number we locate in the document.

To tell Office where recognized text is found, you must call ISmartTagRecognizerSite's CommitSmartTag method. This method takes the Smart Tag name as a String (we just call our existing implementation of SmartTagName to get this), the 1-based start position of the recognized text as an Integer, the length of the text we recognized as an Integer, and the ISmartTagProperties object we created using the GetNewPropertyBag method. This is a little different from the document-level custom class we created in Listing 16.7, where the start position of the recognized text was 0-based.

Listing 16.9 shows the final implementation of our Recognizer class.

Listing 16.9. The Final Implementation of a Smart Tag Recognizer Class

Imports System.Collections.Generic Imports System.Text Imports SmartTag = Microsoft.Office.Interop.SmartTag Public Class Recognizer   Implements SmartTag.ISmartTagRecognizer   Public ReadOnly Property Desc( _     ByVal LocaleID As Integer) As String _     Implements SmartTag.ISmartTagRecognizer.Desc     Get       Return "Recognizes Part Numbers in PN#### format."     End Get   End Property   Public ReadOnly Property Name( _     ByVal LocaleID As Integer) As String _     Implements SmartTag.ISmartTagRecognizer.Name     Get       Return "English"     End Get    End Property    Public ReadOnly Property ProgId() As String _      Implements SmartTag.ISmartTagRecognizer.ProgId      Get        Return Nothing      End Get    End Property    Public Sub Recognize(ByVal Text As String, _      ByVal DataType As SmartTag.IF_TYPE, _      ByVal LocaleID As Integer, _      ByVal RecognizerSite As SmartTag.ISmartTagRecognizerSite) _      Implements SmartTag.ISmartTagRecognizer.Recognize      Dim textToFind As String = "PN"      Const length As Integer = 6 ' Found part numbers will      ' always be 6 characters long      Dim startIndex As Integer = 0      Dim index As Integer = 0      While Text.IndexOf(textToFind, startIndex) >= 0        index = Text.IndexOf(textToFind, startIndex)        If index + length <= Text.Length Then          Dim partNumber As String = Text.Substring(index, length)          Dim price As String = ""          If IsValidPart(partNumber, price) Then            Dim props As SmartTag.ISmartTagProperties = _              RecognizerSite.GetNewPropertyBag()            props.Write("Price", price)            RecognizerSite.CommitSmartTag(SmartTagName(1), _                index + 1, length, props)          End If        End If        startIndex = index + textToFind.Length      End While    End Sub    Public ReadOnly Property SmartTagCount() As Integer _      Implements SmartTag.ISmartTagRecognizer.SmartTagCount      Get        Return 1      End Get     End Property     Public ReadOnly Property SmartTagDownloadURL( _       ByVal SmartTagID As Integer) As String _       Implements SmartTag.ISmartTagRecognizer.SmartTagDownloadURL      Get        Return Nothing      End Get    End Property    Public ReadOnly Property SmartTagName( _      ByVal SmartTagID As Integer) As String _      Implements SmartTag.ISmartTagRecognizer.SmartTagName      Get        Return "http://www.aw-bc.com/VSTO#PartNumberSmartTag"      End Get    End Property    Private Function IsValidPart(ByVal partNumber As String, _      ByRef price As String) As Boolean      Dim numericPartNumber As Int32 = 0      Try        numericPartNumber = _          Convert.ToInt32(partNumber.Substring(2, 4))      Catch      End Try      ' Only part numbers greater than 1000 are valid      If numericPartNumber > 1000 Then        Dim rnd As New Random()        price = rnd.Next(100).ToString()        Return True      End If      price = "N/A"      Return False    End Function End Class 





Visual Studio Tools for Office(c) Using Visual Basic 2005 with Excel, Word, Outlook, and InfoPath
Visual Studio Tools for Office: Using Visual Basic 2005 with Excel, Word, Outlook, and InfoPath
ISBN: 0321411757
EAN: 2147483647
Year: N/A
Pages: 221

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net