视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Photoshop滤镜开发简介--Photoshop回调函数
2020-11-27 14:49:44 责编:小采
文档
 在上一篇文章中,我们介绍了开发Photoshop滤镜插件最基本的一些概念和基础。Ps为了满足插件的应用需求,同时也给插件提供了大量的回调函数(或服务)。例如,滤镜可以在一次调用后,保存最近一次用户设置的参数,并应用到下次调用或显示UI。这就是通过Ps的回调函数完成的。这一篇文章我们将讲解最重要的一些Ps回调函数。了解本文之后,我们将能够使用回调函数,完成例如存储我们的滤镜参数等必要的工作。本篇文章将比第一篇复杂和深入的多,但同时从这篇文章我们也可以一窥PS内部的秘密:缜密的系统设计,完善的接口以及复杂的工作机制。

(一)回调函数的分类:
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;

srcRect:源矩形(源图的复制范围)
dstRow, dstCol:目标起始点坐标(左上角),因为不拉伸绘制,所以只要左上角坐标就够了。
platformContext:在Windows系统下,即device context(DC);

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;


获取了两个子函数集,我们就可以调用相应子函数集下面的函数进行“读”“写”我们的参数了。两个子函数集的使用和注册表操作类似,我们在进行读写前,首先需要打开相应描述符。因此我们先介绍打开和关闭描述符操作。
OpenReadDescriptorProc( ):打开一个“读”描述符
定义:
PIReadDescriptor (*OpenReadDescriptorProc) (PIDescriptorHandle, DescriptorKeyIDArray);
参数说明:
PIDescriptorHandle:
描述符句柄,我们将用它在后面的操作中读写数据,类似注册表的Key。
DescriptorKeyIDArray:
uint32数组,存储需要查询的key集合。其相关定义为:
typedef unsigned long DescriptorKeyID;
typedef DescriptorKeyID DescriptorKeyIDArray[];
数组里面的元素是你需要的key名,即你要查询的参数名称,即你要求查询哪些key。注意因为是int32类型,所以每个key可以容纳4个字符表示的ASCII码,如果不足4个字节,可以用空格补足。例如,设置这个参数赋为可以设置{'Pam1','Pam2',NULL},这表示你需要查询两个参数,'Pam1'和'Pam2'。 例如脚本系统中,高斯模糊(GaussianBlur)滤镜的key是'GsnB'。
每个键值通过调用GetKeyProc()来得到的,每返回一个值,这个字符串数组中的相应key将被设置为空('')。正常情况下,当你在调用CloseReadDescriptorProc()时,这个数组将变成全部是空,否则说明有的key并没有被查询到,这时你将丢失你的数据,或者通过显示对话框要求用户来提供数据。

CloseReadDescriptorProc( ):关闭一个“读”描述符
定义:
OSErr (*CloseReadDescriptorProc) (PIReadDescriptor);
描述;关闭一个描述符,如果读过程中产生错误,它将返回最主要的错误。

GetKeyProc( ):获取一个Key
定义:
(*GetKeyProc) (PIReadDescriptor descriptor, DescriptorKeyID *key, DescType *type, int16 *flags);
描述:这个函数返回一个KeyID(参数名),描述符类型,和标识。根据函数返回时的key,表示当前查询到的是哪个key。然后我们可以使用下面将要提到的相应的查询函数获得这个key的value。相关类型定义:
typedef unsigned long DescriptorKeyID;
typedef unsigned long DescriptorTypeID;

OpenWriteDescriptorProc( )
定义: PIWriteDescriptor (*OpenWriteDescriptorProc) (void);
描述:打开一个写描述符,失败时,返回NULL;
CloseWriteDescriptorProc( )
定义:
OSErr (*CloseWriteDescriptorProc) (PIWriteDescriptor descriptor, PIDescriptorHandle *newDescriptor);
描述:
这个函数关闭一个写描述符,并创建一个新的描述符句柄,你需要把新描述符通过设置到PIDescriptorParameteres中,以返回给宿主程序。这里的函数的行为有些类似GDI操作中的SelectObject。在GDI操作中,当你对设备上下文设置新的属性时,它会把现有属性返回给你,以期待你做个备份。

