百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

如何使用C++开发CDR的CPG插件?

wptr33 2025-04-27 16:41 27 浏览

在正式介绍C++的CDR插件开发技术之前,咱们先来了解一下什么是CPG(Corel Plugin)插件,即 Corel插件。

CPG插件是什么

CDR软件提供了插件机制,CPG插件就是其中的一种,另外还有GMS插件以及其他类型的插件。CPG插件是最高级的一种插件,其自由灵活程度、上手开发难度都比GMS插件要高得多,虽然开发难度较高,但它能够提供更多更强的功能。

基于C++编译的CPG插件,在同等的代码逻辑和处理数据量情况下,CPG插件的运行速度可以远超基于VBA编写的GMS插件。

CPG插件的本质其实是DLL,即动态链接库,只不过它的后缀名是 .cpg,由CDR软件来加载读取,在CDR启动时附加到CDR程序中,得到全局CDR应用程序的实例,从而实现扩展功能(即插件功能)。

CDR在启动过程中,会自动加载 Plugins 或者 plugins64 目录下的 cpg 文件(其实就是加载DLL文件)。在X4版本中,CPG插件的存放目录是 Draw\Plugins,如下图所示:

CPG插件如何开发

由于CPG插件本质上是DLL,所以理论上来说,绝大部分能够编写DLL并编译TLB类型库的开发工具,都可以拿来编写CPG,例如:C++、Delphi 等。

编写CPG插件,需要使用到CDR软件提供的 VGCoreAuto.tlb 这个TLB类型库文件。对于32位CDR而言,在 CDR安装目录的 Programs 文件夹下面,可以找到 vgcoreauto.tlb文件;对于64位CDR而言,在 CDR安装目录的 Programs64文件夹下面,可以找到 vgcoreauto.tlb文件,如下图所示:

X4版本的TLB类型库

X8版本的TLB类型库

CDR类型库对应的ID是
95e23c91-bc5a-49f3-8cd1-1fc515597048
,可以在 C++的源程序文件中头部对其进行导入,参考代码如下:

// 导入CDR类型库,并对有冲突的符号进行重命名(添加 My 前缀)
#import "libid:95e23c91-bc5a-49f3-8cd1-1fc515597048" \
            rename("GetCommandLine", "MyGetCommandLine") \
			rename("CopyFile", "MyCopyFile") \
			rename("FindWindow", "MyFindWindow")

导入后,通过暴露一个 AttachPlugin 函数,即可实现CDR软件和CPG插件之间的“连接”,或者说CPG插件“附加”到了CDR应用程序中。代码如下所示:

// 暴露AttachPlugin函数,这是CDR调用CPG插件的入口
extern "C" __declspec(dllexport) DWORD APIENTRY AttachPlugin(VGCore::IVGAppPlugin * *CorelDrawPlugin) {
    MessageBox(NULL, _bstr_t("CDR调用了 AttachPlugin 函数!"), _bstr_t("CDR插件技术网"), MB_OK);
    return 0x100;
}

使用VS2019基于C++开发CPG插件的步骤

1、在VS 2019中,创建一个DLL类型的工程。

VS2019创建项目界面

选择C++类型的动态链接库项目

在弹出来的项目配置对话框中,按照以下说明来填写。项目取名为 005-cdr-attach-plugin,你也可以改成自己的,这个名称是题主在学习CPG插件开发时,采用的顺序。解决方案名称可以改,但最好不要修改,保持和项目同名就好,也不要勾选“将解决方案和项目放在同一目录中”。保存位置放在F盘的一个文件夹(F:\CPG插件学习\),然后点击创建按钮,等待VS2019生成项目模板,如下图所示:

项目创建成功后,会自动生成一个 dllmain.cpp,这个就是DLL程序的主要程序入口文件,里面的内容已经由 VS 自动生成了一个模板,如下图所示:

在这个自动生成的 dllmain.cpp 中,全选删除,然后粘贴以下代码,就可以得到一个最简单的CPG插件,其功能只是弹出一个消息框,但它确实是本质上的CPG插件。dllmain.cpp 完整源码如下:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
 
// 导入CDR类型库,并对有冲突的符号进行重命名(添加 My 前缀)
#import "libid:95e23c91-bc5a-49f3-8cd1-1fc515597048" \
            rename("GetCommandLine", "MyGetCommandLine") \
			rename("CopyFile", "MyCopyFile") \
			rename("FindWindow", "MyFindWindow")
 
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
    return TRUE;
}
 
// 暴露AttachPlugin函数,这是CDR调用CPG插件的入口
extern "C" __declspec(dllexport) DWORD APIENTRY AttachPlugin(VGCore::IVGAppPlugin * *CorelDrawPlugin) {
    MessageBox(NULL, _bstr_t("CDR调用了 AttachPlugin 函数!"), _bstr_t("CDR插件技术网"), MB_OK);
    return 0x100;
}
 

