编写的MSWord插件

简介
写发展办公室的COM加载项,在以前的文章后,我得到了很多人试图编写的Word加载项的邮件。通过本文,我们将讨论共同发展的问题,一般的Word加载项。首先,我们学习如何构建一个简单的Word 2000中的ATL COM插件。后来在文章中,我们将得到Word的VBA宏方面的事情,并写一个独立的COM插件支持所有版本的Word,的插件。
我假设你已经阅读我的办公室加载项前面的文章,并采取了在示例项目看。有很多的插件开发的问题,如添加自定义菜单/工具栏,处理事件,属性页等常见的所有Office加载项,其中包括Word。这些已经在这讨论。在这里,我们要编写一个Word 2000中的COM插件,首先。稍后,我们将深入到办公室和一般的VBA,并尊重与C的加载项,以。编写一个Word2000的加载项
首先,创建一个新的ATL COM应用程序向导生成的DLL项目,称为WordAddin。接下来插入一个ATL简单对象称为加载项,在以前的文章。接下来,使用ATL向导实现接口实施_IDTExtensibility2。 ,如你所知,这是在为所有Office应用程序的COM插件支持的心脏。下一步,针对Word程序,我们需要导入Word的类型库。这意味着,我们需要导入3个相互依存的typelibs。在项目的stdafx.h中添加下面的代码:/ / Office XP的/ / C:\ PROGRAM FILES \ \共同文件\ \微软共享\ \ Office10 \ \ MSO.DLL的#import"C:\ \ PROGRAM FILES \ \微软Office \ \办公室\ \ mso9.dllquot; rename_namespace("; Office2000quot";)使用命名空间OFFICE2000;#进口 "C:\ \ PROGRAM FILES \ \共同文件\ \微软共享\ \ VBA \ \ VBA6 \ \ VBE6EXT.olbquot; rename_namespace("; VBE6quot";)使用命名空间VBE6;
在项目的Addin.h文件中,朝上方,添加:/ /用于Office XP/ / C:\ \ PROGRAM FILES \ \ Micorosft办公室\ \ Office10 \ \ MSWORD.olb的#import"C:\ \ PROGRAM FILES \ \微软Office \ \办公室\ \ MSWORD9.olbquot; 重命名("; ExitWindowsquot","MyExitWindowsquot;),named_guids rename_namespace("; MSWordquot";)使用命名空间MSWORD;
确保您更改的路径指向您的系统文件的正确位置。
#import语句的不同位置,编译器需要承认一切,产生正确的包装,并编译和链接正确。动,Word2000中登记您的插件,添加下面的代码来加载项RGS注册表脚本文件(在FileView - GT;资源文件)。以下内容添加到文件的末尾。 HKCU{ 软件 { 微软 { 办公室 0; { 字 {& #160; 加载项 0;{ "WordAddin.Addin"   ; { VAL的FriendlyName = S'字自定义加载项" 60; VAL说明= S'字自定义加载项" VAL LoadBehavior = D '00000003' 0;VAL CommandLineSafe = D '00000001' & #160; } } &# 160; } } } }}
是的,我们希望我们的插件被称为"一词自定义加载项"("我爱CodeProject.com加载项",已经太明目张胆!),并启动Word时加载。那么还有什么是新的? :)
如果一切顺利的权利,你现在有一个工作的Word插件,你应该添加自己的实现代码。现在你已经知道如何添加按钮和菜单项,在你的插件,属性表等,已在前面的文章中讨论成立。唯一不同的Word对象模型,并在Outlook插件的例子的代码,是有没有在Word ActiveExplorer对象,你应该得到的CommandBars直接从应用程序界面,对象模型的最顶层。处理事件
可能在你的插件,你也可以在兴趣点在处理一些Word的events.A情况下的应用程序对象DocumentOpen事件的DISPID = 4,这是在这里处理。 Word有一个复杂的对象模型,你会发现其他类似事件。如果您使用好老OLE / COM对象查看器来查看MSWORD9.OLB,你会发现的IDL这样的:... ...   ; [ID(0x00000003),helpcontext(0x00061a83)] 无效DocumentChange(); [ID(0x00000004),helpcontext(0x00061a84)]& #160; 无效DocumentOpen([]文件*文件); ......
,像以前一样,我们将使用ATL的IDispEventSimpleImpllt; GT;模板类来实现我们的接收器。为了简单起见,只有必要的变化,在前面的代码已经mentioned.extern _ATL_FUNC_INFO DocumentOpenInfo;类ATL_NO_VTABLE CAddin: 公共CComObjectRootEx 公共CComCoClass 公共ISupportErrorInfo 公共IDispatchImpl 公共IDispatchImpllt; _IDTExtensibility2,放大器; IID__IDTExtensibility2 放大器; LIBID_AddInDesignerObjectsgt; 公共IDispEventSimpleImpllt; 1,CAddin 放大器; __uuidof(MSWORD::ApplicationEvents2)GT;{市民:........无效__stdcall的DocumentOpen(IDispatchPtr PTR){ CComQIPtrlt; _Documentgt; spDoc(PTR); 0; ATLASSERT(spDoc); .... ....}BEGIN_SINK_MAP(CAddin)SINK_ENTRY_INFO(1,__uuidof(MSWORD::ApplicationEvents2),4, DocumentOpen,放大器; DocumentOpenInfo)END_SINK_MAP()私人:CComPtrlt; MSWORD:_Applicationgt; m_spApp;};
DocumentOpenInfo _ATL_FUNC_INFO DocumentOpenInfo = {CC_STDCALL,VT_EMPTY,1,是指在CAddin.cpp顶部 {VT_DISPATCH | VT_BYREF}};
,仍然为我们做的是添加代码设置和打破连接。使用ATL模板类,因此我们要做的是调用DispEventAdvise()和DispEventUnadvise()。我们CAddin的OnConnection()和OnDisconnection(),不用说,也是这样做this.CComQIPtrlt的正确的地方; _Applicationgt; spApp(应用程序);ATLASSERT(spApp);m_spApp = spApp;HRESULT HR = DispEventAdvise(m_spApp);(FAILED(HR))返回人力资源;
OnDisconnection(),DispEventUnadvise(m_spApp);m_spApp = NULL;
现在你有一个工作的Word COM加载项模板,自豪地在你的腰带。对此,你应该添加自己的实现,错误处理例程等移动到不同的东西,让我们探索VBA字边。接下来,我将讨论一个非常具体的的情况我在我的插件混合使用C代码和VBA宏。宏和Visual Basic编辑器
我工作的一个项目,其中COM插件模型的东西适合我们的罚款。除客户有大量的WORD97用户,WORD97有没有为COM加载项的支持,特别是IDTExtensibility2接口。基本上在我的插件,我需要添加一些自定义的菜单项和按钮,点击它通常意味着显示的对话框。现在,一个COM插件将Word2000的用户的理想选择。但有一些方法,我们可以使插件WORD97兼容?
这导致我们的Visual Basic应用程序(VBA)。大多数Office开发人员都知道,MS Office的组件和应用程序支持丰富的脚本对象模型和VBA中已知的一个脚本接口。 Office版本4之前,每个套件中的应用是非常明显的。对于开发商而言,是不容易的创建使用多个Office应用程序的集成解决方案,因为每个应用程序有一个独特的编程环境。
通过微软的Visual Basic应用程序(VBA),这使得它的首次亮相在Office 95 - 在几个应用程序,虽然解决这个问题。 OFFICE97,套件中的每一个应用程序支持标准的VBA接口。一个VBA程序或宏,可以用它来控制其宿主应用程序的功能是相同的功能集,OLE自动化客户端可以使用外部控制应用程序,无论控制器的编程语言。 Word 97中包括Visual Basic中,一个复杂的开发环境,在Office应用程序共享5.0:字,EXCEL,POWERPOINT,并访问。
在Word中,VBA和Visual Basic中超越仅仅是一个宏languageit是一个全功能的的编程开发环境。在Visual Basic编辑器(VBE)使用熟悉的Microsoft Visual Basic 4.0编程接口,一个用于创建和编辑脚本代码的基础。通过VBA,Word将支持一切从宏文档模板的加载项。那么,什么是文档模板?一个文档模板(*. dot)是一个简单的宏代码(脚本)文件嵌入。在Word中,宏都坚持在Visual Basic模块的文件和模板。虽然宏通常存储在用户的默认模板Normal.dot,Word允许你储存和使用中的任何文档或模板的宏。此外,Office安装的启动文件夹中的任何文档模板等,将autorun.Additional模板和宏可以使用模板放大器加载的加载项或在"工具"菜单上的"宏"对话框。宏和文档模板(也为WordPerfect支持),也可以在一个工作组用户之间共享。
也很有意思的是,MS WORD97起还支持一组,获得与宿主应用程序调用的全局宏。 AUTOEXEC(),AutoNew()的AutoOpen(),AutoClose()和AutoExit()等这些AutoXXX宏被执行与宿主应用程序,就像他们的名字建议。这听起来最有用的,它是。 
如何?如果我们要创建一个文档模板,处理等自动宏,然后创建和销毁我们的插件(这是作为一个ActiveX服务器编写)通过VBA宏 - 那么我们应该在家里舒展。这是什么了IDTExtensibility2的COM加载项 - 主要的方式连接和断开的最顶层的应用程序对象。那么如何才能代替我们在WORD97插件这样呢?通过文档模板。自己的文档模板,可以形容的VBA加载项。每个文档模板设置通过的ThisDocument属性与项目相关的Document对象交互。我们还必须记住,所有宏隐式引用Application对象。
回到手头的任务,假设我们写一个文档模板中,添加代码ourAutoExec()和AutoExit()处理。在处理程序中,我们创建和释放我们的插件COM类对象,并随后调用它的方法。此外,我们的ATL COM类应实施两种方法中,init()和UNINIT(),通过它的应用对象是在C插件设置。我们的宏应该看起来像这样:DIM应用ØDIM为对象OBJAUTOEXEC()设为OBJ = CREATEOBJECT("Word97Addin.Addinquot;)设置Ø = ThisDocument.Applicationobj.Init ØEND SUB小组的autoExit()设置Ø = ThisDocument.Application obj.Uninit Ø设置OBJ =没有设置Ø =没有END SUB
我们可以选择自动加载和卸载的模板放置在办公室的启动folder.Similarly可以处理AutoClose(),AutoNew()和AutoOpen()宏,更相关文件。的时刻,因为我在我的C COM对象处理所有按钮/菜单的创建和活动,沟通是单向的(即宏观GT;插件),但双向沟通是不是太difficult.Suppose你必须在定义一个宏您的模板被称为"NewMacro";从C插件触发这个宏的途径之一是通过应用:run()或应用::RunOld(),这取决于你是否需要传递任何参数。有趣的是,你还可以通过点击一个按钮触发的宏,设置CommandBarButton对象的按钮或菜单项的OnAction属性/ /获取CommandBarButton的接口,所以我们可以指定按钮样式。CComQIPtr LT;办公室:CommandBarButtongt; spCmdButton(spNewBar);ATLASSERT(spCmdButton);spCmdButton - GT; PutCaption(_T("; Buttonquo​​t";));spCmdButton - GT; put_OnAction(OLESTR("NewMacroquot;));/ /设置按钮的属性spCmdButton - GT; PutVisible(VARIANT_TRUE);
这正是我为我的项目没有。我们有一个单一的解决方案,包括一个DLL和一个点文件,跨所有版本的Word运行 - 从97到XP,揭露和封装,大部分通过编译的C代码functionilty。不幸的是,这个VBA的支持带来了安全问题,并在以后的Office版本,如XP,用户可以决定在宏执行上下文的安全级别。虽然这是一个非问题,与我们您需要注意的。
我们学到迄今所有。一直信奉陪同VC + + 6.0通用外接程序项目,我将简要介绍未来。通用外接程序
通用外接程序是一个简单的ATL / COM应用程序向导生成的DLL项目,我插入一个ATL COM的IDispatch为基础的简单对象称为加载项。虽然名字听起来很造作,"普遍性",是指它的能力,跨所有版本的Word运行。
编写的MSWord插件_第1张图片
它适合这种普遍性是addin.dot Word文档模板,这是一个插件的一部分,它的AutoXXX宏。我们的外接程序类有两个成员的init()方法和UNINIT(),采取单一的IDispatch * Application对象。我们UNINIT()的实现很简单,我们可以没有IDispatchPtr参数,可能不适合你的implementation.In项目,我们通过插件添加一个按钮,点击触发一个VBA命名宏,反过来调用我们的COM类的方法。通过一切手段,你可以连接到CommandBarButtonEvents和编写C代码来处理按一下按钮,完成以前。
输出的目的是写一个字插件,绕过的COM插件架构和IDTExtensibility2.That结束,所有仍然对我说的是,无论使用VBA可以做,你可以从C,反之亦然 - 神奇的是在OLEAutomation。致谢
我知道Office开发的一切,我学会了在MSDN。你也可以找到一个囤积的技术文章和有关的一切,从Office开发COM和OLE自动化的短KB的代码片段。 MSDN规则 - 我们都知道。 :)

感谢彼得豪普特曼(又名Peterchen)为他的意见和建议。历史第一次修订 - 第14届,2003年4月。


http://www.orcode.com/article/COM_20114727.html

你可能感兴趣的:(编写的MSWord插件)