VC6编写Office插件

更新时间:2024-05-20 20:48:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

用VC6.0编写Word插件(Office2K、XP、03)

作者:hjphy 源代码下载

最近因为工作的需要,学习了一下Office插件的编写方法。在走了不少弯路以后,最后终于把编写插件的原理给搞清楚了,不敢独享,拿出来跟大家共享一下。下面就以Word 2003为例,向大家简单介绍一下。 第一步,利用向导生成一个ATL COM AppWizard的新工程。

图1

在向导的第一个对话框中,服务器类型选择Dynamic Link Library(DLL),然后单击Finish即可。

图2

然后,选取菜单Insert->New ATL Object项,在弹出的ATL对象向导对话框中选中相应Objects对应右侧的Simple Object选项,点击下一步。

图3

在弹出的对话框中ShortName中输入相应名称,点确定完成插入ATL对象。

图4

这样一个简单的基于ATL的COM组件工程就建立成功了。

第二步,通过导入类型库来实现_IDTExtensibility2接口。在ClassView中的新加的类上点鼠标右键,在弹出的右键菜单中选Implement Interface项。

图5

在弹出的实现接口对话框中点击Add Typelib

图6

在弹出的Browse Type Libraries对话框中,选取Microsoft Add-in Designer(1.0)子项,点OK按钮

图7

在弹出的接口列表对话框中选中_IDTExtensibility2接口,点OK按钮完成导入

这样的话,系统将会自动为你生成空的五个所需接口函数,分别是OnConnection、OnDisconnection、OnAddInsUpdate、OnStartupComplete、OnBeginShutdown。

第三步,通过上面的两个步骤,我们的插件框架已经形成,但是Office怎么知道启动的时候要来把我们的插件Load起来呢?Office的不同组件,例如Word、Excel、Outlook等怎么知道去Load自己的插件呢?答案就是在注册表中加入相应的键值。打开文件视图FileView—>Resource File中的rgs文件,加入以下代码: HKCU {

Software {

Microsoft { Office { Word { Addins {

''TestAddin.SimAddin'' {

val FriendlyName = s ''WORD Custom Addin'' val Description = s ''Word Custom Addin'' val LoadBehavior = d ''00000003'' val CommandLineSafe = d ''00000001'' } } }

} } } }

以上代码由三个需要注意的地方:

1. Office下面的那个子项代表了这个插件是属于那个组件,Word

、Excel、Outlook等等。 2. Addins下面的那个子项要写成你添加的COM组件的名字,千万不要照着我的工程的名字照抄。 3. 所有的值两边加的都是单引号,而且要用英文下的单引号,不能用双引号。

这样一个Office插件的框架才算完成,你可以在OnConnection函数中加一些测试代码,看看有没有执行到,如果执行成功才能继续,否则检查上面的步骤有没有错误。

第四步,同时需要import两个office的文件,一个是MSO.dll,另一个是MSWORD.OLB。这两个文件可以在以下位置找到(具体位置与office安装路径有关):

C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE11 C:\\Program Files\\Microsoft Office\\OFFICE11 然后在stdafx.h中加入如下语句:

#import \ \\

