CorelDRAWX4的C++插件开发(四十)纯C++插件开发(4)继承插件结构体IVGAppPlugin和自动化接口IDispatch

news/2024/11/16 9:39:16/
  • 因为在注册插件的时候,是要传一个名为IDispatch*这样子的一个参数,所以我们可以看到插件在注册的时候默认就是要求这是一个实现了自动化的接口(IDispatch,如下图所示,是后面将要展示的代码,先拎出来讲一下),可以看到参数(IDispatch * EventSink)这实际上就是注册插件时需要提供的自动化的接口IDispatch的地址指针,所以我们在继承了插件结构体时还要实现自动化接口(IDispatch).
    在这里插入图片描述
  • 自动化接口IDispatch接口不过就是未知接口IUnknown接口的扩展
  • 首先大略说一下关于未知接口IUnknown,因为主程序CDR在运行过程中突然要加载我们写的插件程序,然而CDR主程序并不知道我们这些后来人写的是些啥程序,所以他根本不知道调用我们会运行出现什么,所以这个就是这个接口名字含义的由来,他只是用来呼唤我们用的,至于呼唤出来的是个什么东西它完全不知道,所以叫作未知接口,英文IUnknown更直接:“我不知道”…
  • 拆分IUnknown里面就是三个函数,分别是QueryInterface,AddRefRelease,第一个函数QueryInterface是查询接口,也是IUnknown的第一个函数,这是固定的,任何其它的IUnknown接口,第一个函数都是QueryInterface,它是用来确定查询接口用的,第二个AddRef增加和第三个Release减少分别是计数用的,用以确认这个接口的寿命,是实现自动化的一部分.
  • IDispatch就是在IUnknown的基础上再增加四个函数,分别是GetTypeInfoCount,GetTypeInfo,GetIDsOfNamesInvoke,这四个个函数就排在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中就包含了GetTypeInfoCountGetTypeInfoGetIDsOfNamesInvoke四这个纯虚函数,如下图
    在这里插入图片描述
  • 然后我们看到IDispatch : public IUnknownIDispatch 这个自动化接口结构体又继承了IUnknown未知接口结构体中的三个纯虚函数QueryInterfaceAddRefRelease,如下图
    在这里插入图片描述
  • 以上就是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_StopSessionraw_OnUnload就是在关闭CDR的时候执行的函数了,可以把一些卸载类的功能放在这里面
  • 后面就是IDispatch的七个虚函数了,AddRefRelease是生存周期用的,我们的插件程序生存周期和主程序同步,所以不需要管他,直接返回1
  • 然后GetTypeInfoCountGetTypeInfo以及GetIDsOfNames我们就直接返回E_NOTIMPL没有实现该接口,因为这些都是给动态语言后绑定用的,我们并不需要
  • 除了上面5个用不上用的,后面我们主要就是要实现Invoke等其余6个函数,一下节我们来实现它们的函数实体

http://www.ppmy.cn/news/408478.html

相关文章

CorelDRAWX4的C++插件开发(四十一)纯C++插件开发(5)实现六个纯虚函数

这一节我们实现六个剩余的纯虚函数,先上代码 HRESULT __stdcall CongLingKaiShi::QueryInterface(REFIID riid, void** ppvObject) {//如果查询的IID接口是自动化调度接口IDispatch或未知接口IUnknown或插件IVGAppPlugin则统统返回IVGAppPlugin接口if (riid IID_IDispatch ||…

谷歌浏览器打开后是360导航界面解决办法

卸载360安全卫士之后,包括重装谷歌打开还是不行 1,找到谷歌浏览器的安装位置,或者直接点击快捷方式,打开目录 2,将chrome.exe改名为谷歌浏览器.exe,重新建立快捷方式。问题解决

谷歌火狐浏览器被360浏览器劫持的解决办法

几周前就发现谷歌浏览器打开就跳转到360浏览器,一直凑合着用。 今天学习selenium不得不解决这个问题。网上查了很多方法都没用,有些方法还很复杂,倒腾了一上午。一看是几年前的答案。 我的解决办法: 1.用360安全卫士卸载360浏览…

浏览器主页被360锁定解决方案

一般下载了360安全卫士的电脑会存在这个现象:打开系统自带浏览器主页是360导航界面,问题根的本解决方案如下: 1. 打开安全防护中心 2. 打开浏览器防护 3. 打开默认浏览器防护 4. 点击 设置为 未锁定

chrome浏览器频繁卡死

输入chrome:flag 把对应的GPU选项关掉 或者重装 ,从360软件管理器上装

360极速浏览器打开某些网站经常卡死假死问题的处理

由于Google Chrome(谷歌浏览器)国内无法登陆无法使用网络收藏夹等问题。360极速浏览器是很好的代替品。可是360极速浏览器访问某些网站(如网易、凤凰网)经常会卡死。后来发现是flash插件的问题,只要将其禁用即可。方法…

dnp服务器未响应,360浏览器没响应怎么办 360浏览器未响应死机解决方法分享

360浏览器是现在许多小伙伴使用的浏览器,使用360浏览器不仅安全而且功能齐全,最近有用户在使用360浏览器浏览文章的时候,突然卡住,想知道360浏览器没响应怎么解决的小伙伴,可以看看小编给大家带来的解决方法。 360浏览…

Chrome 浏览器关闭了360主页防护后每次打开仍然是360导航问题排查与处理方法,不卸载360流氓软件解决chrome浏览器主页锁定问题

问题如下: 360 的主页锁定,设置了锁定别的但是不生效!解锁了主页锁定,又在 chrome 浏览器的设置里设置了启动后打开主页,仍然不生效! 每次打开后仍然是恶心的 360 导航主页。 后来发现是 chrome 快捷方式…