|
在Office2000下的Word2000、Access2000、Excel2000、PowerPoint2000等软件中的工具条或菜单条资源中,看到一些其它软件加入的新的 自定义工具条按钮或菜单条,当点击它们时,会有其不同的响应发生。在这里我们不用VB/VBA也不用vc6来实现它,而是用delphi(5,6,7)适用开发具有这种效果的Office2000内部COM插件。在Office2000中,不管是Word2000、Access2000、Excel120000、PowerPoint2000还是Outlook2000等,它们COM插件的编程方法及步骤都是极其相似的(除注册表中键值及导入相应类型库不同外),具体的编程差别我会注明在程序中。 一个Office2000下的内部COM插件必须实现一个_IDTExtensibility2派发接口,_IDTExtensibility2派发接口被定义在MSADDin Designer类型库(MSADDNDR.dll/MSADDNDR.tlb)中,通常位于<盘符>/Program Files/Common Files/Designer下。_IDTExtensibility2接口中必须实现下面五个接口涵数(一般只需编写OnConnection和OnDisconnection中代码,并且delphi自动生成框架),分别如下: 1. OnConnection: 装载插件到内存时处理(可以通过自动化在程序启动时自动装载插件)。 2. OnDisconnection: 从内存中缷载插件时处理。 3. OnAddinsUpdate: COM插件改变时处理。 4. OnStartupComplete: 当应用程序启动时插件刚装载完成时处理。 5. OnBeginShutdown: 当应用程序关闭时插件刚缷载完成时处理。 只有在正确注册了相应应用程序的内部COM插件时,才能被其应用程序加载上,你会在outlook 或者 word等的工具-〉com加载项中看到注册了的com插件。需要在注册表中创建以下键值:HKEY_CURRENT_USER\Software\Microsoft\Office\<TheOfficeApp>\Addins\<ProgID> 其中,TheOfficeApp表示相应程序名,如:Word、Outlook等,ProgID表示内部COM插件程序的唯一标识符的字符串表示形式,如:project1.MyOutLookAddIn等。 ProgID键值下主要创建以下键值: 1. FriendlyName: 字符串类型,插件的名称,将在相应程序的COM加载对话框中看到。 2. LoadBehavior: 双字节类型,决定插件将以什么形式被装载。当其值为0x03时,为应用程序装载时被自动装载(一般使用此值)、当其值为0x08时,为用户控制激活装载。  下面,我给大家详细说明制作过程: 1,新建 active library,保存为 project1,这就是ProgID的前面部分 2,新建com Object,在Class Name中填写 MyOutLookAddIn,这将是ProgID的后面部分,点一下Implemented Interface后面的List按钮。再点一下对话框中的Add Library按钮,选择“Program Files\Common Files\Designer”目录下的msaddndr.dll文件。然后在列表中找到msaddndr.dll里面的_IDTExtensibility2接口点击确定。现在Com AddIn部分已经完成,现在要在outlook里面加一个CommandBar和两个按钮,并且让按钮响应用户自定义事件 3,创建一个新的Unit,主要新建一个TcommandBarButton的OleServer类以连接到CommandButton并响应事件,记得,一定要引用 office2000, outlook2000单元。代码:如下 定义部分 TCommandBarButtonClick = procedure(const Ctrl: OleVariant; var CancelDefault: OleVariant) of Object; TCommandBarButton = class(TOleServer) private FIntf: CommandBarButton; FOnClick: TCommandBarButtonClick; function GetDefaultInterface: CommandBarButton; procedure SetOnClick(const Value: TCommandBarButtonClick); protected procedure InitServerData; override; procedure InvokeEvent(DispID: TDispID; var Params: TVariantArray); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure Connect; override; procedure ConnectTo(svrIntf: CommandBarButton); procedure Disconnect; override; property DefaultInterface: CommandBarButton read GetDefaultInterface; published property OnClick : TCommandBarButtonClick read FOnClick write SetOnClick; end; //实施部分 { TCommandBarButton } procedure TCommandBarButton.Connect; var punk: IUnknown; begin if FIntf = nil then begin punk := GetServer; ConnectEvents(punk); Fintf:= punk as CommandBarButton; end; end; procedure TCommandBarButton.ConnectTo(svrIntf: CommandBarButton); begin Disconnect; FIntf := svrIntf; ConnectEvents(FIntf); end; constructor TCommandBarButton.Create(AOwner: TComponent); begin inherited; end; destructor TCommandBarButton.Destroy; begin inherited; end; procedure TCommandBarButton.Disconnect; begin if Fintf <> nil then begin DisconnectEvents(FIntf); FIntf := nil; end; end; function TCommandBarButton.GetDefaultInterface: CommandBarButton; begin if FIntf = nil then Connect; Assert(FIntf <> nil, 'DefaultInterface is NULL. Component is not connected to Server. You must call ''Connect'' or ''ConnectTo'' before this operation'); Result := FIntf; end; procedure TCommandBarButton.InitServerData; const CServerData: TServerData = ( ClassID: '{C45BDF5C-8430-4e26-97EF-B3624198366D}'; //随便3个GUID IntfIID: '{A30AF5AC-D1FD-486a-8C7E-F71416EAFC4B}'; EventIID: {24BDE880-D3DB-4777-A5D4-AD24E1E3FCBD}'; LicenseKey: nil; Version: 500); begin ServerData := @CServerData; end; procedure TCommandBarButton.InvokeEvent(DispID: TDispID; var Params: TVariantArray); begin case DispID of -1: Exit; // DISPID_UNKNOWN 1: if Assigned(FOnClick) then FOnClick(Params[0], Params[1]); end; {case DispID} end; procedure TCommandBarButton.SetOnClick( const Value: TCommandBarButtonClick); begin FOnClick := Value; end; 4, 继续完成TMyOutlookAddIn类 在类定义里面增加项 private FCommandBarButton : TCommandBarButton; FCommandBarButton2 : TCommandBarButton; procedure FClick(const Ctrl: OleVariant; var CancelDefault: OleVariant); procedure F2Click(const Ctrl: OleVariant; var CancelDefault: OleVariant); 在OnConnection写下面代码 procedure TMyOutLookAddIn.OnConnection(const Application: IDispatch; ConnectMode: ext_ConnectMode; const AddInInst: IDispatch; var custom: PSafeArray); //读取一个Bitmap并复制到粘贴板 procedure CopyBitMapToClipBoard(strFile : string); var aBitMap : TBitmap; begin with TClipboard.Create do begin try aBitMap := TBitmap.Create; aBitMap.LoadFromFile(strFile); Assign(aBitMap); finally aBitMap.Free; Free; end; end; end; var App : OutLookApplication; //word addin实现差别,定义 :wordApp: WordApplication aCommandBar : CommandBar; aButton,aButton2 : _CommandBarButton; begin App := OutLookApplication(Application); aCommandBar := App.ActiveExplorer.CommandBars.Add('NewButtonBar', msoBarTop, False, True); //button栏 //word addin实现差别 // App := WordApplication(Application); // aCommandBar := App.CommandBars.Add('SYNI', msoBarTop, False, True); //button栏 //第一个button aButton := aCommandBar.Controls.Add(msoControlButton, EmptyParam, EmptyParam, EmptyParam, True) as _CommandBarButton; aButton.Set_Style(msoButtonIconAndCaption); aButton.Set_Caption('SCP Manager'); CopyBitMapToClipBoard(YourBmpFile); //这两句话是给按钮设定一个外部图标, aButton.PasteFace; //你要增加一个bitmap资源bitmap大小为16*16 aButton.Set_Tag('Manger'); FCommandBarButton := TCommandBarButton.Create(nil); FCommandBarButton.ConnectTo(aButton);//button关联 FCommandBarButton.OnClick := FClick;//响应事件的赋值 //第二个button aButton2 := aCommandBar.Controls.Add(msoControlButton, EmptyParam, EmptyParam, EmptyParam, True) as _CommandBarButton; aButton2.Set_Style(msoButtonIconAndCaption); aButton2.Set_Caption('SCP History'); CopyBitMapToClipBoard(YourBmpFile2); //这两句话是给按钮设定一个外部图标, aButton2.PasteFace; // aButton2.Set_Tag('History'); // 必须与其他button不同 FCommandBarButton2 := TCommandBarButton.Create(nil); FCommandBarButton2.ConnectTo(aButton2); FCommandBarButton2.OnClick := F2Click; //响应事件2 aCommandBar.Set_Visible(True); end; 在OnDisconnection写下面代码 procedure TMyOutLookAddIn.OnDisconnection(RemoveMode: ext_DisconnectMode; var custom: PSafeArray); begin FCommandBarButton.Disconnect; FCommandBarButton.Free; FCommandBarButton2.Disconnect; FCommandBarButton2.Free; end; //写Click事件(弹出一个dialog) procedure TMyOutLookAddIn.FClick(const Ctrl: OleVariant; var CancelDefault: OleVariant); begin ShowMessage('激活Manager按钮click事件'); end; //写Click事件(执行一个程序) procedure TMyOutLookAddIn.F2Click(const Ctrl: OleVariant; var CancelDefault: OleVariant); begin ShellExecute(NIL,'open','YourExePragram',NIL,NIL,SW_SHOW); end; 5, 最后编译注册。得打开RegEdit,像前面提到的那样写注册表。可以把它导出来,以后用到别的机器上的时候,直接合并就可以了。 6,运行outlook2000或者2003,就可以看到效果。  参考文献: COM Add-ins : Building a COM Add-in for Outlook 2000 - (MSDN ,Thomas Rizzo) Office2000下内部COM插件的编程实现 (徐景周) 用Delphi制作Office的Com AddIn (cwxiao888) 需要代码的朋友,给你跟我联系, leyi.163@163.com
|