rename_namespace(%using namespace Office; #import

\

Files\\\\Common

Files\\\\Microsoft

Shared\\\\VBA\\\\VBA6\\\\VBE6EXT.olb\

rename_namespace(%using namespace VBE6; #import

\

Files\\\\Microsoft

Office\\\\OFFICE11\\\\MSWORD.OLB\

rename(\

#import \ \\

rename_namespace(%using namespace Word;

加完以上代码以后一定要编译一下,看看是否能够成功。引入这两个文件的原因,主要是为了引入一些变量类型,为后面的创建UI作准备。

最后一步,编写代码。在OnConnection加入如下代码: CComPtr < Office::_CommandBars> spCmdBars;

CComQIPtr spApp(Application); ATLASSERT(spApp);

HRESULT hr = spApp->get_CommandBars(&spCmdBars); if(FAILED(hr)) return hr;

ATLASSERT(spCmdBars);

CComVariant vName(\

CComPtr spNewCmdBar; CComVariant vPos(1);

CComVariant vTemp(VARIANT_TRUE);

CComVariant vEmpty(DISP_E_PARAMNOTFOUND, VT_ERROR); spNewCmdBar = spCmdBars->Add(vName, vPos, vEmpty, vTemp);

CComPtr < Office::CommandBarControls> spBarControls; spBarControls = spNewCmdBar->GetControls(); ATLASSERT(spBarControls);

CComVariant vToolBarType(1); CComVariant vShow(VARIANT_TRUE);

CComPtr < Office::CommandBarControl> spNewBar;

spNewBar = spBarControls->Add(vToolBarType, vEmpty, vEmpty, vEmpty, vShow); ATLASSERT(spNewBar);

CComQIPtr < Office::_CommandBarButton> spCmdButton(spNewBar); ATLASSERT(spCmdButton);

HBITMAP hBmp =(HBITMAP)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_BITMAP),IMAGE_BITMAP,0,0,LR_LOADMAP3DCOLORS);

::OpenClipboard(NULL); ::EmptyClipboard();

::SetClipboardData(CF_BITMAP, (HANDLE)hBmp); ::CloseClipboard(); ::DeleteObject(hBmp);

spCmdButton->PutStyle(Office::msoButtonIconAndCaption); hr = spCmdButton->PasteFace(); if (FAILED(hr)) return hr;

spCmdButton->PutVisible(VARIANT_TRUE); spCmdButton->PutCaption(OLESTR(\ spCmdButton->PutEnabled(VARIANT_TRUE);

spCmdButton->PutTooltipText(OLESTR(\ spCmdButton->PutTag(OLESTR(\ spNewCmdBar->PutVisible(VARIANT_TRUE);

m_spCmdButton = spCmdButton;

这样,再次打开word,就可以看到如图一所示的界面效果了。

图9

但是点击时没有响应,最后就让我们来解决这个问题。

1. 在COutlookAddin继承类中加入IDispEventSimpleImpl继承,代码如下: class ATL_NO_VTABLE COutlookAddin :

public CComObjectRootEx, ?? public

IDispEventSimpleImpl<1,COutlookAddin,&__uuidof(Office::_CommandBarButtonEvents)>

2. 声明_ATL_SINK_INFO结构回调参数信息。在OutlookAddin.h文件中加入下面语句: // 按钮事件响应信息声明

extern _ATL_FUNC_INFO OnClickButtonInfo; 在OutlookAddin.cpp文件中加入定义语句,如下: // 按钮事件响应信息定义

_ATL_FUNC_INFO OnClickButtonInfo ={CC_STDCALL,VT_EMPTY,2,{VT_DISPATCH,VT_BYREF | VT_BOOL}}; 3. 加入Sink映射,如下: EGIN_SINK_MAP(COutlookAddin)

SINK_ENTRY_INFO(1, __uuidof(Office::_CommandBarButtonEvents),/*dispid*/ 0x01, OnClickButton1, &OnClickButtonInfo)

SINK_ENTRY_INFO(2, __uuidof(Office::_CommandBarButtonEvents),/*dispid*/ 0x01, OnClickButton2, &OnClickButtonInfo)

SINK_ENTRY_INFO(3, __uuidof(Office::_CommandBarButtonEvents),/*dispid*/ 0x01, OnClickMenu, &OnClickButtonInfo) END_SINK_MAP()

4. 加入事件函数。在OutlookAddin.h中加入声明:

void __stdcall OnClickButton1(IDispatch * /*Office::_CommandBarButton**/ Ctrl,VARIANT_BOOL * CancelDefault); 在OutlookAddin.cpp中加入实现: // 工具条按钮1点击事件响应函数

void __stdcall CWordAddin::OnClickButton1(IDispatch * { }

MessageBox(NULL, \

/*Office::_CommandBarButton**/ Ctrl,VARIANT_BOOL * CancelDefault)

5. 最后,打开或断开与接口的连接。方法如下

在OnConnection接口函数的最后部分,加入下面代码来打开连接: 在OnConnection接口函数的最后部分,加入下面代码来打开连接: CommandButton1Events::DispEventAdvise((IDispatch*)m_spButton); 在OnDisconnection接口函数中,加入下面代码来断开连接:

CommandButton1Events::DispEventUnadvise((IDispatch*)m_spButton);

综上所述,编写一个简单的office的插件,其实并不难,只要按照步骤一步一步进行,肯定能成功,如果大家在使用过程中有什么疑问,欢迎一起探讨。 相关链接:Office2000下内部COM插件的编程实现

最新评论 [发表评论] [文章投稿]

哈哈,终于发现了。用那个title一样的dll就可以。我靠一下! ( pjl110 发表于 2007-11-13 17:16:00)

我没有MSADDNDR.TLB文件,谁发一下给我啊!谢谢!

pjllovelihua@163.com ( pjl110 发表于 2007-11-13 16:53:00)

请问下,怎么将VC6.0与Delphi联系起来编程,我是想写一个程序,用Delphi做前台的按钮控制,而当点击了按钮时能通过Delphi连接到VC上,用VC做后台控制,请问该怎么做啊????????????????

谢谢!! ( dreamf 发表于 2007-9-24 15:04:00)

你好,我是按你的操作进行的,怎么编译StdAfx.h中加入如下语句:

#import \ \\

rename_namespace(%using namespace Office;

#import \amespace(%using namespace VBE6;

#import \itWindowsEx\

#import \ \\

rename_namespace(%using namespace Word; 后

查看所有评论 推荐给好友 打印

“cannot compile the file 'D:\\TestAddin\\StdAfx.h':no compile tool is associated with the file extension ”

可以帮我解决这个问题吗??谢谢!!!!!!!!!! ( dreamf 发表于 2007-9-24 14:57:00)

你好,我是按你的操作进行的,怎么编译StdAfx.h中加入如下语句:

#import \ \\

rename_namespace(%using namespace Office;

#import \amespace(%using namespace VBE6;

#import \itWindowsEx\

#import \ \\

rename_namespace(%using namespace Word; 后

“cannot compile the file 'D:\\TestAddin\\StdAfx.h':no compile tool is associated with the file extension ”

可以帮我解决这个问题吗??谢谢!!!!!!!!!! ( dreamf 发表于 2007-9-24 14:56:00)

您好!我想开发一个QQ的插件,不知道按你这个方法可不可以实现? ( linewei 发表于 2007-4-9 2:57:00)

我最近在写一个excel插件,道理跟上面的差不多,但是我遇到了一些困难,我想捕获鼠标消息,比如鼠标点击了一个单元格,那么单元格的数据立刻会被显示到另外的一个控件中,怎么才能对office中的鼠标消息编写响应函数。上面的例子捕获的是WM_COMMAND消息 ( eyesmart 发表于 2007-4-6 17:02:00)

vc vb dll 控件学习网( 源码 ) http://konny520.diy.myrice.com

vc vb dll 控件学习网( 源码 )

http://konny520.diy.myrice.com ( konny 发表于 2007-3-5 15:58:00)

一个菜鸟问题:请问ATL这些编程方法在哪里可以找到,比如我们怎么就知道要去实现某一个接口的? ( w_xbei 发表于 2007-2-27 14:17:00)

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

作者:useresu 下载源代码 摘要

本文介绍了一种使用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 \ rename_namespace(%using namespace Office;

#import \ rename_namespace(%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 spCmdBars; CComPtr spCmdBar; hr = m_spApp->get_CommandBars(&spCmdBars);

if(FAILED(hr)) return hr;

ATLASSERT(spCmdBars);

// now we add a new toolband to Word // to which we''ll add 2 buttons CComVariant vName(\ 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 toolband''s CommandBarControls

CComPtr < Office::CommandBarControls> spBarControls; spBarControls = spNewCmdBar->GetControls(); ATLASSERT(spBarControls);

//MsoControlType::msoControlButton = 1 CComVariant vToolBarType(1);

//show the toolbar?

CComVariant vShow(VARIANT_TRUE);

CComPtr spNewBar; CComPtr spNewBar2;

// add first button

spNewBar = spBarControls->Add(vToolBarType,vEmpty,vEmpty,vEmpty,vShow); ATLASSERT(spNewBar);

// add 2nd button

spNewBar2 = spBarControls->Add(vToolBarType,vEmpty,vEmpty,vEmpty,vShow); ATLASSERT(spNewBar2);

_bstr_t bstrNewCaption(OLESTR(\

_bstr_t bstrTipText(OLESTR(\

// get CommandBarButton interface for each toolbar button // so we can specify button styles and stuff

// each button displays a bitmap and caption next to it CComQIPtr < Office::_CommandBarButton> spCmdButton(spNewBar); CComQIPtr < Office::_CommandBarButton> spCmdButton2(spNewBar2);

ATLASSERT(spCmdButton); m_spButton = spCmdButton; ATLASSERT(spCmdButton2);

// to set a bitmap to a button, load a 32x32 bitmap

// and copy it to clipboard. Call CommandBarButton''s PasteFace() // to copy the bitmap to the button face. to use

// Word''s set of predefined bitmap, set button''s FaceId to //the // button whose bitmap you want to use

HBITMAP hBmp =(HBITMAP)::LoadImage(_Module.GetResourceInstance(),

MAKEINTRESOURCE(IDB_BITMAP1),IMAGE_BITMAP,0,0,LR_LOADMAP3DCOLORS);

// put bitmap into Clipboard ::OpenClipboard(NULL); ::EmptyClipboard();

::SetClipboardData(CF_BITMAP, (HANDLE)hBmp); ::CloseClipboard();

::DeleteObject(hBmp);

// set style before setting bitmap

spCmdButton->PutStyle(Office::msoButtonIconAndCaption); hr = spCmdButton->PasteFace(); if (FAILED(hr)) return hr;

spCmdButton->PutVisible(VARIANT_TRUE); spCmdButton->PutCaption(OLESTR(\ spCmdButton->PutEnabled(VARIANT_TRUE);

spCmdButton->PutTooltipText(OLESTR(\ spCmdButton->PutTag(OLESTR(\ spCmdButton2->put_OnAction(OLESTR(\

//show the toolband

spNewCmdBar->PutVisible(VARIANT_TRUE);

spCmdButton2->PutStyle(Office::msoButtonIconAndCaption);

//specify predefined bitmap spCmdButton2->PutFaceId(1758);

spCmdButton2->PutVisible(VARIANT_TRUE); spCmdButton2->PutCaption(OLESTR(\ spCmdButton2->PutEnabled(VARIANT_TRUE);

spCmdButton2->PutTooltipText(OLESTR(\ spCmdButton2->PutTag(OLESTR(\ spCmdButton2->PutVisible(VARIANT_TRUE);

spCmdButton2->put_OnAction(OLESTR(\添加菜单项的过程与之相类似:

首先通过调用CommandBars集合的get_ActiveMenuBar()方法得到一个CommandBar对象,这个对象代表当前的工程中的活动菜单,然后调用CommandBar的GetControls得到当前菜单的控件集合。尝试在Word的“格式”菜单(第5个菜单)中加入新的菜单项,调用CommandBarControls的GetItem(5)得到需要的“格式”菜单项,它也是一个CommandBarControls集合,(前面曾经提到,控件集是可以嵌套的),这样就可以通过调用它的Add方法添加新的菜单项了。具体的实现代码如下: _bstr_t bstrNewMenuText(OLESTR(\ CComPtr < Office::CommandBarControls> spCmdCtrls;

CComPtr < Office::CommandBarControls> spCmdBarCtrls; CComPtr < Office::CommandBarPopup> spCmdPopup; CComPtr < Office::CommandBarControl> spCmdCtrl;

// get CommandBar that is Word''s main menu hr = spCmdBars->get_ActiveMenuBar(&spCmdBar); if (FAILED(hr)) return hr;

// get menu as CommandBarControls spCmdCtrls = spCmdBar->GetControls(); ATLASSERT(spCmdCtrls);

// we want to add a menu entry to Outlook''s 6th(Tools) menu //item CComVariant vItem(5);

spCmdCtrl= spCmdCtrls->GetItem(vItem); ATLASSERT(spCmdCtrl);

IDispatchPtr spDisp;

spDisp = spCmdCtrl->GetControl();

// a CommandBarPopup interface is the actual menu item CComQIPtr < Office::CommandBarPopup> ppCmdPopup(spDisp); ATLASSERT(ppCmdPopup);

spCmdBarCtrls = ppCmdPopup->GetControls(); ATLASSERT(spCmdBarCtrls);

CComVariant vMenuType(1); // type of control - menu CComVariant vMenuPos(6);

CComVariant vMenuEmpty(DISP_E_PARAMNOTFOUND, VT_ERROR); CComVariant vMenuShow(VARIANT_TRUE); // menu should be visible CComVariant vMenuTemp(VARIANT_TRUE); // menu is temporary

CComPtr < Office::CommandBarControl> spNewMenu;

// now create the actual menu item and add it

spNewMenu = spCmdBarCtrls->Add(vMenuType, vMenuEmpty, vMenuEmpty, vMenuEmpty, vMenuTemp); ATLASSERT(spNewMenu);

spNewMenu->PutCaption(bstrNewMenuText); spNewMenu->PutEnabled(VARIANT_TRUE); spNewMenu->PutVisible(VARIANT_TRUE);

//we''d like our new menu item to look cool and display

// an icon. Get menu item as a CommandBarButton

CComQIPtr < Office::_CommandBarButton> spCmdMenuButton(spNewMenu); ATLASSERT(spCmdMenuButton);

spCmdMenuButton->PutStyle(Office::msoButtonIconAndCaption);

// we want to use the same toolbar bitmap for menuitem too. // we grab the CommandBarButton interface so we can add // a bitmap to it through PasteFace(). spCmdMenuButton->PasteFace();

// show the menu

spNewMenu->PutVisible(VARIANT_TRUE);

return S_OK;

这时运行程序,可以看到添加的按钮和菜单项已经出现在Word中,还需要为其加入响应事件,这样才能真正的通过插件扩展Word的功能。

8、为我刚加入的按钮加入其响应事件:

ATL为COM对象的Idispatch接口提供了两个模板类:IDispEventImpl<>和IDispEventSimpleImpl<>,选择IDispEventSimpleImpl<>,因为它不需要额外的类型库信息,从IDispEventSimpleImpl<>继承一个类: class ATL_NO_VTABLE CAddin :

public CComObjectRootEx < CComSingleThreadModel>, .....

public IDispEventSimpleImpl<1,CAddin,

&__uuidof(Office::_CommandBarButtonEvents> 声明按钮点击事件的回调函数:

void __stdcall OnClickButton(Idispatch * /*Office::_CommandBarButton**/ Ctrl, VARIANT_BOOL * CancelDefault);

用_ATL_SINK_INFO结构描述回调的参数信息:打开CAddin.h文件,在其最上加入以下声明: extern _ATL_FUNC_INFO OnClickButtonInfo;(注意一定声明为外部变量) 然后打开CAddin.cpp文件为其加入以下定义: _ATL_FUNC_INFO OnClickButtonInfo =

{CC_STDCALL,VT_EMPTY,2,{VT_DISPATCH,VT_BYREF | VT_BOOL}}; 加入按钮点击事件的具体实现:

void __stdcall CAddin::OnClickButton(IDispatch*

/*Office::_CommandBarButton* */ Ctrl, VARIANT_BOOL * CancelDefault) {

USES_CONVERSION;

CComQIPtr pCommandBarButton(Ctrl);

//the button that raised the event. Do something with this... MessageBox(NULL, \

}

在接口映射宏中加入以下信息: BEGIN_SINK_MAP(CAddin)

SINK_ENTRY_INFO(1, __uuidof(Office::_CommandBarButtonEvents), /*dispid*/ 0x01,

OnClickButton, &OnClickButtonInfo) END_SINK_MAP()

最后在分别在CAddin 类的 OnConnection() 和OnDisconnection()中调用DispEventAdvise() 和 DispEventUnadvise()连接和断开连接消息来源。

到这里就实现了一个简单的COM插件,运行程序,点击工具栏上新加入的按钮,就可以弹出(\Button1\)消息框。

如果熟悉VBA编程,就可以把编写的宏作为按钮响应事件,只需调用按钮的put_OnAction()方法: spCmdButton->put_OnAction(OLESTR(\

本文对ATL并没有做深入的探讨,如果想了解ATL的知识,请参考:《ATL Internals》。

用VC6.0编写Word插件(Office2007篇)

作者:hjphy 下载源代码

简介

微软在06年底推出了两个重量级的产品:Vista和Office 2007。在Office2007中使用了新的UI方式。微软大力鼓吹这种叫做Ribbon的新的UI将会给使用Office的人带来更大的便利性。在Office插件方面,微软保持了对原有版本 (office 2K、XP、03) 的兼容性,都被放到一个叫做Add-In的Tab里面,如下图所示。

不过样子比较难看,到底有没有办法让界面做得更漂亮一点呢?答案是肯定的。本文假设读者已经阅读并理解了我的上一篇文章:

“用VC6.0编写Word插件(Office2K、XP、03)”

首先,引入新的Office的几个库文件,如果你的电脑安装了Office 2007,那么下面几个文件就会存在你的硬盘里面。

然后,原来的那个WordAddin需要继承一个名叫IRibbonExtensibility新的接口,并实现这个接口必须的函数raw_GetCustomUI。

然后,原来的那个WordAddin需要继承一个名叫IRibbonExtensibility新的接口,并实现这个接口必须的函数raw_GetCustomUI。

实现上边这个函数的目的是,因为Office2007在启动的时候就会询问插件的IRibbonExtensibility接口是否存在,如果该接口存在的话,就会调用这个接口的函数raw_GetCustomUI,在这个函数里面,我们必须把我们的UI通过XML的方式传给Office 2007,这样,在XML里面,我们可以自己定义我们需要的UI形式,样式非常丰富多彩,只有想不到,没有做不到。以下是一个简单的XML的例子:

Top