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
程序集的引用。该项目的生成设置中已选中了
注册 COM
interop。将生成程序集密钥 (.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
事件,您会收到一个消息框。请关闭该消息框。请注意,外接程序向标准工具栏中添加了一个新的标题为“My
Custom Button”(我的自定义按钮)的自定义按钮。 |
d. |
单击 My Custom
Button(我的自定义按钮)。该按钮的 Click
事件将由外接程序来处理,而且您会收到一个消息框。请关闭该消息框。 |
e. |
退出该 Office 应用程序。 |
f. |
退出该应用程序时,将激发 OnBeginShutDown
事件,您会收到一个消息框。关闭该消息框以结束演示。 |
|