Illustrator SDK插件开发(插件开发框架注释)

本文深入介绍了Illustrator SDK中的插件开发框架,重点分析了Main.cpp、Plugin.cpp和Suites.cpp三个核心文件,解释了插件启动、关闭、消息响应及错误处理等关键流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在本篇文章,我将分析一下Illustrator SDK包中为开发人员提供的一个插件开发框架。

在SDK文件夹下可以找到samplecode文件夹,里面包含了插件开发的例子,同时common文件夹中提供了一个通用的插件开发框架。许多例子也是使用这个框架开发的。其中重要的是Main.cpp、Plugin.cpp和Suites.cpp。

Main.cpp中包含了PluginMain函数,也就是上篇文章介绍的Illustartor与插件进行交互的入口。我将Illustrator的Suite的概念理解为一个功能集,提供某一方面的功能API,在Main.cpp里,定义了SPBasicSuite对象,它提供了Illustrator的一些基本功能:请求和释放其他Suite、内存管理。以下是这个函数的详细代码。

extern "C" ASAPI ASErr PluginMain(char* caller, char* selector, void* message)
{
 ASErr error = kNoErr;
 SPMessageData *msgData = (SPMessageData *)message;
 
 Plugin *plugin = (Plugin *)msgData->globals;
 
 sSPBasic = msgData->basic; //这里记录下了SPBasicSuite对象
 
 if (strcmp(caller, kSPInterfaceCaller) == 0) 
 { 
  if (strcmp( selector, kSPInterfaceStartupSelector) == 0)  //插件启动
  {
   plugin = AllocatePlugin(msgData->self);
   if (plugin)
   {
    msgData->globals = (void *)plugin;
    error = plugin->StartupPlugin((SPInterfaceMessage *)message); //具体工作

    if (error != kNoErr)
    {
     // Make sure to delete in case startup failed
     delete plugin;
     plugin = nil;
     msgData->globals = nil;
    }
   }
   else
   {
    error = kOutOfMemoryErr;
   }
  }
  else if (strcmp(selector, kSPInterfaceShutdownSelector) == 0) //插件关闭
  {
   if (plugin)
   {
    error = plugin->ShutdownPlugin((SPInterfaceMessage *)message);    //具体工作
    delete plugin;
    plugin = nil;
    msgData->globals = nil;
   }
  }
 }
 
 if (plugin)
 {
  if (Plugin::IsReloadMsg(caller, selector))   //从Illustrator中还原插件
  {
   // Call this before calling any virtual functions (like Message)
   FixupReload(plugin);
   error = plugin->ReloadPlugin((SPInterfaceMessage *)message);
  }
  else //消息处理
  {
   // If a load or reload failed because the suites could not be acquired, we released
   // any partially acquired suites and returned an error.  However, SuitePea still might
   // call us, so protect against this situation.
   if (plugin->SuitesAcquired()) 
    error = plugin->Message(caller, selector, message);
   else
    error = kNoErr;
  }

  if (error == kUnhandledMsgErr)
  {
   error = kNoErr;
#ifndef NDEBUG
#ifdef MAC_ENV
   fprintf(stderr, "Warning: Unhandled plugin message: caller \"%s\" selector \"%s\"\n", caller, selector);
#else
   char buf[1024];
   
   sprintf(buf+1, "Warning: Unhandled plugin message: caller \"%s\" selector \"%s\"\n", caller, selector);
   OutputDebugStringA(buf+1);
#endif
#endif
  }
 } 

 if (error) //错误处理
 {
  if (plugin)
   plugin->ReportError(error, caller, selector, message);
  else
   Plugin::DefaultError(msgData->self, error);
 }
 
 return error;
}

 

框架与插件的交互逻辑在PluginMain函数里可以得到清晰的展现,包括插件启动、插件关闭、插件还原、插件消息响应、错误处理。

其中声明了2个重要的函数:AllocatePlugin和FixupReload。前者用于创建插件对象实例,后者用于还原插件对象实例。对于Illustrator对插件内存的管理,以及对错误处理策略,本人理解还是显得晦涩,需要更多的了解Illustrator的开发思想和c++语言特性才能体会。

Suites.cpp包含了对插件基本Suites的定义。这些Suites会在插件启动时,由SPBasicSuite对象进行请求,在插件关闭时进行释放。具体过程如下:

插件启动》Plugin调用StartupPlugin》创建Suites》请求基本Suites

插件结束》Plugin调用ShutdownPlugin》删除Suites》释放基本Suites

当然在Plugin中可以根据需要,做更多的操作。Plugin作为插件开发的基类,提供了一套可扩展的体系。如下列virtual方法:

