Office2000(2003) 下 outlook,word 的 com addin 之 delphi实现!(整理摸索)

本文介绍了使用Delphi开发Office2000内部COM插件的方法。阐述了COM插件需实现的_IDTExtensibility2接口及相关接口函数,说明了注册插件所需的注册表键值。详细说明了制作过程,包括新建项目、创建COM对象、编写代码、完成类定义、编译注册等步骤,最后运行查看效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       在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时,为用户控制激活装载。

com加载

下面,我给大家详细说明制作过程:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值