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