Microsoft Office XP 和 Microsoft Office 2003
都支持一種新的統(tǒng)一的設(shè)計(jì)結(jié)構(gòu),這種結(jié)構(gòu)用于生成應(yīng)用程序外接程序以增強(qiáng)和控制
Office 應(yīng)用程序。這些外接程序叫做 COM 外接程序。本文逐步討論了
Office COM 外接程序,并介紹了如何使用 Microsoft Visual C# .NET 生成
Office COM 外接程序。
回到頂端
IDTExensibility2 接口
IDTExensibility2 接口。所有 COM
外接程序都從此接口繼承而來,而且都必須實(shí)現(xiàn)其五個(gè)方法中的每一個(gè)方法。
OnConnection
OnConnection
事件。外接程序可以在啟動時(shí)連接、由最終用戶連接或者通過自動化來連接。如果
OnConnection
成功地返回,就表明已加載了外接程序。如果返回錯(cuò)誤消息,那么宿主應(yīng)用程序就立即釋放其對該外接程序的引用,而且該對象將被銷毀。
OnConnection 使用下列四個(gè)參數(shù):
| " |
Application —
一個(gè)對宿主應(yīng)用程序?qū)ο蟮囊谩?/td>
|
| " |
ConnectMode —
一個(gè)指定外接程序連接方式的常量。外接程序可以采取下列幾種方式連接:
| " |
ext_cm_AfterStartup — 外接程序由最終用戶從
COM 外接程序 對話框啟動。 |
| " |
ext_cm_CommandLine —
外接程序從命令行連接。注意,此方式不適用于生成 Office 應(yīng)用程序的
COM 外接程序。 |
| " |
ext_cm_External —
外接程序由外部應(yīng)用程序通過自動化連接。請注意,此方式不適用于生成
Office 應(yīng)用程序的 COM 外接程序。 |
| " |
ext_cm_Startup —
外接程序由宿主在應(yīng)用程序啟動時(shí)啟動。此行為由注冊表中的設(shè)置來控制。 |
|
| " |
AddInInst — 一個(gè)對 COMAddIn
對象的引用,它引用宿主應(yīng)用程序的 COMAddIns
集合中的此外接程序。 |
| " |
Custom — 一個(gè)包含 Variant
類型值的數(shù)組,它可以存儲用戶定義的數(shù)據(jù)。 |
OnDisconnection
OnDisconnection
事件。外接程序應(yīng)在此事件中執(zhí)行所有資源清理操作,并還原對宿主應(yīng)用程序所做的任何更改。
OnDisconnection 使用下列兩個(gè)參數(shù):
| " |
RemoveMode —
一個(gè)指定外接程序斷開連接的方式的常量。外接程序可以采用下列方式斷開連接:
| " |
ext_dm_HostShutdown
—外接程序在宿主應(yīng)用程序關(guān)閉時(shí)斷開連接。 |
| " |
ext_dm_UserClosed —
外接程序由最終用戶或自動化控制器斷開連接。 |
|
| " |
Custom — 一個(gè)包含 Variant
類型值的數(shù)組,它可以存儲用戶定義的數(shù)據(jù)。 |
OnAddInsUpdate
OnAddInsUpdate 事件。換言之,每當(dāng)安裝 COM
外接程序或者從宿主應(yīng)用程序中刪除 COM
外接程序時(shí),都會激發(fā)此事件。
OnStartupComplete 和 OnBeginShutdown
OnStartupComplete 和
OnBeginShutdown
方法都是在宿主應(yīng)用程序已離開或正要進(jìn)入這一狀態(tài)時(shí)被調(diào)用的。只有在啟動期間已連接了外接程序的情況下才調(diào)用
OnStartupComplete,只有宿主在關(guān)閉過程中要斷開與外接程序的連接的情況下才調(diào)用
OnBeginShutdown。
由于在激發(fā)這些事件時(shí)宿主應(yīng)用程序的用戶界面是完全活動的,因此它們可能是執(zhí)行某些操作的唯一途徑,以其他途徑將無法從
OnConnection 和
OnDisconnection
中執(zhí)行這些操作。
回到頂端
COM
外接程序注冊
HKEY_CURRENT_USER\Software\Microsoft\Office\OfficeApp\Addins\ProgID
外接程序可以在此項(xiàng)的位置為好記的顯示名稱和完整的說明提供值。此外,外接程序應(yīng)使用一個(gè)名為
LoadBehavior 的 DWORD
值指定所希望的加載行為。此值確定宿主應(yīng)用程序如何加載外接程序,而且它由下列值的組合組成:
| " |
0 = Disconnect — 未加載。 |
| " |
1 = Connected — 已加載。 |
| " |
2 = Bootload — 在應(yīng)用程序啟動時(shí)加載。 |
| " |
8 = DemandLoad — 只在由用戶請求時(shí)加載。 |
| " |
16 = ConnectFirstTime —
只加載一次(在下次啟動時(shí))。 |
通常指定 0x03 (Connected | Bootload) 這一典型的值。
實(shí)現(xiàn)了
IDTExtensibility2 的外接程序還應(yīng)指定一個(gè)名為
CommandLineSafe 的 DWORD
值,以指出外接程序?qū)τ诓恢С钟脩艚缑娴牟僮魇欠癜踩V禐?0x00 表示
False,值為 0x01 則表示 True。
回到頂端
如何使用
Visual C# .NET 生成 COM 外接程序
要在 Visual C# .NET 中創(chuàng)建 COM 外接程序,請按照下列步驟操作:
| 1. |
在 Visual C# .NET 中,創(chuàng)建一個(gè)類庫項(xiàng)目。 |
| 2. |
添加一個(gè)對實(shí)現(xiàn)了 IDTExtensibility2
的類型庫的引用。此項(xiàng)的主 interop 程序集已經(jīng)出現(xiàn)在
Extensibility 名稱下。 |
| 3. |
添加一個(gè)對 Microsoft Office 對象庫的引用。此項(xiàng)的主
interop 程序集已經(jīng)出現(xiàn)在 Office 名稱下。 |
| 4. |
在實(shí)現(xiàn)了 IDTExtensibility2
的類庫中創(chuàng)建一個(gè)公共類。 |
| 5. |
生成該類庫之后,將該庫向 COM interop
進(jìn)行注冊。為此,需要為此類庫生成一個(gè)使用強(qiáng)名稱的程序集,然后將它注冊到
COM interop。可以使用 Regasm.exe 來向 COM interop 注冊 .NET
組件。 |
| 6. |
創(chuàng)建注冊表?xiàng)l目以使 Office
應(yīng)用程序可以識別并加載外接程序。 |
您可以選擇完成所有這些步驟,或可以創(chuàng)建類型為
共享的外接程序
的 .NET 項(xiàng)目。這將啟動“擴(kuò)展性向?qū)А?,該向?qū)Э蓭椭?.NET 中創(chuàng)建
COM 外接程序。
“擴(kuò)展性向?qū)А睂?chuàng)建一個(gè) Visual C# .NET
類庫項(xiàng)目,同時(shí)創(chuàng)建一個(gè)實(shí)現(xiàn)了
IDTExtensibility2 接口的
Connect 類。它還會生成實(shí)現(xiàn)
IDTExtensibility
的空成員的主干代碼。此項(xiàng)目具有對 Extensibility 和 Office
程序集的引用。該項(xiàng)目的生成設(shè)置中已選中了
注冊 COM
interop。將生成程序集密鑰 (.snk) 文件,并在 Assemblyinfo.vb
文件的
AssemblyKeyfile 屬性中進(jìn)行引用。
除類庫項(xiàng)目外,該向?qū)н€將生成一個(gè)安裝項(xiàng)目,該項(xiàng)目可用于在其他計(jì)算機(jī)上部署
COM 外接程序。在需要時(shí)可以刪除此項(xiàng)目。
回到頂端
分步示例
| 1. |
在 Microsoft Visual Studio .NET
的文件菜單上,單擊新建,然后單擊項(xiàng)目。 |
| 2. |
在新建項(xiàng)目對話框中,展開項(xiàng)目類型下的其他項(xiàng)目,選擇擴(kuò)展性項(xiàng)目,然后選擇共享的外接程序模板。 |
| 3. |
鍵入 MyCOMAddin
作為該外接程序的名稱,然后單擊確定。 |
| 4. |
“擴(kuò)展性向?qū)А背霈F(xiàn)后,請按照下列步驟操作:
| a. |
在第 1 頁,選擇使用 Visual C#
創(chuàng)建外接程序,然后單擊下一步。 |
| b. |
在第 2
頁,選擇下面的宿主應(yīng)用程序,然后單擊下一步:
| " |
Microsoft Word |
| " |
Microsoft PowerPoint |
| " |
Microsoft Outlook |
| " |
Microsoft Excel |
| " |
Microsoft Access |
|
| c. |
在第 3
頁上,輸入該外接程序的名稱和描述,然后單擊下一步。
注意:該外接程序的名稱和描述出現(xiàn)在 Office 應(yīng)用程序的 COM
加載項(xiàng)對話框中。
|
| d. |
在第 4
頁,選擇所有可用的選項(xiàng),然后單擊下一步。 |
| e. |
單擊完成。 |
|
| 5. |
在項(xiàng)目菜單上,單擊添加引用。單擊組件列表中的
System.Windows.Forms.DLL,單擊選擇,然后單擊確定。 |
| 6. |
將下列代碼添加到 Connect
類中的名稱空間列表中:
using System.Reflection;
|
| 7. |
將下列成員添加到 Connect 類中:
private CommandBarButton MyButton;
|
| 8. |
在 Connect 類中實(shí)現(xiàn)
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
外接程序的過程中實(shí)際上就向 COM interop 注冊了 .NET 類。 |
| b. |
啟動一個(gè)您選作外接程序的宿主應(yīng)用程序的 Office
應(yīng)用程序(例如,Microsoft Word 或 Microsoft Excel)。 |
| c. |
外接程序啟動之后,將激發(fā)其
OnStartupComplete
事件,您會收到一個(gè)消息框。請關(guān)閉該消息框。請注意,外接程序向標(biāo)準(zhǔn)工具欄中添加了一個(gè)新的標(biāo)題為“My
Custom Button”(我的自定義按鈕)的自定義按鈕。 |
| d. |
單擊 My Custom
Button(我的自定義按鈕)。該按鈕的 Click
事件將由外接程序來處理,而且您會收到一個(gè)消息框。請關(guān)閉該消息框。 |
| e. |
退出該 Office 應(yīng)用程序。 |
| f. |
退出該應(yīng)用程序時(shí),將激發(fā) OnBeginShutDown
事件,您會收到一個(gè)消息框。關(guān)閉該消息框以結(jié)束演示。 |
|