深入理解VSTO 智能标记和COM智能标记

  

作者:McLean Schofield

发布时间:2008/05/02  12:09 PM

翻译:lancet(Jinmu)

英文原文:Understanding VSTO Smart Tags and COM Smart Tags 

  

VS2005 和VS2008中,创建Excel 和Word文档级别的工程时,VSTO提供简单的对象模型 让你为文档或工作薄创建智能标记。智能标记是一种能够被 Office 应用程序在文档中识别的字符串。当应用程序识别出这个字符串后, 在该字符串的附近将显示一个小图标,用户点击这个图标就能得到一个功能列表,从中你能够选中某一个并激活。通常,这些功能和 识别的字符串有某种联系,例如:你有一个和股票代码相关的智能标记,当用户在文档中输入的大写字符串和 已知的股票代码字符串相符合时,一个具有一系列和股票相关功能的智能标记将会显示在用户所输入字符串附近,比如说查看股票价格。

 

大多数情况下, 用VSTO要比用其他方法创建智能标记容易得多。但是,用VSTO 创建智能标记的时候有一些限制。 即使你不用VSTO创建智能标记,你仍然能够使用VSTO外接程序里智能标记的一些特性。

在该文中,我将VSTO 创建的智能标记称为“VSTO智能标记”,而将非VSTO创建的智能标记称作“COM智能标记”.

 

创建VSTO智能标记

创建VSTO智能标记相对来说比较简单:你仅需要创建一个SmartTag对象来识别一个或多个术语,创建一个或多个Action对象来定义你的智能标记上的选项所规定功能对应的代码,当用户点击这些选项时, 相应的代码将被执行. 最后将SmartTag 对象添加到ThisWorkBook或者ThisDocument类中的VSTOSmartTags属性中.

下面的VB代码展示了如何在Excel WorkBook项目中实现一个简单的智能标记。这个智能标记能够识别“sale”术语,当点击智能标记时,将弹出一个消息框显示包含已识别术语的单元格地址。假设这段代码从项目的ThisWorkbook类开始运行。 

Private SmartTagExample As Microsoft.Office.Tools.Excel.SmartTag
Private 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

你可以察看How to: Add Smart Tags to Word Documents 和How to: Add Smart Tags to Excel Workbooks得到更多相关信息。

使用VSTO智能标记的一些限制

尽管实现VSTO智能标记很容易,但它确实有些限制:

  • VSTO智能标记只能够使用在Word或者Excel中的文档级别的项目中。而不能够使用在为Word或者Excel应用程序级外接程序,因此, 在用户打开的其它Word文档或Excel 工作薄中将不能够使用这些智能标记,这个功能只能够适用于特定的文档工程,而不是一个普实的对任何其它的WorkBook或者Word都是通用的功能。(能够对任何文档或者WorkBook都能用的标签通常叫做应用程序级别的智能标记[译者注:VS2008 SP1已经增加了对应用程序级外接程序支持的智能标记]  

  • VSTO智能标记也不能用于其它的支持智能标记的Office 产品中,比如PowerPoint和Outlook(撰写邮件时使用了Word作为编辑器)。 [这点请读者查阅VS2008 sp1 相关文档]

如果你想为其它的非Word Excel应用程序创建智能标记,或者你需要为WordExcel 创建应用程序级别的智能标记, 那么你必须创建COM智能标记

创建COM智能标记

如果想创建一个COM智能标记,用Smart Tag SDK来创建托管(或非托管的)的DLL,你必须至少要实现 ISmartTagRecognizer ISmartTagAction 这两个COM接口,根据你的需要可选择性的实现其它的接口。这个要求对COM编程比较熟悉,你必须实现这些接口所有的属性和方法,即使你不需要那些方法和属性。同时,相应的DLL必须在终端用户的计算机上被注册,对此的描述可以在Smart Tag SDK中找到. 

 

VSTO 插件里实现COM 智能标记

现在,你可能很想知道是否能够在VSTO外接程序里实例化COM智能标记,因为VSTO外接程序是托管程序集,而在托管代码里是能够实例化COM 接口的。你可以,但很有可能不愿意这样去做。原因在于Office里插件和智能标记程序集有完全不同的查找和装载机制

  •  Office应用程序查找在注册表HKEY_CURRENT_USER"Software"Microsoft"Office"Common"Smart Tag键值下的智能标记DLL,然后调用智能标记的专用接口(比如ISmartTagRecognizer)来调用智能标记DLL
  •  在另一方面,Office应用程序在一个完全不同的并和应用程序有关的注册表键值下(link http://msdn.microsoft.com/en-us/library/bb386106.aspx )找外接程序的DLL,然后通过IDTExtensibility2接口来调用外接程序DLL
    • 题外话#1,如果是你一个对IDTExtensibility不了解的VSTO开发人员,VSTO抽象出IDTExtensibility2 接口使得实现和你的外接程序代码分离。VSTO运行时为你实现了这个接口,并将那些即将用到的函数转发给你的接口,以备外接程序中的ThisAddIn_Startup and ThisAddIn_Shutdown事件处理代码调用。
    • 题外话#2,如果你点击了IDTExtensibility2链接,正在好奇为什么会在Visual Studio扩展性文档里找到这个接口,那是因为这个接口(以及该文档定义的Extensibility.dll程序集)也是用来开发Visual Studio外接程序的。

这些差别也意味着,如果你在VSTO外接程序集里实现COM接口,你的程序集将会被装载两次:一次是作为一个外接程序,另一次是作为智能标记。要取决于你外接程序的大小,这很有可能导致大量的冗余代码装载到内存里。而且,每个VSTO插件装载在各自的应用程序域中,外接程序集的两个实例在不同的应用程序域中,因而不易共享代码和数据。因为存在这些问题, 在VSTO外接程序里实现一个COM 智能标记是一件吃力不讨好的事情。

从一个COM 智能标记里调用VSTO插件是可能的吗?

如果你看到这里,你的下一个问题很有可能就是“那好,如果我有实现了COM 智能标记的DLL和VSTO外接程序作为我的Office解决方案的一部分,那么我怎么才能从我的智能标记中调用我的外接程序呢”.大量的Office自定义项特性仅能够用于外接程序,你可能想在更多的场合用到这些特性。例如, 你有可能在Excel 的外接程序里实现了custom task pane (自定义任务窗格 )。在任何打开的工作薄里, 当用户点击智能标记里的特定功能时,你很有可能希望在任务窗格上显示专有信息。比如,当用户点击你设定的功能时,你的COM智能标记怎么才能够告诉你的外接程序把数据显示在自定义任务窗格?

这里有很多种方式来实现这个功能。任何能够使你和两个应用程序域之间进行通讯的技术, 例如.NET remoting or Windows Communication Foundation, 都能用,中间的差异仅仅是复杂程度不同而已.然而,最容易的办法是在插件中暴露一个对象给其他的Office解决方案,然后从你的智能标记中调用这个对象。我的下一篇文章将重点讲述这个如何做的。

 

 

posted @ 2008-10-14 15:39  dp/dt  阅读(2163)  评论(1编辑  收藏  举报