CorelDRAWX4的C++插件开发(四十)纯C++插件开发(4)继承插件结构体IVGAppPlugin和自动化接口IDispatch
- 因为在注册插件的时候,是要传一个名为
IDispatch*
这样子的一个参数,所以我们可以看到插件在注册的时候默认就是要求这是一个实现了自动化的接口(IDispatch,如下图所示,是后面将要展示的代码,先拎出来讲一下),可以看到参数(IDispatch * EventSink)这实际上就是注册插件时需要提供的自动化的接口IDispatch
的地址指针,所以我们在继承了插件结构体时还要实现自动化接口(IDispatch).
- 而自动化接口
IDispatch
接口不过就是未知接口IUnknown
接口的扩展 - 首先大略说一下关于未知接口IUnknown,因为主程序CDR在运行过程中突然要加载我们写的插件程序,然而CDR主程序并不知道我们这些后来人写的是些啥程序,所以他根本不知道调用我们会运行出现什么,所以这个就是这个接口名字含义的由来,他只是用来呼唤我们用的,至于呼唤出来的是个什么东西它完全不知道,所以叫作未知接口,英文IUnknown更直接:“我不知道”…
- 拆分
IUnknown
里面就是三个函数,分别是QueryInterface
,AddRef
和Release
,第一个函数QueryInterface是查询接口,也是IUnknown的第一个函数,这是固定的,任何其它的IUnknown接口,第一个函数都是QueryInterface,它是用来确定查询接口用的,第二个AddRef增加和第三个Release减少分别是计数用的,用以确认这个接口的寿命,是实现自动化的一部分. - 而
IDispatch
就是在IUnknown的基础上再增加四个函数,分别是GetTypeInfoCount
,GetTypeInfo
,GetIDsOfNames
和Invoke
,这四个个函数就排在IUnknown三个函数后面形成一个自动化接口,有了这四个函数这个接口就不再是未知接口了,而是能够获取当前的函数个数,函数名称,ID和具体实现了一些什么功能等等.
- 接下来我们就开始创建结构体
struct CongLingKaiShi :public VGCore::IVGAppPlugin {public:// IVGAppPlugin CDR主程序启动的 4 个函数virtual HRESULT __stdcall raw_OnLoad(VGCore::IVGApplication* Application);virtual HRESULT __stdcall raw_StartSession();virtual HRESULT __stdcall raw_StopSession();virtual HRESULT __stdcall raw_OnUnload();
public:// IUnknown 未知接口 3 个函数virtual HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject);virtual ULONG __stdcall AddRef(void) {return 1;}virtual ULONG __stdcall Release(void) {return 1;}
public:// IDispatch 调度接口 4 个函数virtual HRESULT __stdcall GetTypeInfoCount(UINT* pctinfo) { return E_NOTIMPL; }virtual HRESULT __stdcall GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) { return E_NOTIMPL; }virtual HRESULT __stdcall GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) { return E_NOTIMPL; }virtual HRESULT __stdcall Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr);
};
- 首先我们看到这是一个结构体
struct
也就是结构体对象生成之前的模板 - 结构体的名字叫作
CongLingKaiShi
- 后面跟上的冒号
:public VGCore::IVGAppPlugin
就是说CongLingKaiShi这个结构体要继承冒号后面的VGCore::IVGAppPlugin
结构体, public
是描述继承形式为公有继承,也就是爷爷的财产(除私人物品)儿子和孙辈可以使用或分配给任何人- 顺带再说
private
私有继承,也就是爷爷的财产(除私人物品)儿子可以使用或分配给任何人,但孙子辈看不到 - 另一个
protected
保护继承,也就是爷爷的财产(除私人物品)只有子子孙孙及其挚友能自己使用,无权给其它外人 - 所以没有这些要求的话一般都是公有继承
public
,然后可以看到结构体里面还有四个public:
这些都定义为公有成员 - 然后我们可以看到一共有11个
virtual
开头的虚函数,这11个函数怎么来的呢,我们可以打开vgcoreauto.tlh
文件,查到定位到IVGAppPlugin
这个函数体,如下图所示
- 可以看到下方有四个
=0
为结尾的纯虚函数,然后可以看到IVGAppPlugin
后面紧跟着一个: IDispatch
,说明IVGAppPlugin还继承了IDispatch
这个结构体,而在IDispatch
中就包含了GetTypeInfoCount
和GetTypeInfo
和GetIDsOfNames
和Invoke
四这个纯虚函数,如下图
- 然后我们看到
IDispatch : public IUnknown
IDispatch 这个自动化接口结构体又继承了IUnknown
未知接口结构体中的三个纯虚函数QueryInterface
和AddRef
和Release
,如下图
- 以上就是11个纯虚函数的由来,所以当我们的结构体
CongLingKaiShi
继承了一个VGCore::IVGAppPlugin的时候,实际上我们就一次性继承了11个纯虚函数,而纯虚函数是必须被实例化的,因为纯虚函数在基类是没有实体的(基类纯虚函数在基类中免写实体并方便基类指针多态访问派生类要写实体的虚函数,这句话有点拗口,反正就是要把这些函数全都实现一遍就好了) virtual
是表示这个函数是虚函数,它一定是派生出来的结构体或者类当中的同名函数,是另外在程序的虚函数表中进行维护的HRESULT
是函数返回值,是一个无符号的长整数,跟ULONG类似的,它一般就是大于等于0的长整数long__stdcall
是标准呼叫,里面规定了出栈和入栈的顺序等等raw_OnLoad(VGCore::IVGApplication* Application)
第是第一个函数,也是最重要的一个函数,名称为raw_OnLoad,就是在CDR主程序加载成功的时候,主程序会启动这个函数,然后把最重要的VGCore::IVGApplication* Application
这个主程序的根结构体Application
传过来.然后我们就可以通过这个Application操作当前的CDR主程序了,因为所有的东西都是封装在这个Application里面.(Application在三十二章里面详细讲过了)- 然后
raw_StartSession
也差不多类似是内部启动完毕之后会加载的函数,启动时间在raw_OnLoad
之后 raw_StopSession
和raw_OnUnload
就是在关闭CDR的时候执行的函数了,可以把一些卸载类的功能放在这里面- 后面就是IDispatch的七个虚函数了,
AddRef
和Release
是生存周期用的,我们的插件程序生存周期和主程序同步,所以不需要管他,直接返回1 - 然后
GetTypeInfoCount
和GetTypeInfo
以及GetIDsOfNames
我们就直接返回E_NOTIMPL
没有实现该接口,因为这些都是给动态语言后绑定用的,我们并不需要 - 除了上面5个用不上用的,后面我们主要就是要实现
Invoke
等其余6个函数,一下节我们来实现它们的函数实体
CorelDRAWX4的C++插件开发(四十)纯C++插件开发(4)继承插件结构体IVGAppPlugin和自动化接口IDispatch相关推荐
- CorelDRAWX4的C++插件开发(四十一)纯C++插件开发(5)实现六个纯虚函数
这一节我们实现六个剩余的纯虚函数,先上代码 HRESULT __stdcall CongLingKaiShi::QueryInterface(REFIID riid, void** ppvObject ...
- CorelDRAWX4的VBA插件开发(四十六)VBA插入启动事件让CDR启动时检测并自动添加工具栏和按钮
先上结果图,这个工具栏和按钮都是主程序自动生成的 在程序的运行当中,如果我们希望程序能够自己创建工具栏和按钮,可以在CDR启动事件中设置一个检测功能 Private Sub GlobalMacroSt ...
- CorelDRAWX4的VBA插件开发(四十四)建立类(1)汇总相似功能简化重复代码:一键建立设计外框加出血线和等分折页线
这次主要来浅讲一下"类"这个功能,先上一下要实现的功能,建立设计外框加出血线和等分折页线,先上图 那什么是类呢?类其实就是CLASS,用来封装成员参数和函数的,拆开来里面就是这些东 ...
- CorelDRAWX4的VBA插件开发(四十五)建立类(2)汇总相似功能简化重复代码:一键建立设计外框加出血线和等分折页线
在上一节中已经建立好了类,那么这一节我们来调用它,先建立一个面板 然后修改框体名称 然后从左侧新建一些按钮并且以拼音为结尾进行命名 Private Sub CheckBox2_zheYe_Click( ...
- ffmpeg源码简析(十二)FFMPEG中的主要结构体总结
FFMPEG中结构体很多.最关键的结构体可以分成以下几类: a) 解协议(http,rtsp,rtmp,mms) AVIOContext,URLProtocol,URLContext主要存储视音频使用 ...
- Com插件开发-CDR插件-自动化接口-IDispatch接口-原理解析
文章目录 1.原理概述 2.GetIDsOfNames 3.GetTypeInfo 4.GetTypeInfoCount 5.Invoke 6.作者答疑 1.原理概述 向支持自动化的编程工具和其他应用 ...
- CorelDRAWX4的C++插件开发(三十九)纯C++插件开发(3)声明变量并暴露导出函数
接上一节我们接下来声明一些需要用到的变量 // 声明CorelDRAW变量=VBA::Application类 VGCore::IVGApplication* corelApp = NULL; //声 ...
- Swift学习笔记 (十八) 结构体和类
结构体和类作为一种通用而又灵活的结构,成为了人们构建代码的基础.你可以使用定义常量.变量和函数的语法,为你的结构 体和类定义属性.添加方法. 与其他编程语⾔所不同的是,Swift 并不要求你为自定 ...
- CorelDRAWX4的VBA插件开发(三十四)调用C++实现一键智能群组(第3节)主调函数以及三个被调函数
这一节就进入到了群组的实质性的内容,先把群组Qunzu()函数展示一下 先展示主调函数Qunzu(),函数里面还有四个被调函数等会儿再说 BOOL Qunzu() {//undo开 这个是一键多步撤销 ...
最新文章
- 判断正则 shell_年薪百万之路--第七十八天 Linux基础 shell
- OpenCV色彩校正模型MCC
- mysql对所有列的数据进行修改6_MySQL的SQL语句 - 数据定义语句(6)- ALTER TABLE 语句 (3)...
- 基于 .Net Core 的组件 Nuget 包制作 amp; 发布
- WARNING: Ignoring invalid distribution -ip
- mysql集群跨地域同步部署_跨地域冗余 - 跨数据中心部署方案 - 《TiDB v2.1 用户文档》 - 书栈网 · BookStack...
- 向量数量积公式_多法 | 向量数量积相关最值问题的常见处理方法
- kafka消费者分区的分配的三种机制
- linux 7 远程桌面xrdp,[转帖]CentOS7安装xrdp(windows远程桌面连接linux)
- 基于CNN目标检测方法(RCNN,Fast-RCNN,Faster-RCNN,Mask-RCNN,YOLO,SSD)行人检测
- .net 编译、反编译、查壳、脱壳、反混淆工具
- 毕设查重,避免雷区【划重点!!!】
- 第三方Banner制作轮播图的具体方法
- Python爬取豆瓣电影top250(附全部源码)
- 许远东:世界上只有2种流量,人找货和货找人,元宇宙机会在哪里
- WebDAV之葫芦儿·派盘+Ever play播放器
- 【软考数据库】第五章 计算机网络
- pygame制作游戏全套的
- Redis的五种基础数据结构和三种高级数据结构
- 迁移学习系列--领域泛化
热门文章
- FluentValidation验证教程
- 《毕业生》系列之四 霸面天源迪科
- 微信小程序校园学生选课教学论坛信息管理系统SSM-JAVA【数据库设计、论文、源码、开题报告】
- Oracle安装的一些问题收集[转]
- MSTAR数据的处理
- Android学习笔记之清单文件
- 清华大学公开课线性代数2——第9讲:马尔科夫矩阵和正矩阵
- 商业画布是什么-business model canvas
- 对*p++与*++p;(*p)++ 与 ++(*p)的理解
- 群辉videostation支持DST、EAC3