用Delphi开发WpsOffice插件(三);(响应WPS的各种事件);WPSOffice的三大组件,为了方便二次开发,;一、WPS的事件接口;WPSOFFICE的事件是以接口的形式提供的,以;WPS_TLB.PAS中,有applicatio;['{000209FE-0000-4B30-A9;procedureStartup;dispid1;procedu
(响应WPS的各种事件)
WPS Office的三大组件,为了方便二次开发,都预留了事件接口,不同程序都有不同事件,通过响应不同事件,开发者可以开发出不同功能的插件程序。今天我们就一起来学习一下怎样响应WPS的各种事件,示例以WPS文字为例,其它两大组件你您可以自己摸索。
一、WPS的事件接口
WPS OFFICE的事件是以接口的形式提供的,以WPS文字为例,它的接口声明在
WPS_TLB.PAS中,有applicationevents接口和 DocumentEvents接口,声明和说明如下: ApplicationEvents = dispinterface
['{000209FE-0000-4B30-A977-D214852036FE}']
procedure Startup; dispid 1;//启动时触发
procedure Quit; dispid 2;//退出时触发
procedure DocumentChange; dispid 3;//文档改变时触发
procedure DocumentOpen(const Doc: _Document); dispid 4;//打开文档时触发
procedure DocumentBeforeClose(const Doc: _Document; var Cancel: WordBool); dispid 6;//关闭文档前触发
procedure DocumentBeforePrint(const Doc: _Document; var Cancel: WordBool); dispid 7;//打印文档前触发
procedure DocumentBeforeSave(const Doc: _Document; var SaveAsUI: WordBool; var Cancel: WordBool); dispid 8;//保存文档前触发
procedure NewDocument(const Doc: _Document); dispid 9;//新建文档时时触发
procedure WindowActivate(const Doc: _Document; const Wn: Window); dispid 10;//窗口激活时触发
procedure WindowDeactivate(const Doc: _Document; const Wn: Window); dispid 11;//窗口失去焦点时触发
procedure WindowSelectionChange(const Sel: Selection); dispid 12;//文档选区改变时触发
procedure WindowBeforeRightClick(const Sel: Selection; var Cancel: WordBool); dispid 13;//右键点击前触发
procedure WindowBeforeDoubleClick(const Sel: Selection; var Cancel: WordBool); dispid 14;//双击事件前触发
procedure WindowSize(const Doc: _Document; const Wn: Window); dispid 25;//窗口大小改变时触发
end;
DocumentEvents = dispinterface
['{000209F6-0000-4B30-A977-D214852036FE}']
procedure New; dispid 4;//新建文档时触发
procedure Open; dispid 5;//打开文档触发
procedure Close; dispid 6;//关闭文档时触发
end;
那怎么让我们的插件响应它呢?这是一个复杂的问题,它需要我们编写一个事件接收器类来挂接事件接口,然后再连接到应用程序的application接口,最后在插件中编写响应过程就可以了。由于过程比较复杂,所以我们使用已经封装好的类,它可以简化我们的编写过程,文后我会提供这一系列封装好的单元文件,主要有有WPSEVENTS.PAS 、ETEVENTS.PAS WPPEVENTS.PAS、 KSOEVENTS.PAS四个,每个单元对应一个组件,KSO对应通用的工具栏相关事件,具体情况大家可以查看源码,大家可以下载使用。
二、插件的功能与实现过程
今天我们要编写的插件实现了两个功能,一是在新打开一个文档时,将光标移到文档末尾,(默认是在文档开头),二是当新建一个文档时,自动在文档的页眉处添加文档的创建日期,同时在页脚处添加当前页码和总页数。要实现这两个功能,我们就要响应WPS的文档打开事件(DocumentOpen)和新建文档事件(NewDocument),在这两个事件中加入我们的实现代码。
按前文的步骤创建插件框架,然后声明事件接收器对象和响应过程。我们要响应的两个过程和接收器对象声明如下:
procedure OnDocumentOpen(Sender: TObject; const Doc: _Document); procedure OnNewDocument(Sender: TObject; const Doc: _Document); TWpsApp:TWPSApplicationEvents;
其中DOC是要打开或新建的文档对象,您可以用它来操作文档。在插件的连接事件中,我们要创建事件接收器对象并把他它连接到application对象,然后再挂接事件到我们定义的过程就可以了。最后还要记得在插件断开时释放我们创建的对象就可以了。具体的实现细节如下:
procedure TWpsAddin.OnConnection(const Application: IDispatch; ConnectMode: ext_ConnectMode; const AddInInst: IDispatch; var custom: PSafeArray);
begin
Fapp:=Application as _Application;
TWpsApp:=TWPSApplicationEvents.Create;//创建接收器对象实例
TWpsApp.Connect(Fapp);//连接到APPlication接口
TWpsApp.DocumentOpen:=OnDocumentOpen;//挂接事件到我们声明的过程 TWpsApp.NewDocument:=OnNewDocument;
end;
Procedure TWpsAddin.OnDisconnection(RemoveMode:
ext_DisconnectMode; var custom: PSafeArray);
begin
TWpsApp.Disconnect;//断开连接
Fapp:=nil;//释放接口
end;
(关于WPS各种接口对象的调用和使用,请参考详细的WPS API文档)
第一个功能的实现代码非常简单,只需要一行代码,如下:
procedure TWpsAddin.OnDocumentOpen(Sender: TObject; const Doc: _Document);
begin
Fapp.Selection.EndKey(wpsStory,wpsMove);//将光标移到最后。
end;
第二个功能实现有些复杂,需要对WPS的API 有较多的了解,具体的代码如下,你可以参考一下,以方便您的学习:
procedure TWpsAddin.OnNewDocument(Sender: TObject; const Doc: _Document);//新建文档事件
var rng:Range;
begin
rng:=Doc.Sections.Item(1).Headers.Item(wpsHeaderFooterPrimary).Range;//获取页眉区域
//设置页眉文本为当前日期
rng.Text:=FormatDateTime('创建于yyyy年m月d日 hh:nn:ss',now); //设置对齐方式为左对齐
rng.Paragraphs.Alignment:=wpsAlignRowLeft;
//获取页脚区域
rng:=Doc.Sections.Item(1).Footers.Item(wpsHeaderFooterPrimary).Range;
rng.Fields.Add(rng,wpsFieldPage,'',true);//添加页码域
rng.InsertBefore('第');//在前面添加"第"字
rng.Expand(wpsParagraph);//扩展区域到全段
rng.InsertAfter('页 共');//在段后插入
rng.Collapse(wpsCollapseEnd);//收缩区域到段尾
rng.Fields.Add(rng,wpsFieldNumPages,'',true);//插入总页数域 rng.Expand(wpsParagraph);//扩展区域到全段
rng.InsertAfter('页');//在段后插入
//设置对齐方式为居中对齐
rng.ParagraphFormat.Alignment:=wpsAlignParagraphCenter;
//设置文本为粗体
rng.Bold:=1;
End;
插件编写完成后,不要忘了编写插件配置文件,没有它就不能正常安装到插件平台。由于这个插件没有创建任何界面元素,所以安装后我们没有在工具栏上看到变化(当然可以在插件平台中看到),但在我们打开一个文档或新建一个文档时就看到变化了。本节的重点就是事件接收器对象(TWPSDocumentEvents),它封装了所有的Application事件,文档事件的响应要用(TWPSDocumentEvents)对象,它们的工作原理都是一样的,即创建接收器对象,连接到Application接口,挂接事件接口到本COM对象的相应方法中。对应的方法在WPSEvents中有声明:
TApplicationDocumentOpen = procedure(Sender: TObject; const Doc: _Document) of object;
TApplicationDocumentBeforeClose = procedure(Sender: TObject; const Doc: _Document; var Cancel: WordBool) of object;
TApplicationDocumentBeforePrint = procedure(Sender: TObject; const Doc: _Document; var Cancel: WordBool) of object;
TApplicationDocumentBeforeSave = procedure(Sender: TObject; const Doc: _Document; var SaveAsUI: WordBool; var Cancel: WordBool) of object;
TApplicationNewDocument = procedure(Sender: TObject; const Doc: _Document) of object;
TApplicationWindowActivate = procedure(Sender: TObject; const Doc: _Document; const Wn: Window) of object;
TApplicationWindowDeactivate = procedure(Sender: TObject; const Doc: _Document; const Wn: Window) of object;
TApplicationWindowSelectionChange = procedure(Sender: TObject; const Sel: Selection) of object;
TApplicationWindowBeforeRightClick = procedure(Sender: TObject; const Sel: Selection; var Cancel: WordBool) of object;
TApplicationWindowBeforeDoubleClick = procedure(Sender: TObject; const Sel: Selection; var Cancel: WordBool) of object;
TApplicationWindowSize = procedure(Sender: TObject; const Doc: _Document; const Wn: Window) of object;
你可以按照声明将需要的事件写到你的插件程序中,挂接后就可以使用了。
大家可以试一下 end