两个子函数集中读出和写入数据的函数:
由于这里的函数较多,我们不一一逐个讲解,这里只是介绍大概形式,需要时单独讲解。
大多数具有比较规范的特点(有少部分函数具有例外形式,我们后面单独介绍),即读用Get开头,写用Put开头,第一个参数是相应描述符,第二个参数是用于接收查询结果(或者用于存放写入数据)的相应类型数据指针。假设我们需要查询的数据类型是TypeName,则其如下:

OSErr (*GetTypeNameProc) (PIReadDescriptor descriptor, TypeName *dest); //读
OSErr (*PutTypeNameProc) (PIWriteDescriptor descriptor, DescriptorKeyID, TypeName *dest); //写:
下面我们列出所有读子函数集和写子函数集的函数(在piaction.h中定义):

Read Descriptor sub-suite

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.gxlcms.com/

-->//读子函数集成员
typedef struct ReadDescriptorProcs
{
int16 readDescriptorProcsVersion; //版本号
int16 numReadDescriptorProcs; //函数数量
OpenReadDescriptorProc openReadDescriptorProc; //打开一个读描述符
CloseReadDescriptorProc closeReadDescriptorProc; //关闭一个读描述符
GetKeyProc getKeyProc; //读取一个key
GetIntegerProc getIntegerProc; //获取一个整数
GetFloatProc getFloatProc; //获取一个整数
GetUnitFloatProc getUnitFloatProc; //获取一个double数
GetBooleanProc getBooleanProc; //获取一个int32
GetTextProc getTextProc; //获取一个text的Handle
GetAliasProc getAliasProc; //获取一个(别名?)的句柄
GetEnumeratedProc getEnumeratedProc; //获取枚举类型
GetClassProc getClassProc; //例外,提供一个类型,和一个接收对象句柄的指针
GetSimpleReferenceProc getSimpleReferenceProc; //获取一个引用。
GetObjectProc getObjectProc; //例外,额外提供对象类型
GetCountProc getCountProc; //获取uint32数据
GetStringProc getStringProc; //获取unsigned char[256](第一个字符是字符串长度,以结尾)
GetPinnedIntegerProc getPinnedIntegerProc; //例外:获取指定范围内的整数,额外提供最小值和最大值。
GetPinnedFloatProc getPinnedFloatProc; //例外:获取指定范围内的double,额外提供最小值和最大值。
GetPinnedUnitFloatProc getPinnedUnitFloatProc; //例外:获取指定范围内指定单位(距离,密度,角度,像素,百分比)的double,
//额外提供最小值和最大值。
} ReadDescriptorProcs;


Write Descriptor sub-suite

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.gxlcms.com/

-->//写子函数集成员,形式类似前面的函数,但都额外需要提供key
typedef struct WriteDescriptorProcs
{
int16 writeDescriptorProcsVersion;
int16 numWriteDescriptorProcs;
OpenWriteDescriptorProc openWriteDescriptorProc;
CloseWriteDescriptorProc closeWriteDescriptorProc;
PutIntegerProc putIntegerProc;
PutFloatProc putFloatProc;
PutUnitFloatProc putUnitFloatProc;
PutBooleanProc putBooleanProc;
PutTextProc putTextProc;
PutAliasProc putAliasProc;
PutEnumeratedProc putEnumeratedProc;
PutClassProc putClassProc;
PutSimpleReferenceProc putSimpleReferenceProc;
PutObjectProc putObjectProc;
PutCountProc putCountProc;
PutStringProc putStringProc;
/* Scoped classes are not for use by plug-ins in Photoshop 4.0 */
PutScopedClassProc putScopedClassProc;
PutScopedObjectProc putScopedObjectProc;
} WriteDescriptorProcs;


读写参数实例:
从脚本系统读出参数:假设我们的参数的key为'Pam1',我们用一个临时变量param1来接收他:

