当前位置:编程学习 > VC++ >>

使用VC++ ATL实现Office的COM插件

本文介绍了一种使用VC++ ATL(Active Template Library),利用IDTExtensibility2接口,为Microsoft Word加入功能简单的COM插件(addin),加入工具栏按钮和菜单等可视部件,并为其加入响应事件的方法,并在最后简单说明了实现与Office宏混合编程的方法。

  说到Office相关的编程,大家首先想到的可能是VBA(Visual Basic for Application),事实上, ATL也是一种很好的工具。这里介绍的就是一种基于ATL的Office编程方法,实现的功能很简单,仅仅是一个示例,步骤如下:

  1、在visual C++编程环境下,利用向导生成一个名为WordAddin的ATL COM Appwizard工程:

  在向导的第一个对话框中server type单选框选择默认的服务器类型Dynamic Link Library(DLL),下面的三个复选框中选择Allow merging of proxy-stub code选项。然后单击Finish,这样一个空的ATL project就产生了(如图 一)。


图一

  2、插入我们的ATL object:

  选择菜单Insert—>Insert new ATL object,出现new ATL object向导对话框,左边的category列表中选择object,右边相应的选择simple object,单击下一步(Next)(如图 二):


图二
  在第二个对话框names属性页的“Short Name:”中填入Addin(如图三):


图三

  在Attribute属性页中,选中Support IsupportErrorInfo复选框,单击OK(如图四):


图四

  这样就产生了一个类名为WordAddin的ATL COM object,编译(build)该工程看是否一切正常。

  2、用IDTExtensibility2实现CAddin类:

   IDTExtensibility2是定义在MSADDin Designer typelibrary(MSADDNDR.dll/MSADDNDR.tlb)中的库文件,该文件一般在C:Program Files/Common Files/Designer目录下。IDTExtensibility2 库提供了 5 个可用来操纵插件以及宿主应用程序的事件: OnConnection、OnDisconnection、OnAddInsUpdate、OnStartupComplete 和 OnBeginShutdown。这些事件的具体功能和用法可查阅MSDN。用向导来实现IDTExtensibility2接口:切换到classview页,右键点击Caddin类,在弹出的菜单中选择Implement Interface,出现Implement Interface对话框,选择Add Tylpelib按钮(如图 五):


图五

  (单击OK,)在出现的Browse Typelibraries对话框中选择Microsoft Add-in Designer(1.0) (如图六):


图六

  单击OK,在AddinDesignerObjects属性页中选择IDTExtensibility2(如图七):


图七

  再单击OK。这样向导就在ATL COM object中添加了IDTExtensibility2的5个具体事件,并对他们进行了一些默认的初始设置,同时还更新了COM_INTERFACE_MAP()。
4、注册插件到它的宿主程序:

  打开文件视图FileView—>Resource File中的Addin.rgs文件,加入以下代码:

HKCU
{
 Software
 {
  Microsoft
  {
   Office
   {
    Word
    {
     Addins
     {
      WordAddin.Addin
      {
       val FriendlyName = s WORD Custom Addin
       val Description = s Word Custom Addin
       val LoadBehavior = d 00000003
       val CommandLineSafe = d 00000001
      }
     }
    }
   }
  }
 }
}

  5、重新编译(build)该工程注册我们的插件。

  6、运行,选择Executable File为word 2000,注意要选择正确的路径,如果运行成功,则插件已经加入到word中。

  7、给插件添加菜单和按钮:

  这里简单的介绍一下Office 的命令条:在Office中,菜单栏、工具栏和弹出式菜单都叫做命令条(Command Bar对象)。所有这些种类的命令条中都可以包括其他命令条和不限数量的控件,如相对工具栏这个命令条而言,按钮就是它的控件。有的控件(如菜单)本身又是命令条,可以多级嵌套。所有的命令条可用一个CommandBars集合控制。CommandBars集合是一个通用的可共享且可编程的对象,通过它的Add()方法可以为其添加一个CommandBar 对象(即命令条),而每个 CommandBar 对象都有一个CommandBarControls 集合,这个集合里包含了这个命令条里的所有控件。使用 CommandBar 对象的 Controls 属性可引用命令条中的控件。

  现在给word加入一个工具条及其按钮和一个菜单:

  首先在工程中加入office和Word的类型库,在stdafx.h文件中加入以下代码:

#import "C:Program FilesMicrosoft OfficeOfficemso9.dll"
rename_namespace("Office") named_guids
using namespace Office;

#import "C:Program FilesMicrosoft OfficeOfficeMSOUTL9.olb"
rename_namespace("Word"), raw_interfaces_only, named_guids
using namespace Outlook;

  注意:一定要把路径改为和office的安装路径一致。

  在Word对象模型中,Application对象是代表整个工程的最高级对象,我们可以用它的GetCommandBars方法得到CommandBars对象,由于CommandBars对象是Word所有工具条和菜单项的集合,所以就可以通过调用它的Add方法添加新的工具条。然后为工具条添加新的按钮,其实方法一样简单,我们可以调用CommandBar的GetControls方法得到工具条的CommandBarControls集合,如前所说,CommandBarControls集合是该工具条所有控件的集合,按钮自然是其中之一,那么接下来我们就可以通过调用CommandBarControls集合的Add方法添加一个新的按钮了。下面是具体的实现代码:

CComQIPtr<_Application> spApp(Application);

ATLASSERT(spApp);
m_spApp = spApp;
HRESULT hr = AppEvents::DispEventAdvise(m_spApp);

if(FAILED(hr))
 return hr;

CComPtr <Office::_CommandBars> spCmdBars;
CComPtr <Office::CommandBar> spCmdBar;
hr = m_spApp->get_CommandBars(&spCmdBars);

if(FAILED(hr))
 return hr;

ATLASSERT(spCmdBars);

// now we add a new toolband to Word
// to which well add 2 buttons
CComVariant vName("WordAddin");
CComPtr spNewCmdBar;

// position it below all toolbands
//MsoBarPosition::msoBarTop = 1
CComVariant vPos(1);
CComVariant vTemp(VARIANT_TRUE); // menu is temporary
CComVariant vEmpty(DISP_E_PARAMNOTFOUND, VT_ERROR);

//Add a new toolband through Add method
// vMenuTemp holds an unspecified parameter
//spNewCmdBar points to the newly created toolband
spNewCmdBar = spCmdBars->Add(vName, vPos, vEmpty, vTemp);

//now get the toolbands CommandBarControls
CComPtr < Office::CommandBarControls> spBarControls;
spBarControls = spNewCmdBar->GetControls();
ATLASSERT(spBarControls);

//MsoControlType::msoControlButton = 1
CComVariant vToolBarType(
补充:软件开发 , Vc ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,