The document-level projects for Excel and Word in VSTO (in Visual Studio 2005 and Visual Studio 2008) provide a simple object model that you can use to create smart tags for documents and workbooks. A smart tag is a string that an Office application recognizes in a document. After the application recognizes the string, it displays a small icon next to the text. The user can then click that icon to display a list of actions they can choose from and activate. Typically, the actions are related to in some way to the identified text. For example, you could have a smart tag that recognizes stock symbols; when a user types an uppercase string of letters that matches a known stock symbol, a list of stock-related actions, such as looking up a stock price, could appear.
In most ways, creating smart tags using VSTO is much easier than creating smart tags without VSTO. However, there are some limitations that might prevent you from using VSTO to create smart tags. Even if you cannot use VSTO to create a smart tag, you can still use features in a VSTO add-in from the smart tag.
In this discussion, I'll refer to smart tags created by using VSTO as "VSTO smart tags", and smart tags created without using VSTO as "COM smart tags".
Creating VSTO Smart Tags
Creating a VSTO smart tag is relatively straightforward: you create a SmartTag object that recognizes one or more terms, create one or more Action objects that define the code that runs when the user clicks your smart tag options, and finally add the SmartTag object to the VstoSmartTags property of the ThisDocument or ThisWorkbook class in your project.
The following somewhat contrived example demonstrates a simple smart tag in an Excel workbook project. This smart tag recognizes the term "sale", and when clicked, the action displays the address of the cell that contains the recognized term in a message box. This code assumes it is running from the ThisWorkbook class in the project.
Private SmartTagExample As Microsoft.Office.Tools.Excel.SmartTagPrivate WithEvents DisplayAddressAction As Microsoft.Office.Tools.Excel.Action Private Sub AddSmartTag() SmartTagExample = New Microsoft.Office.Tools.Excel.SmartTag( _ "www.microsoft.com/Demo#DemoSmartTag", "Smart Tag Example") SmartTagExample.Terms.Add("sale") DisplayAddressAction = New Microsoft.Office.Tools.Excel.Action( _ "Display Cell Address") ' Add the action to the smart tag. SmartTagExample.Actions = New Microsoft.Office.Tools.Excel.Action() { _ DisplayAddressAction} ' Add the smart tag to the workbook. Me.VstoSmartTags.Add(SmartTagExample)End Sub Private Sub DisplayAddress_Click(ByVal sender As Object, _ ByVal e As Microsoft.Office.Tools.Excel.ActionEventArgs) _ Handles DisplayAddressAction.Click Dim smartTagAddress As String = e.Range.Address( _ ReferenceStyle:=Excel.XlReferenceStyle.xlA1) MsgBox("The recognized text '" & e.Text & _ "' is at range " & smartTagAddress)End Sub
Private SmartTagExample As Microsoft.Office.Tools.Excel.SmartTagPrivate WithEvents DisplayAddressAction As Microsoft.Office.Tools.Excel.Action
Private Sub AddSmartTag() SmartTagExample = New Microsoft.Office.Tools.Excel.SmartTag( _ "www.microsoft.com/Demo#DemoSmartTag", "Smart Tag Example") SmartTagExample.Terms.Add("sale") DisplayAddressAction = New Microsoft.Office.Tools.Excel.Action( _ "Display Cell Address")
' Add the action to the smart tag. SmartTagExample.Actions = New Microsoft.Office.Tools.Excel.Action() { _ DisplayAddressAction}
' Add the smart tag to the workbook. Me.VstoSmartTags.Add(SmartTagExample)End Sub
Private Sub DisplayAddress_Click(ByVal sender As Object, _ ByVal e As Microsoft.Office.Tools.Excel.ActionEventArgs) _ Handles DisplayAddressAction.Click
Dim smartTagAddress As String = e.Range.Address( _ ReferenceStyle:=Excel.XlReferenceStyle.xlA1) MsgBox("The recognized text '" & e.Text & _ "' is at range " & smartTagAddress)End Sub
For more information, see How to: Add Smart Tags to Word Documents and How to: Add Smart Tags to Excel Workbooks in the VSTO documentation.
Limitations of VSTO Smart Tags
Although VSTO smart tags are easy to implement, they do have several limitations:
If you need to create a smart tag for an application other than Word or Excel, or you need to create an application-level smart tag for Word or Excel, you must create a COM smart tag.
Creating COM Smart Tags
To create a COM smart tag, use the Smart Tag SDK to create a managed (or unmanaged, if you prefer) DLL that implements the ISmartTagRecognizer and ISmartTagAction COM interfaces at a minimum, and optionally other interfaces, depending on the features you want to provide. This requires familiarity with COM programming, and that you implement all of the properties and methods of these interfaces, even those you don't intend to use. The DLL must also be registered on end user computers, as described in the Smart Tag SDK.
At this point, you might be wondering whether you could implement a COM smart tag in a VSTO add-in, since a VSTO add-in is a managed assembly, and you can implement COM interfaces in managed code.
You could, but you probably don't want to. The reason for this is that add-ins and smart tag DLLs have entirely different discovery and load mechanisms in Office:
The implication of these differences is that if you implement the smart tag COM interfaces in a VSTO add-in assembly, your assembly will be loaded twice: once as an add-in, and again as a smart tag DLL. Depending on the size of your add-in, this could result in a lot of redundant code being loaded into memory. Furthermore, because every VSTO add-in is loaded into a separate application domain, the two instances of your assembly will be in separate application domains, and cannot easily share code or data. Because of these issues, there is not much of a benefit to implement a COM smart tag in a VSTO add-in.
Calling Into A VSTO Add-in From a COM Smart Tag—Is It Possible?
If you're following me this far, your next question might be "OK, so if I implement a COM smart tag DLL and a VSTO add-in as part of my overall Office solution, how can I call into my add-in from my smart tag?" Because there are many Office customization features that can be used only in an add-in, you can probably think of many scenarios where this might be useful. For example, you might implement a custom task pane in an add-in for Excel, and you want to display unique information on this task pane when the user clicks a smart tag action in any open workbook. When the user clicks your action, how can your smart tag tell your add-in to display data in the custom task pane?
There are a number of ways you can do this. Any technology that enables you to communicate between application domains, such as .NET remoting or Windows Communication Foundation, should work, with varying degrees of complexity. However, the easiest way to do this is to expose an object in your add-in to other Office solutions, and then to call into this object from your smart tag. My next post will show how to do this.
--------------------------------------------------
McLean Schofield, programming writer