Read A Parameter Demo Code

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.gxlcms.com/

--> PIReadDescriptor token = NULL; //读操作符
DescriptorKeyID key = NULL; //uint32,即char*,键名
DescriptorTypeID type = NULL; //描述符类型
int32 flags = 0; //标识
DescriptorKeyIDArray array = { 'Pam1', NULL }; //要查询的key集合
double param1; //我们要读取的参数
//获取描述符参数结构
PIDescriptorParameters* descParams = gFilterRecord->descriptorParameters;
if (descParams == NULL) return err;
//获取Descriptor Suite中的“读”子函数集
ReadDescriptorProcs* readProcs = gFilterRecord->descriptorParameters->readDescriptorProcs;
if (readProcs == NULL) return err;

if (descParams->descriptor != NULL)
{
//打开“读”描述符
token = readProcs->openReadDescriptorProc(descParams->descriptor, array);
if (token != NULL)
{
//获取一个键
while(readProcs->getKeyProc(token, &key, &type, &flags) && !err)
{
switch (key)
{
case 'Pam1'://读取到我们的参数
err = readProcs->getFloatProc(token, ¶m1);
break;
default:
err = readErr;
break;
}
}
//关闭读描述符
err = readProcs->closeReadDescriptorProc(token);
//释放描述符
gFilterRecord->handleProcs->disposeProc(descParams->descriptor);
descParams->descriptor = NULL;
}
}

向脚本系统写入参数:同上面的例子:

Write Descriptor Demo Code

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.gxlcms.com/

--> OSErr err = noErr;
PIWriteDescriptor token = NULL;
PIDescriptorHandle h;
const double param1 = 1.05;

PIDescriptorParameters* descParams = gFilterRecord->descriptorParameters;
if (descParams == NULL) return err;

WriteDescriptorProcs* writeProcs = gFilterRecord->descriptorParameters->writeDescriptorProcs;
if (writeProcs == NULL) return err;

token = writeProcs->openWriteDescriptorProc();
if (token != NULL)
{
//写入参数~
writeProcs->putFloatProc(token,'Pam1',¶m1);
//释放描述符
gFilterRecord->handleProcs->disposeProc(descParams->descriptor);
//关闭该“读”描述符
writeProcs->closeWriteDescriptorProc(token, &h);
//把新的描述符返还给photoshop
descParams->descriptor = h;
}


3.3 DescriptorRegistry suite:(描述符注册函数集)
描述符注册函数集主要用于描述符的注册和获取。这样可以实现在滤镜多次被调用期间,委托ps保存我们的参数。它包含注册,移除,获取key的几个关键函数。
Register()
描述:注册一个key。
定义:
OSErr (*Register)
(
/* IN */ const char* key, // 唯一的字符串或ID
/* IN */ PIActionDescriptor descriptor, //描述符句柄
/* IN */ Boolean isPersistent // 是否委托PS维护以能够存储和恢复
);
Erase()
描述:移除一个Key
定义:
OSErr (*Erase)
(
/* IN */ const char* key // 唯一的字符串或ID
);
Get()
描述:返回一个Key。返回的描述符是一个拷贝,所以使用完后你必须主动释放它。
定义:
OSErr (*Get)
(
/* IN */ const char* key, // 唯一的字符串或者ID
/* OUT */ PIActionDescriptor* descriptor // 使用完后释放他
);

3.4 ActionDescriptor suite: (动作描述符函数集)
动作描述符函数集,用于存放keys(或对象)到描述符,以及从描述符读出他们,及其他描述符管理。这个函数集中同时包含了读写函数,使用方法和上一节中的描述符类似。它的定义如下:

PSActionDescriptorProcs Struct

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.gxlcms.com/

