Microsoft Office 2000 和更高版本都支持一种新的统一的设计结构,这种结构用于生成应用程序加载项以增强和控制 Office 应用程序。这些加载项称为 COM 加载项。本文分步讨论了 Office COM 加载项并介绍了如何使用 Microsoft Visual Basic .NET 生成 Office COM 加载项。
回到顶端
IDTExensibility2 接口
COM 加载项是一种进程内 COM 服务器或 ActiveX 动态链接库 (DLL),它实现如 Microsoft 加载项设计器类型库 (Msaddndr.dll) 中所描述的
IDTExensibility2 接口。所有 COM 加载项都从此接口继承而来,而且都必须实现其五个方法中的每一个方法。
OnConnection
每当连接 COM 加载项时,都会激发
OnConnection 事件。加载项可以在启动时连接,由最终用户连接或者通过自动化来连接。如果
OnConnection 成功地返回,则表明已加载了加载项。如果返回错误消息,那么宿主应用程序就立即释放其对该加载项的引用,而且该对象将被破坏。
OnConnection 使用以下四个参数:
• | Application — 一个对宿主应用程序对象的引用。 |
• | ConnectMode — 一个指定加载项连接方式的常量。加载项可以使用以下几种方式连接:
• | ext_cm_AfterStartup — 加载项由最终用户从 COM 加载项对话框启动。 | • | ext_cm_CommandLine — 加载项从命令行连接。请注意,此方法不适用于生成 Office 应用程序的 COM 加载项。 | • | ext_cm_External — 加载项由外部应用程序通过自动化连接。请注意,此方法不适用于生成 Office 应用程序的 COM 加载项。 | • | ext_cm_Startup — 加载项由宿主在应用程序启动时启动。此行为由注册表中的设置来控制。 |
|
• | AddInInst — 一个对 COMAddIn 对象的引用,它引用宿主应用程序的 COMAddIns 集合中的此加载项。 |
• | Custom — 一个包含 Variant 类型值的数组,它可以存储用户定义的数据。 |
OnDisconnection
当 COM 加载项断开连接并且在它从内存中卸载之前,将激发
OnDisconnection 事件。加载项应在此事件中执行所有资源清理操作,并还原对宿主应用程序所做的任何更改。
OnDisconnection 使用以下两个参数:
• | RemoveMode — 一个指定加载项断开连接的方式的常量。加载项可以使用以下方式断开连接:
• | ext_dm_HostShutdown — 加载项在宿主应用程序关闭时断开连接。 | • | ext_dm_UserClosed — 加载项由最终用户或自动化控制器断开连接。 |
|
• | Custom — 一个包含 Variant 类型值的数组,它可以存储用户定义的数据。 |
OnAddInsUpdate
当注册的 COM 加载项集发生变化时,将激发
OnAddInsUpdate 事件。换言之,每当安装 COM 加载项或者从宿主应用程序中删除 COM 加载项时,都会激发此事件。
OnStartupComplete 和 OnBeginShutdown
当宿主应用程序在忙于向内存中加载自身或者从内存中卸载自身时应避免用户交互,而
OnStartupComplete 和
OnBeginShutdown 方法都是在宿主应用程序已离开或正要进入这一状态时被调用的。只有在启动期间已连接了加载项的情况下才调用
OnStartupComplete,只有宿主在关闭过程中要断开与加载项的连接的情况下才调用
OnBeginShutdown。
由于在激发这些事件时宿主应用程序的用户界面是完全活动的,因此它们可能是执行某些操作的唯一途径,以其他途径将无法从
OnConnection 和
OnDisconnection 中执行这些操作。
回到顶端
COM 加载项注册
除了正常的 COM 注册外,COM 加载项还需要向其运行所在的每一个 Office 应用程序注册自身。为了向特定应用程序注册其自身,加载项应使用其 ProgID 作为项名称在以下位置下创建一个子项:
HKEY_CURRENT_USER\Software\Microsoft\Office\OfficeApp\Addins\ProgID
加载项可以在此项的位置为好记的显示名称和完整的说明提供值。此外,加载项应使用一个名为 LoadBehavior 的 DWORD 值指定所希望的加载行为。此值确定宿主应用程序如何加载加载项,而且它由以下值的组合组成:
• | 0 = Disconnect — 未加载。 |
• | 1 = Connected — 已加载。 |
• | 2 = Bootload — 在应用程序启动时加载。 |
• | 8 = DemandLoad — 只在用户请求时加载。 |
• | 16 = ConnectFirstTime — 只加载一次(在下次启动时)。 |
通常指定 0x03 (Connected | Bootload) 这一典型的值。
实现了
IDTExtensibility2 的加载项还应指定一个名为 CommandLineSafe 的 DWORD 值,以指出加载项对于不支持用户界面的操作是否安全。值为 0x00 表示 False,值为 0x01 则表示 True。
回到顶端
使用 Visual Basic .NET 生成 COM 加载项
如上文所述,Office COM 加载项是由 Office 应用程序通过 COM 运行时层激活的进程内 COM 服务器。因此,为了在 Visual Basic .NET 中开发 COM 加载项,加载项组件需要在 .NET 中实现,然后通过 COM interop 层向 COM 客户端(即 Office 应用程序)公开。
要在 Visual Basic .NET 中创建 COM 加载项,请按照下列步骤操作:
1. | 在 Visual Basic .NET 中,创建一个类库项目。 |
2. | 添加一个对实现 IDTExtensibility2 的类型库的引用。此项的主 interop 程序集已经出现在 Extensibility 名称下。 |
3. | 添加一个对 Microsoft Office 对象库的引用。此项的主 interop 程序集已经出现在 Office 名称下。 |
4. | 在实现 IDTExtensibility2 的类库中创建一个公共类。 |
5. | 生成该类库之后,将该库向 COM interop 进行注册。为此,需为此类库生成一个使用强名称的程序集,然后将它注册到 COM interop。可以使用 Regasm.exe 来向 COM interop 注册 .NET 组件。 |
6. | 创建注册表条目以使 Office 应用程序可以识别并加载加载项。 |
您可以选择完成所有这些步骤,也可以创建类型为
共享的加载项的 NET 项目。这将启动“扩展向导”,该向导可帮助您在 .NET 中创建 COM 加载项。
“扩展向导”将创建一个 Visual Basic .NET 类库项目,同时创建一个实现
IDTExtensibility2 接口的
Connect 类。它还会生成实现
IDTExtensibility 的空成员的框架代码。此项目具有对 Extensibility 和 Office 程序集的引用。该项目的生成设置中已选中了
为 COM Interop 注册。将生成程序集密钥 (.snk) 文件,并在 Assemblyinfo.vb 文件的
AssemblyKeyfile 属性中进行引用。
除类库项目外,该向导还将生成一个安装项目,该项目可用于在其他计算机上部署 COM 加载项。在需要时可以删除此项目。
回到顶端
分步示例
1. | 在 Microsoft Visual Studio .NET 的文件菜单上,单击新建,然后单击项目。 |
2. | 在新建项目对话框中,展开项目类型下的其他项目,选择扩展性项目,然后选择共享的加载项模板。 |
3. | 键入 MyCOMAddin 作为该加载项的名称,然后单击确定。 |
4. | “扩展向导”出现后,请按照下列步骤操作:
a. | 在第 1 页,选择使用 Visual Basic 创建加载项,然后单击下一步。 | b. | 在第 2 页,选择下面的宿主应用程序,然后单击下一步:
• | Microsoft Word | • | Microsoft PowerPoint | • | Microsoft Outlook | • | Microsoft Excel | • | Microsoft Access |
| c. | 在第 3 页上,输入该加载项的名称和说明,然后单击下一步。
注意:该加载项的名称和说明出现在 Office 应用程序的 COM 加载项对话框中。
| d. | 在第 4 页,选择所有可用的选项,然后单击下一步。 | e. | 单击完成。 |
|
5. | 将以下成员添加到 Connect 类中: Dim WithEvents MyButton As CommandBarButton |
6. | 在 Connect 类中实现 IDTExtensibility2 的所有成员的代码,如下所示: Public Sub OnBeginShutdown(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnBeginShutdown
On Error Resume Next
' Notify the user you are shutting down, and delete the button.
MsgBox("Our custom Add-in is unloading.")
MyButton.Delete()
MyButton = Nothing
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
Dim oCommandBars As CommandBars
Dim oStandardBar As CommandBar
On Error Resume Next
' Set up a custom button on the "Standard" command bar.
oCommandBars = applicationObject.CommandBars
If oCommandBars Is Nothing Then
' Outlook has the CommandBars collection on the Explorer object.
oCommandBars = applicationObject.ActiveExplorer.CommandBars
End If
oStandardBar = oCommandBars.Item("Standard")
If oStandardBar Is Nothing Then
' Access names its main toolbar Database.
oStandardBar = oCommandBars.Item("Database")
End If
' In case the button was not deleted, use the exiting one.
MyButton = oStandardBar.Controls.Item("My Custom Button")
If MyButton Is Nothing Then
MyButton = oStandardBar.Controls.Add(1)
With MyButton
.Caption = "My Custom Button"
.Style = MsoButtonStyle.msoButtonCaption
' The following items are optional, but recommended.
' The Tag property lets you quickly find the control
' and helps MSO keep track of it when more than
' one application window is visible. The property is required
' by some Office applications and should be provided.
.Tag = "My Custom Button"
' The OnAction property is optional but recommended.
' It should be set to the ProgID of the add-in, so that if
' the add-in is not loaded when a user clicks the button,
' MSO loads the add-in automatically and then raises
' the Click event for the add-in to handle.
.OnAction = "!<MyCOMAddin.Connect>"
.Visible = True
End With
End If
' Display a simple message to show which application you started in.
MsgBox("Started in " & applicationObject.Name & ".")
oStandardBar = Nothing
oCommandBars = Nothing
End Sub
Public Sub OnDisconnection(ByVal RemoveMode As Extensibility.ext_DisconnectMode, ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnDisconnection
On Error Resume Next
If RemoveMode <> Extensibility.ext_DisconnectMode.ext_dm_HostShutdown Then _
Call OnBeginShutdown(custom)
applicationObject = Nothing
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
MsgBox("On Connection In MyAddin")
applicationObject = application
addInInstance = addInInst
' If you aren't in startup, manually call OnStartupComplete.
If (connectMode <> Extensibility.ext_ConnectMode.ext_cm_Startup) Then _
Call OnStartupComplete(custom)
End Sub
Private Sub MyButton_Click(ByVal Ctrl As Microsoft.Office.Core.CommandBarButton, ByRef CancelDefault As Boolean) Handles MyButton.Click
MsgBox("Our CommandBar button was pressed!")
End Sub
|
7. | 生成并测试 COM 加载项。为此,请按照下列步骤操作:
a. | 在生成菜单上,单击生成 MyCOMAddin。请注意,在生成 COM 加载项的过程中实际上就向 COM interop 注册了 .NET 类。 | b. | 启动一个您选作加载项的宿主应用程序的 Office 应用程序(如 Microsoft Word 或 Microsoft Excel)。 | c. | 加载项启动之后,将激发 OnConnection 事件,您会收到一个消息框。解除该消息框之后,会激发 OnStartupComplete 事件,您将收到第二个消息框。请解除该消息框。 | d. | 请注意,加载项向常用工具栏中添加了一个新的标题为“My Custom Button”(我的自定义按钮)的自定义按钮。 | e. | 单击 My Custom Button(我的自定义按钮)。该按钮的单击事件将由加载项来处理,而且您会收到一个消息框。请解除该消息框。 | f. | 退出该 Office 应用程序。 | g. | 退出应用程序时,将激发 OnBeginShutDown 事件,您会收到一个消息框。解除该消息框以结束演示。 |
|