由于本人工作需求,需要对Adobe Acrobat与Adobe Reader的进行研究,并开发与其相关的插件。但是问题来了,我搜索了一遍网上的资料,无论是百度还是谷歌都找不到一篇比较正式的开发教程。无奈之下我也只能到官网下载最新版的Acrobat SDK,然后自己阅读文档并一步步地做出来。相信也有很多像我这样的新手对于第一次开发Adobe的插件一头雾水,同时又为网上搜不到相关资料而烦恼。所以,现在我根据自己的学习路径来写下关于Adobe插件开发的要点,一来帮助自己重温技术与知识,二来又能为那些需要帮助的人解惑,简直是一举两得。
利用Acrobat SDK可以进行三种方式的开发:JavaScript,Plug-ins和Interapplication communication,本文着重讨论的是第二种也就是插件的方式开发。插件方式开发就是利用提供的API去进行C++编程,编译获得一个平台相关的文件,而这个文件就是我们要的插件,在Windows平台下其实就是一个dll文件,不过这个dll文件得改一下后缀名(Windows平台下是.api)。这三种方式具体有什么区别可以查看:点击打开链接
首先登陆Adobe开发者中心下载最新版的Acrobat SDK:点击打开链接
解压SDK后可以发现里面包含了多个文件夹(下图),但由于本文主要介绍的是开发通用的插件,所以只要关心两个文件夹——Documentation和PluginSupport。Documentation里包含的是开发参考文档,主要是pdf_reference.pdf和Acrobat_HTMLHELP,前者是详细的pdf技术指引,而后者可以用网页的方式来打开,其实就是网页版(最好用IE打开浏览)的开发参考文档和API库。另外一个文件夹PluginSupport这里包含了至关重要的内容,里面主要是开发过程中所需的头文件、示例与工具。
四、开发步骤
准备工作已经做好,现在可以开始创建工程了,但是官方SDK已经提供了一套完整的开发示例给开发者,我们可以利用其中的Starter示例来作为你工程的起点,这样你就不用自己去创建一个新的工程,也不用去包含头文件等,直接开始创建自己的插件功能。它的目录路径为“~\sdk110_v1_win\Adobe\Acrobat XI SDK\Version 1\PluginSupport\Samples\Starter”。另外,如果你使用的IDE是Visual Studio,那就可以使用工具——“Visual Studio App Wizard”,通过安装该工具,你可以使用直接在Visual Studio中创建一个Adobe Plug-in项目了,该工具的目录路径为“~\sdk110_v1_win\Adobe\Acrobat XI SDK\Version 1\PluginSupport\Tools\Visual Studio App Wizard”。
为了更好的理解创建一个插件的过程,下面重新创建一个空白的工程(以Visual Studio2008为例)。
新建一个插件的步骤:
1. 创建一个新的VC++ 空项目。
2. 包含Acrobat SDK头文件,目录路径为(~\PluginSupport\Headers\API及~\PluginSupport\Headers\SDK)。
3. 添加PIMain.c源文件,文件所在的目录路径(~\PluginSupport\Headers\API),需要把该文件添加到项目源文件夹中参与编译,因为里面包含了项目的入口DLLMain。
4. 添加必须预处理器定义:WIN_ENV、WIN_PLATFORM、WIN32和WINDOWS
5. 根据自身的业务需求添加逻辑代码。
首先必须添加一个源文件用来初始化插件,在其中必须实现的方法:
PluginExportHFTs
PluginImportReplaceAndRegister
PluginInit
PluginUnload
GetExtensionName
PIHandshake
这些方法可以复制粘贴Starter示例中StartInit.cpp文件的代码,然后在方法里实现自己想要的功能。
要实现这些方法,需要知道他们的作用,这里涉及插件的的生命周期。当Acrobat或Reader启动的时候会自动去查找并定位Plug-ins目录,然后加载里面的每一个插件。只要加载成功,就会调用握手方法进行连接,即PIHandshake方法:
ACCB1 ASBool ACCB2 PIHandshake(ASUns32 handshakeVersion, void, *hsData);
在握手阶段,插件会接收到一个hsData的结构体,里面包含了一组函数指针,然后通过ASCallbackCreateProto方法创建以下四个函数的回调,并把它赋值给hsData的函数指针变量:
ACCB1 ASBool ACCB2 PluginExportHFTs(void);
ACCB1 ASBool ACCB2 PluginImportReplaceAndRegister(void);
ACCB1 ASBool ACCB2 PluginInit(void);
ACCB1 ASBool ACCB2 PluginUnload(void);
握手函数的实现如下:
ACCB1 ASBool ACCB2 PIHandshake(Uns32 handshakeVersion, void *handshakeData)
{
if(handshakeVersion == HANDSHAKE_V0200)
{
PIHandshakeData_V0200 *hsData = (PIHandshakeData_V0200 *)handshakeData;
hsData->extensionName = GetExtensionName();
hsData->exportHFTsCallback =
(void*)ASCallbackCreateProto(PIExportHFTsProcType,
&PluginExportHFTs);
hsData->importReplaceAndRegisterCallback =
(void*)ASCallbackCreateProto(PIImportReplaceAndRegisterProcType,
&PluginImportReplaceAndRegister);
hsData->initCallback =
(void*)ASCallbackCreateProto(PIInitProcType, &PluginLoad);
hsData->unloadCallback =
(void*)ASCallbackCreateProto(PIUnloadProcType, &PluginUnload);
return true;
}
return false;
}
握手结束后,Acrobat或Reader就会按顺序调用前三个回调函数:PluginExportHFTs、PluginImportReplaceAndRegister和PluginInit,完成初始化工作。当最后程序结束时,会自动调用PluginUnload。
HFT(Host Function Table)机制是Adobe一种暴露插件方法接口的机制,可以在PluginExportHFTs中导出任何本插件希望提供给其它插件使用的方法,可以直接返回true。相反地,PluginImportReplaceAndRegister是导入其他HFT,可能是Acrobat标准提供的HFT,也可能是其他的地方提供的HFT。显然易见的是,PluginInit进行初始化工作,可以对自己的业务对象进行初始化,相对地在PluginUnload中对这些对象及内存进行释放。
6. 编译代码,生成插件(.api)。
这一步非常简单,把编译生成的插件(.api)放到Adobe Acrobat或Reader安装目录下的Plug-ins文件夹中(复制前请先关闭Acrobat或Reader),该目录一般为“~\Adobe\Reader 11.0\Reader\plug_ins”,然后打开Acrobat或Reader即可,程序会自动加载插件。
插件的本质就是一个后缀名称为aex的动态库,把编译好的动态库放到AE指定的文件夹下(一般是AE安装文件夹下的Plug-ins或者用快捷方式链接到指定文件夹),AE启动时就会找到插件并加载它。 首先是进入点函数:代码如下所示: SPBasicSuite是什么?代码如下: 欢迎光临知了软件开发网络平台,本公司定制开发各类软件,主要...
在AE插件开发中,为了方便捕捉常用的异常,申明了许多方便使用的异常宏,源代码如下所示: 这些宏必须成对使用,否则由于代码不完全,而编译通不过。 欢迎光临知了软件开发网络平台,本公司定制开发各类软件,主要方向为桌面专业软件开发和插件定制开发,桌面软件主要包括文字图形识别类软件,信息管理类软件,3D打印类软件,视频类软件以及其它涉...
其实网上都有类似的博文,但大多都是调用默认打印机,所以今天写一篇调用指定打印机的方法 首先要下载第三方软件Acrobat ReaderpFile为文件路径 pPrinter为打印机名字 此方法有一个缺点,就是运行的时候会弹出软件窗口.其实原理就是模拟手工操作....
开发AE插件会使用到非常多的AE内部数据结构,先大致了解这些结构对于开发AE插件,还是非常有帮助,源代码如下所示: 这一部分是版本定义,区别各种不同版本。部分常用参数和枚举变量,代码如下: 有些参数阈值,有些是分哪些模块,它们都是可以转换成整形的有特定意义的标志。 欢迎光临知了软件开发网络平台,本公司定制开发各类软件,主要方向...
一个图是欧拉图的充要条件是每个点度数是偶数且连通 第一种操作是同时更改 ai 与 aj 的度数奇偶性,那么 ai 与 aj 之间连边,搞棵生成树,一个点的度数是奇数时就删去它与它父亲的边。 然后用第二种操作把左边的点连通,再用第二种操作把左边度数为奇数的点连起来...
我们要使左边的点度数都变为偶数。考虑第一种操作,会使左边两个点的度奇偶性变化,所以问题就转化成:给出一个图,选较少的边使得每个点的度满足奇偶性的限制。 这个怎么搞呢?有一个结论:若有解,则图的任意一个生成树,只取树边中的一些边都能得到一组解。 怎么证明呢? 显然如果已知一组边是合法的解,那么这些边一定能在同一棵生成树上。 把这组解的边标为白色边。对于其他的任意一颗生成树,若白边在树上就取他,若白边...
1. 背景 因为公司现在要在广告 SDK 开发中实现一部分代码的更新,或者是新增部分功能,因此需要从后台通过网络下载然后通过插件化的方式进行加载展示。本来想的是自己实现,但是遇到了一些问题,所以直接采用滴滴的开源框架 VirtualAPK 来实现。由于 VirtualAPK 是针对于 app 开发者的,所以我们在打包的时候需要把 SDK 稍微做一些改动。 2. 前期准备 滴滴开源框架 Virtua...
在AE内部传递参数,特别是一些复杂计算,对值具有一定的限制,源代码如下: 参数意义见注释。 欢迎光临知了软件开发网络平台,本公司定制开发各类软件,主要方向为桌面专业软件开发和插件定制开发,桌面软件主要包括文字图形识别类软件,信息管理类软件,3D打印类软件,视频类软件以及其它涉及专业的各类图形图像处理软件。插件包含AE插件,AI...
将<CEFCommandLine>中加上这一条数据,即可开启nodejs...
文章目录 简介 在字符串标准化之后进行校验 注意不可信字符串的格式化 小心使用Runtime.exec() 正则表达式的匹配 简介 为了保证java程序的安全,任何外部用户的输入我们都认为是可能有恶意攻击意图,我们需要对所有的用户输入都进行一定程度的校验。 本文将带领大家探讨一下用户输入校验的一些场景。一起来看看吧。 在字符串标准化之后进行校验 通常我们在进行字符串校验的时候需要对一些特殊字符进行...