-->typedef struct PSActionDescriptorProcs
{
// ALLOCATES: descriptor
SPAPI OSErr (*Make)(PIActionDescriptor *descriptor);
SPAPI OSErr (*Free)(PIActionDescriptor descriptor);
SPAPI OSErr (*GetType)(PIActionDescriptor descriptor, DescriptorKeyID key, DescriptorTypeID *type);
// index is zero based
SPAPI OSErr (*GetKey)(PIActionDescriptor descriptor, uint32 index, DescriptorKeyID *key);
SPAPI OSErr (*HasKey)(PIActionDescriptor descriptor, DescriptorKeyID key, Boolean *hasKey);
SPAPI OSErr (*GetCount)(PIActionDescriptor descriptor, uint32 *count);
SPAPI OSErr (*IsEqual)(PIActionDescriptor descriptor, PIActionDescriptor other, Boolean *isEqual);
SPAPI OSErr (*Erase)(PIActionDescriptor descriptor, DescriptorKeyID key);
SPAPI OSErr (*Clear)(PIActionDescriptor descriptor);
/*存入数据*/
SPAPI OSErr (*PutInteger)(PIActionDescriptor descriptor, DescriptorKeyID key, int32 value);
SPAPI OSErr (*PutFloat)(PIActionDescriptor descriptor, DescriptorKeyID key, double value);
SPAPI OSErr (*PutUnitFloat)(PIActionDescriptor descriptor, DescriptorKeyID key, DescriptorUnitID unit, double value);
SPAPI OSErr (*PutString)(PIActionDescriptor descriptor, DescriptorKeyID key, char *cstrValue);
SPAPI OSErr (*PutBoolean)(PIActionDescriptor descriptor, DescriptorKeyID key, Boolean value);
SPAPI OSErr (*PutList)(PIActionDescriptor descriptor, DescriptorKeyID key, PIActionList value);
SPAPI OSErr (*PutObject)(PIActionDescriptor descriptor, DescriptorKeyID key, DescriptorClassID type, PIActionDescriptor value);
SPAPI OSErr (*PutGlobalObject)(PIActionDescriptor descriptor, DescriptorKeyID key, DescriptorClassID type, PIActionDescriptor value);
SPAPI OSErr (*PutEnumerated)(PIActionDescriptor descriptor, DescriptorKeyID key, DescriptorEnumTypeID type, DescriptorEnumID value);
SPAPI OSErr (*PutReference)(PIActionDescriptor descriptor, DescriptorKeyID key, PIActionReference value);
SPAPI OSErr (*PutClass)(PIActionDescriptor descriptor, DescriptorKeyID key, DescriptorClassID value);
SPAPI OSErr (*PutGlobalClass)(PIActionDescriptor descriptor, DescriptorKeyID key, DescriptorClassID value);
SPAPI OSErr (*PutAlias)(PIActionDescriptor descriptor, DescriptorKeyID key, Handle value);
/*获取数据*/
SPAPI OSErr (*GetInteger)(PIActionDescriptor descriptor, DescriptorKeyID key, int32* value);
SPAPI OSErr (*GetFloat)(PIActionDescriptor descriptor, DescriptorKeyID key, double* value);
SPAPI OSErr (*GetUnitFloat)(PIActionDescriptor descriptor, DescriptorKeyID key, DescriptorUnitID* unit, double* value);
SPAPI OSErr (*GetStringLength)(PIActionDescriptor descriptor, DescriptorKeyID key, uint32 *stringLength);
SPAPI OSErr (*GetString)(PIActionDescriptor descriptor, DescriptorKeyID key, char *cstrValue, uint32 maxLength);
SPAPI OSErr (*GetBoolean)(PIActionDescriptor descriptor, DescriptorKeyID key, Boolean* value);
SPAPI OSErr (*GetList)(PIActionDescriptor descriptor, DescriptorKeyID key, PIActionList* value);
SPAPI OSErr (*GetObject)(PIActionDescriptor descriptor, DescriptorKeyID key, DescriptorClassID* type, PIActionDescriptor* value);
SPAPI OSErr (*GetGlobalObject)(PIActionDescriptor descriptor, DescriptorKeyID key, DescriptorClassID* type, PIActionDescriptor* value);
SPAPI OSErr (*GetEnumerated)(PIActionDescriptor descriptor, DescriptorKeyID key, DescriptorEnumTypeID* type, DescriptorEnumID* value);
SPAPI OSErr (*GetReference)(PIActionDescriptor descriptor, DescriptorKeyID key, PIActionReference* value);
SPAPI OSErr (*GetClass)(PIActionDescriptor descriptor, DescriptorKeyID key, DescriptorClassID* value);
SPAPI OSErr (*GetGlobalClass)(PIActionDescriptor descriptor, DescriptorKeyID key, DescriptorClassID* value);
SPAPI OSErr (*GetAlias)(PIActionDescriptor descriptor, DescriptorKeyID key, Handle* value);
/*数组形式*/
SPAPI OSErr (*HasKeys)(PIActionDescriptor descriptor, DescriptorKeyIDArray requiredKeys, Boolean *hasKeys);
SPAPI OSErr (*PutIntegers)(PIActionDescriptor descriptor, DescriptorKeyID key, uint32 count, int32* value);
SPAPI OSErr (*GetIntegers)(PIActionDescriptor descriptor, DescriptorKeyID key, uint32 count, int32* value);
SPAPI OSErr (*AsHandle)(PIActionDescriptor descriptor, PIDescriptorHandle *value); /*转换为句柄*/
SPAPI OSErr (*HandleToDescriptor)(PIDescriptorHandle value, PIActionDescriptor *descriptor); /*句柄转换为描述符*/
SPAPI OSErr (*PutZString)(PIActionDescriptor descriptor, DescriptorKeyID key, ASZString zstring);
SPAPI OSErr (*GetZString)(PIActionDescriptor descriptor, DescriptorKeyID key, ASZString *zstring);
SPAPI OSErr (*PutData)(PIActionDescriptor descriptor, DescriptorKeyID key, int32 length, void *value);
SPAPI OSErr (*GetDataLength)(PIActionDescriptor descriptor, DescriptorKeyID key, int32* value);
SPAPI OSErr (*GetData)(PIActionDescriptor descriptor, DescriptorKeyID key, void* value);
} PSActionDescriptorProcs;