现在请编译代码,生成解决方案。注意,本工程已配置了目标类型的后缀名是“.cpg”,因此在生成解决方案时,得到的最终文件就是CPG(否则,如果不配置,则默认后缀名是 .dll)。后缀名配置、以及编译代码生成解决方案的相关截图如下图所示:

CPG插件编译结果

最终得到的CPG插件文件

将生成的CPG插件放在上文所提的插件目录(以X4版本为例),重新启动CDR,即可得到如下所示的运行效果:

复制生成的CPG插件的CDR插件目录

CPG插件运行效果演示

本文小结

在VS2019中新建DLL类型的工程,然后在自动生成的 dllmain.cpp 顶部引入CDR的类型库,通过暴露 AttachPlugin 函数,编译生成CPG文件(DLL文件)。这便是通过C++编写CPG插件的最小可运行例子(步骤)。

当然,这个CPG插件没什么用,作用就只有一个弹出消息框。要实现具体的功能,还需要定义一个类,让该类继承自 IVGAppPlugin,从而实现一个自己可控的CPG插件类。

本文仅做参考,部分图片和源码摘自题主的CPG文章专栏,如有不正之处还请指正,我将非常感谢!感兴趣读者可联系题主获取本文提到的完整工程源码压缩包,这里就不上传了。

相关推荐

oracle数据导入导出_oracle数据导入导出工具

关于oracle的数据导入导出,这个功能的使用场景,一般是换服务环境,把原先的oracle数据导入到另外一台oracle数据库,或者导出备份使用。只不过oracle的导入导出命令不好记忆,稍稍有点复杂...

继续学习Python中的while true/break语句

上次讲到if语句的用法,大家在微信公众号问了小编很多问题,那么小编在这几种解决一下,1.else和elif是子模块,不能单独使用2.一个if语句中可以包括很多个elif语句,但结尾只能有一个...

python continue和break的区别_python中break语句和continue语句的区别

python中循环语句经常会使用continue和break,那么这2者的区别是?continue是跳出本次循环,进行下一次循环;break是跳出整个循环;例如:...

简单学Python——关键字6——break和continue

Python退出循环,有break语句和continue语句两种实现方式。break语句和continue语句的区别:break语句作用是终止循环。continue语句作用是跳出本轮循环,继续下一次循...

2-1,0基础学Python之 break退出循环、 continue继续循环 多重循

用for循环或者while循环时,如果要在循环体内直接退出循环,可以使用break语句。比如计算1至100的整数和,我们用while来实现:sum=0x=1whileTrue...

Python 中 break 和 continue 傻傻分不清

大家好啊,我是大田。...

python中的流程控制语句:continue、break 和 return使用方法

Python中,continue、break和return是控制流程的关键语句,用于在循环或函数中提前退出或跳过某些操作。它们的用途和区别如下:1.continue(跳过当前循环的剩余部分,进...

L017:continue和break - 教程文案

continue和break在Python中,continue和break是用于控制循环(如for和while)执行流程的关键字,它们的作用如下:1.continue:跳过当前迭代,...

作为前端开发者,你都经历过怎样的面试?

已经裸辞1个月了,最近开始投简历找工作,遇到各种各样的面试,今天分享一下。其实在职的时候也做过面试官,面试官时,感觉自己问的问题很难区分候选人的能力,最好的办法就是看看候选人的github上的代码仓库...

面试被问 const 是否不可变?这样回答才显功底

作为前端开发者,我在学习ES6特性时,总被const的"善变"搞得一头雾水——为什么用const声明的数组还能push元素?为什么基本类型赋值就会报错?直到翻遍MDN文档、对着内存图反...

2023金九银十必看前端面试题!2w字精品!

导文2023金九银十必看前端面试题!金九银十黄金期来了想要跳槽的小伙伴快来看啊CSS1.请解释CSS的盒模型是什么,并描述其组成部分。...

前端面试总结_前端面试题整理

记得当时大二的时候,看到实验室的学长学姐忙于各种春招,有些收获了大厂offer,有些还在苦苦面试,其实那时候的心里还蛮忐忑的,不知道自己大三的时候会是什么样的一个水平,所以从19年的寒假放完,大二下学...

由浅入深,66条JavaScript面试知识点(七)

作者:JakeZhang转发链接:https://juejin.im/post/5ef8377f6fb9a07e693a6061目录...

2024前端面试真题之—VUE篇_前端面试题vue2020及答案

添加图片注释,不超过140字(可选)...

今年最常见的前端面试题,你会做几道?

在面试或招聘前端开发人员时,期望、现实和需求之间总是存在着巨大差距。面试其实是一个交流想法的地方,挑战人们的思考方式,并客观地分析给定的问题。可以通过面试了解人们如何做出决策,了解一个人对技术和解决问...