Microsoft Office XP 和 Microsoft Office 2003都支持一种新的统一的设计结构,这种结构用于生成应用程序外接程序以增强和控制Office 应用程序。这些外接程序叫做 COM 外接程序。本文逐步讨论了Office COM 外接程序,并介绍了如何使用 Microsoft Visual C# .NET 生成Office COM 外接程序。
回到顶端
IDTExensibility2 接口
IDTExensibility2 接口。所有 COM外接程序都从此接口继承而来,而且都必须实现其五个方法中的每一个方法。
OnConnection
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
OnDisconnection事件。外接程序应在此事件中执行所有资源清理操作,并还原对宿主应用程序所做的任何更改。
OnDisconnection 使用下列两个参数:
" | RemoveMode —一个指定外接程序断开连接的方式的常量。外接程序可以采用下列方式断开连接:" | ext_dm_HostShutdown—外接程序在宿主应用程序关闭时断开连接。 | " | ext_dm_UserClosed —外接程序由最终用户或自动化控制器断开连接。 |
|
" | Custom — 一个包含 Variant类型值的数组,它可以存储用户定义的数据。 |
OnAddInsUpdate
OnAddInsUpdate 事件。换言之,每当安装 COM外接程序或者从宿主应用程序中删除 COM外接程序时,都会激发此事件。
OnStartupComplete 和 OnBeginShutdown
OnStartupComplete 和
OnBeginShutdown方法都是在宿主应用程序已离开或正要进入这一状态时被调用的。只有在启动期间已连接了外接程序的情况下才调用
OnStartupComplete,只有宿主在关闭过程中要断开与外接程序的连接的情况下才调用
OnBeginShutdown。
由于在激发这些事件时宿主应用程序的用户界面是完全活动的,因此它们可能是执行某些操作的唯一途径,以其他途径将无法从
OnConnection 和
OnDisconnection中执行这些操作。
回到顶端
COM外接程序注册
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 C# .NET 生成 COM 外接程序
要在 Visual C# .NET 中创建 COM 外接程序,请按照下列步骤操作:
1. | 在 Visual C# .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 C# .NET类库项目,同时创建一个实现了
IDTExtensibility2 接口的
Connect 类。它还会生成实现
IDTExtensibility的空成员的主干代码。此项目具有对 Extensibility 和 Office程序集的引用。该项目的生成设置中已选中了
注册 COMinterop。将生成程序集密钥 (.snk) 文件,并在 Assemblyinfo.vb文件的
AssemblyKeyfile 属性中进行引用。
除类库项目外,该向导还将生成一个安装项目,该项目可用于在其他计算机上部署COM 外接程序。在需要时可以删除此项目。
回到顶端
分步示例
1. | 在 Microsoft Visual Studio .NET的文件菜单上,单击新建,然后单击项目。 |
2. | 在新建项目对话框中,展开项目类型下的其他项目,选择扩展性项目,然后选择共享的外接程序模板。 |
3. | 键入 MyCOMAddin作为该外接程序的名称,然后单击确定。 |
4. | “扩展性向导”出现后,请按照下列步骤操作:a. | 在第 1 页,选择使用 Visual C#创建外接程序,然后单击下一步。 | b. | 在第 2页,选择下面的宿主应用程序,然后单击下一步:" | Microsoft Word | " | Microsoft PowerPoint | " | Microsoft Outlook | " | Microsoft Excel | " | Microsoft Access |
| c. | 在第 3页上,输入该外接程序的名称和描述,然后单击下一步。
注意:该外接程序的名称和描述出现在 Office 应用程序的 COM加载项对话框中。
| d. | 在第 4页,选择所有可用的选项,然后单击下一步。 | e. | 单击完成。 |
|
5. | 在项目菜单上,单击添加引用。单击组件列表中的System.Windows.Forms.DLL,单击选择,然后单击确定。 |
6. | 将下列代码添加到 Connect类中的名称空间列表中:using System.Reflection;
|
7. | 将下列成员添加到 Connect 类中:private CommandBarButton MyButton;
|
8. | 在 Connect 类中实现IDTExtensibility2 的成员的代码,如下所示:public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom) { applicationObject = application; addInInstance = addInInst; if(connectMode != Extensibility.ext_ConnectMode.ext_cm_Startup) { OnStartupComplete(ref custom); }}public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom) { if(disconnectMode != Extensibility.ext_DisconnectMode.ext_dm_HostShutdown) { OnBeginShutdown(ref custom); } applicationObject = null;}public void OnAddInsUpdate(ref System.Array custom){}public void OnStartupComplete(ref System.Array custom){ CommandBars oCommandBars; CommandBar oStandardBar; try { oCommandBars = (CommandBars)applicationObject.GetType().InvokeMember("CommandBars", BindingFlags.GetProperty , null, applicationObject ,null); } catch(Exception) { // Outlook has the CommandBars collection on the Explorer object. object oActiveExplorer; oActiveExplorer= applicationObject.GetType().InvokeMember("ActiveExplorer",BindingFlags.GetProperty,null,applicationObject,null); oCommandBars= (CommandBars)oActiveExplorer.GetType().InvokeMember("CommandBars",BindingFlags.GetProperty,null,oActiveExplorer,null); } // Set up a custom button on the "Standard" commandbar. try { oStandardBar = oCommandBars["Standard"]; } catch(Exception) { // Access names its main toolbar Database. oStandardBar = oCommandBars["Database"]; } // In case the button was not deleted, use the exiting one. try { MyButton = (CommandBarButton)oStandardBar.Controls["My Custom Button"]; } catch(Exception) { object omissing = System.Reflection.Missing.Value ; MyButton = (CommandBarButton) oStandardBar.Controls.Add(1, omissing , omissing , omissing , omissing); MyButton.Caption = "My Custom Button"; MyButton.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. MyButton.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 presses the button, //MSO loads the add-in automatically and then raises //the Click event for the add-in to handle. MyButton.OnAction = "!<MyCOMAddin.Connect>"; MyButton.Visible = true; MyButton.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.MyButton_Click); object oName = applicationObject.GetType().InvokeMember("Name",BindingFlags.GetProperty,null,applicationObject,null); // Display a simple message to show which application you started in. System.Windows.Forms.MessageBox.Show("This Addin is loaded by " + oName.ToString() , "MyCOMAddin"); oStandardBar = null; oCommandBars = null;}public void OnBeginShutdown(ref System.Array custom){ object omissing = System.Reflection.Missing.Value ; System.Windows.Forms.MessageBox.Show("MyCOMAddin Add-in is unloading."); MyButton.Delete(omissing); MyButton = null;}private void MyButton_Click(CommandBarButton cmdBarbutton,ref bool cancel) { System.Windows.Forms.MessageBox.Show("MyButton was Clicked","MyCOMAddin"); }
|
9. | 生成并测试该 COM外接程序。为此,请按照下列步骤操作:a. | 在生成菜单上,单击生成解决方案。请注意,生成 COM外接程序的过程中实际上就向 COM interop 注册了 .NET 类。 | b. | 启动一个您选作外接程序的宿主应用程序的 Office应用程序(例如,Microsoft Word 或 Microsoft Excel)。 | c. | 外接程序启动之后,将激发其OnStartupComplete事件,您会收到一个消息框。请关闭该消息框。请注意,外接程序向标准工具栏中添加了一个新的标题为“MyCustom Button”(我的自定义按钮)的自定义按钮。 | d. | 单击 My CustomButton(我的自定义按钮)。该按钮的 Click事件将由外接程序来处理,而且您会收到一个消息框。请关闭该消息框。 | e. | 退出该 Office 应用程序。 | f. | 退出该应用程序时,将激发 OnBeginShutDown事件,您会收到一个消息框。关闭该消息框以结束演示。 |
|