把我们的参数写入描述符并注册的例子:在此之前,我们需要为我们的插件的参数指定一个唯一的ID,以注册和提取属于我们的描述符,例如:
#define plugInUniqueID "d9543b0c-3c91-11d4-97bc-00b0d0204936"

写入我们的参数

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.gxlcms.com/

-->//写入参数并注册
SPErr WriteRegistryParameters(void)
{
SPErr err = noErr;
//获得SPBasicSuite,它是获取其他Suite的基础
SPBasicSuite* basicSuite = gFilterRecord->sSPBasic;
//描述符注册函数集指针
PSDescriptorRegistryProcs* registryProcs = NULL;
//描述符函数集指针
PSActionDescriptorProcs* descriptorProcs = NULL;
//描述符句柄
PIActionDescriptor descriptor = NULL;
//我们的参数
double param1=0.1;

//获取描述符注册函数集
err = basicSuite->AcquireSuite(kPSDescriptorRegistrySuite,
kPSDescriptorRegistrySuiteVersion,
(const void **)®istryProcs);

//获取动作描述符函数集
err = basicSuite->AcquireSuite(kPSActionDescriptorSuite,
kPSActionDescriptorSuiteVersion,
(const void **)&descriptorProcs);

err = descriptorProcs->Make(&descriptor);
//写入我们的参数
err = descriptorProcs->PutFloat(descriptor, 'Pam1',param1);
//注册指定ID的描述符
err = registryProcs->Register(plugInUniqueID, descriptor, true);
//释放描述符
if (descriptor != NULL)
descriptorProcs->Free(descriptor);
//释放函数集
if (registryProcs != NULL)
basicSuite->ReleaseSuite(kPSDescriptorRegistrySuite,
kPSDescriptorRegistrySuiteVersion);
if (descriptorProcs != NULL)
basicSuite->ReleaseSuite(kPSActionDescriptorSuite,
kPSActionDescriptorSuiteVersion);
return err;
}

读取我们的参数的例子:

下载本文

显示全文
专题