(一)回调函数的分类:
Ps的回调函数按照获取他们的位置可以被分为两种:
(1)Direct Callback:(可以直接调用的回调函数)
这些回调函数是FilterRecord的直接成员,可以从FilterRecord参数中直接获取。例如AdvanceStateProc(更新数据),TestAbortProc(测试用户取消)等,属于此类。
(2)Callback Suite:(回调函数集)
把函调函数按功能分类而提供的回调函数集,是一组回调函数组成的集合,它是一个指针,指向包含了一组回调函数的结构体(struct),我们可以从FilterRecord获取某个回调函数集,然后调用其中的函数。
当前提供的主要回调函数集有:
Buffer Suite:缓存内存管理(申请和释放缓存空间)。
UI Hook Suite:一组和UI操作有关的函数。
Channel Ports Suite:通道端口读写,用于读写PS内部的真正选区数据!而不是副本拷贝。
Descriptor Suite:描述符操作集,用于脚本记录系统,它本身又包含“读”“写”两个sub-suite(子函数集)。
Color Space Suite:颜色空间服务(颜色转换等)。
Handle Suite:句柄管理(PS封装的句柄和内存管理,和Buffer suite类似)。
Error Suite:接收和向用户显示错误信息(接收不同类型的错误信息字符串)。
GetFileList Suite:获取文件列表(获取文件,调用浏览器浏览网页等)。
GetPath Suite: 获取路径。
ZString Suite:封装字符串处理。
例如UI Hook Suite,提供了一组和UI有关的回调函数。它的第一版本被定义为:
UI Hooks Suite Version1
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.gxlcms.com/
-->#define kPSUIHooksSuiteVersion1 1 // suite版本
typedef struct
{
ProcessEventProc processEvent;
DisplayPixelsProc displayPixels;
ProgressProc progressBar;
TestAbortProc testAbort;
MainAppWindowProc MainAppWindow;
HostSetCursorProc SetCursor;
HostTickCountProc TickCount;
PluginNameProc GetPluginName;
} PSUIHooksSuite1;
请注意,有些回调函数即属于直接回调,又被存储到某个suite中,例如testAbout和displayPixels。我推测,在早期这些函数指针都被添加到FilterRecord中,但随着升级,添加的回调函数越来越多,这样就会使FilterRecord不断升级和增加成员,使维护困难,所以Adobe开始把回调函数归类,分为几种Suite,而只把suite放到FilterRecord中,这样添加函数时只要添加到相应的suite,并升级该suite即可,而不影响FilterRecord。这样早期的一些回调函数,就同时位于两个位置,FilterRecord和其所属的suite中,导致他们即可以直接调用,也可以通过相应的suite来调用。
(二)Suite PEA (插件函数集管理模块(层),我翻译的名字,有待商讨)
Suite PEA是一些Adobe系列软件使用的插件体系,它为宿主程序提供了通用的插件管理核心层,并为插件提供了一个标准接口。
和直接调用略有区别的是,函数集应该在使用前,先进行获取请求(Acquired),在使用后释放(release)suite。
一个获取的函数集本质上是一个结构体指针,指向一个包含了一组函数指针的结构,因此我们调用某个函数时候的形式如下:
sSuite->function();
因此调用一个回调函数集中的函数,形式如下:
Suite的获取和释放
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.gxlcms.com/
-->ADMBasicSuite *sADMBasic;
//获取ADMBasic Suite:
filterParamBlock->sSPBasic->AcquireSuite(
kADMBasicSuite,
kADMBasicSuiteVersion,
&sADMBasic );
//调用
sADMBasic->Beep( );
//释放
filterParamBlock->sSPBasic->ReleaseSuite(
kADMBasicSuite,
kADMBasicSuiteVersion );
(三)一部分比较重要的回调函数简介
下面我们将介绍一些我认为对于滤镜插件比较重要的回调函数。简单介绍这些回调函数的位置和使用方法。
3.1 DisplayPixelsProc( )
功能:在指定的DC上在指定位置输出像素数据(绘制图片)。(当然这个功能实际上我们也可以自己来完成。)
位置:Direct Callback, UI Hook Suite;
定义:
OSErr (*DisplayPixelsProc) (const PSPixelMap *source,
const VRect *srcRect, int32 dstRow, int32 dstCol,
unsigned32 platformContext);
参数说明:
source:第一个参数是一个描述像素信息的结构(PSPixelMap)的指针,它定义如下:
PSPixelMap Struct Define
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.gxlcms.com/
-->typedef struct PSPixelMap
{
int32 version; //版本号
VRect bounds; //边界
int32 imageMode; //模式
int32 rowBytes; //扫描行宽度
int32 colBytes; //列字节数
int32 planeBytes; //每通道字节数
void *baseAddr; //像素数据起始地址
//--------------------
// 省略
} PSPixelMap;
3.2 Descriptor suite(描述符函数集)
描述符集主要是用于ps的脚本系统的,它用于记录(录制)一系列PS中的动作过程中需要的信息和参数,并能够回放。它有分为“读”和“写”两个子函数集。我们可以使用这个函数集,使ps的脚本系统“获知”我们的滤镜并能够记录到某个动作序列中。
获取方式是先通过FilterRecord得到PIDescriptorParameters:
PIDescriptorParameters Struct Define
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.gxlcms.com/
-->typedef struct PIDescriptorParameters
{
int16 descriptorParametersVersion; //版本号
int16 playInfo; //动作播放标识:0-对话框可选;1-需要对话框;2-无对话框;
int16 recordInfo; //动作录制标识:0-对话框不显示;1-对话框显示;2-对话框静寂;
PIDescriptorHandle descriptor; //描述符的句柄,非常重要,我们将用它读写数据!
WriteDescriptorProcs* writeDescriptorProcs; //“写”子函数集
ReadDescriptorProcs* readDescriptorProcs; //“读”子函数集
} PIDescriptorParameters;
获取“读”和“写” sub-suite
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.gxlcms.com/
-->//获得描述符参数结构:
PIDescriptorParameters* descParams = gFilterRecord->descriptorParameters;
if (descParams == NULL) return err;
//获得“读”子函数集:
ReadDescriptorProcs* readProcs = gFilterRecord->descriptorParameters->readDescriptorProcs;
if (readProcs == NULL) return err;
//获得“写”子函数集:
WriteDescriptorProcs* writeProcs = gFilterRecord->descriptorParameters->writeDescriptorProcs;
if (writeProcs == NULL) return err;