virtual void ReportError(ASErr error, char *caller, char *selector, void *message);

virtual ASErr LockPlugin(ASBoolean lock);

virtual ASErr StartupPlugin(SPInterfaceMessage *message);
 virtual ASErr PostStartupPlugin();
 virtual ASErr ShutdownPlugin(SPInterfaceMessage *message);
 virtual ASErr UnloadPlugin(SPInterfaceMessage *message);
 virtual ASErr ReloadPlugin(SPInterfaceMessage *message);
 virtual ASErr AcquireProperty(SPPropertiesMessage *message);
 virtual ASErr ReleaseProperty(SPPropertiesMessage *message);
 virtual void GetPluginName(char *name, unsigned int maxlen);
 virtual ASErr About(SPInterfaceMessage *message);

virtual ASBoolean Purge();
 virtual ASErr Message(char *caller, char *selector, void *message);
 virtual ASErr SetGlobal(Plugin *plugin);

 virtual ASErr AllocateSuiteTables();
 virtual ASErr FillSuiteTables();
 virtual ASErr EmptySuiteTables();

 virtual ASErr AcquireOptionalSuites();

 virtual ASErr Notify(AINotifierMessage *message);

 virtual ASErr GoAction(DoActionMessage *message);

 virtual ASErr GoMenuItem(AIMenuMessage *message);
 virtual ASErr UpdateMenuItem(AIMenuMessage *message);

 virtual ASErr GetFilterParameters(AIFilterMessage *message);
 virtual ASErr GoFilter(AIFilterMessage *message);

 virtual ASErr PluginGroupNotify(AIPluginGroupMessage *message);
 virtual ASErr PluginGroupUpdate(AIPluginGroupMessage *message);

 virtual ASErr GetFileFormatParameters(AIFileFormatMessage *message);
 virtual ASErr GoFileFormat(AIFileFormatMessage *message);
 virtual ASErr CheckFileFormat(AIFileFormatMessage *message);
 virtual ASErr FileFormatUpdate(AIUpdateFileFormatMessage *message);
 virtual ASErr SetFileFormatParameters(DoActionMessage *message);

 virtual ASErr EditTool(AIToolMessage *message);
 virtual ASErr TrackToolCursor(AIToolMessage *message);
 virtual ASErr ToolMouseDown(AIToolMessage *message);
 virtual ASErr ToolMouseDrag(AIToolMessage *message);
 virtual ASErr ToolMouseUp(AIToolMessage *message);
 virtual ASErr SelectTool(AIToolMessage *message);
 virtual ASErr DeselectTool(AIToolMessage *message);
 virtual ASErr ReselectTool(AIToolMessage *message);
 virtual ASErr DecreaseDiameter(AIToolMessage *message);
 virtual ASErr IncreaseDiameter(AIToolMessage *message);

 virtual ASErr EditLiveEffectParameters(AILiveEffectEditParamMessage * message);
 virtual ASErr GoLiveEffect(AILiveEffectGoMessage * message);
 virtual ASErr LiveEffectInterpolate(AILiveEffectInterpParamMessage * message);
 virtual ASErr LiveEffectGetInputType(AILiveEffectInputTypeMessage * message);
 virtual ASErr LiveEffectConvertColorSpace(AILiveEffectConvertColorMessage * message);
 virtual ASErr LiveEffectScaleParameters(AILiveEffectScaleParamMessage * message);
 virtual ASErr LiveEffectAdjustColors(AILiveEffectAdjustColorsMessage * message);
 virtual ASErr LiveEffectHandleMerge(AILiveEffectHandleMergeMessage * message);
 
 virtual ASErr GoTimer(AITimerMessage * message);

 virtual ASErr GoClipboard( AIClipboardMessage *message );
 virtual ASErr CanCopyClipboard( AIClipboardMessage *message );
 virtual ASErr CloneClipboard( AIClipboardMessage *message );
 virtual ASErr DisposeClipboard( AIClipboardMessage *message );

 virtual ASErr WorkspaceWrite( AIWorkspaceMessage *message );
 virtual ASErr WorkspaceRestore( AIWorkspaceMessage *message );
 virtual ASErr WorkspaceDefault( AIWorkspaceMessage *message );

 

重载这些方法提供插件的特性,熟悉面向对象方法的开发者来说是容易的。结合Main和Plugin以及Suites理解插件的体系结构,有利于了解插件的运作机制,是打基础的过程。此外common中还有些类,如SDKAboutPluginsHelper提供了关于对话框的功能、SDKErrors提供了错误格式化并进行对话框提示的功能。可以在具体开发过程中逐渐的查看并了解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值