您当前的位置: 首页 >  pip

插件开发

暂无认证

  • 3浏览

    0关注

    492博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

illustrator插件开发向导--基础入门(二)--插件定义--PiPL资源--插件管理--插件入口和消息--加载和卸载--启动和关闭

插件开发 发布时间:2022-03-06 13:34:03 ,浏览量:3

文章目录
    • What defines a plug-in?(什么定义了一个插件)
    • 1.PiPL资源
    • 2.Plug-in management(插件管理)
      • 2.1Plug-in entry point and message(插件入口和消息)
      • 2.2Reload and unload messages(加载和卸载消息)
      • 2.3Start-up and shut-down message(启动和关闭消息)
    • 3.Notifiers(通告)
      • 3.1Handling callers and selectors
      • 3.2Message data(消息内容)
    • 4.作者答疑
  本文收集自互联网,再稍加修改,方便读者阅读。

What defines a plug-in?(什么定义了一个插件)

在Windows中,插件在DLL中。Illustrator插件有以下特性:

  1. 文件后缀为.aip,如CoolEffect.aip。
  2. 正确的插件PiPL资源。PiPL资源包含了插件的信息。Illustrator认为只有那些有PiPL资源的插件有可能是插件。有正确属性的文件被加载到插件列表。
  3. 代码入口包含可以在目标平台上运行二进制代码。入口点在PiPL资源中指定,调用时有许多消息描述哪个动作去执行。
1.PiPL资源

  Plug-in property list(PiPL)资源包含被Illustrator插件管理器使用的属性,包括:插件类型(kind);插件代码调用机制(ivrs);入口点(code descriptor)。Illustrator认为包含有正确PiPL的文件才可能为插件。PiPL属性使用本地平台资源定义。

2.Plug-in management(插件管理)

  当illustrator初始化启动时,只有拥有正确PiPL和代码入口的插件才能被识别。每一个插件在需要时从内存中加载或卸载。插件需要在假设它不会总是在内存的前提上编写。这也导致插件需要在卸载和重新加载时保存和恢复状态信息。插件可以从应用程序得到一些服务。由于插件可能被卸载,illustrator提供了存储重要数据的方法。每次插件调用时,会给出足够的信息来完成动作的执行。   当一个插件的资源需要另外一个插件提供时,加载顺序就变得很重要,因为提供资源的插件需要首先加载。正如上面提到的,插件导出时在PiPL资源中需要声明一个或多个suites.illustrator在加载和执行插件时,使用这些信息,确认suites和其他资源是否可用。

2.1Plug-in entry point and message(插件入口和消息)

  加载插件代码到内存中时,Illustrator插件管理与你的插件进行着通信,如果必要,会调用PiPL代码描述属性中入口点。约定上,入口点叫做PluginMain,以C语言方式编译链接: Extern “C” ASAPI ASErr PluginMain(char caller, char selector, void* message);**   三个参数被传给PluginMain函数。他们共同构成了一个消息。前两个参数表示了消息动作,描述了插件功能。第三个参数是一个指向数据结构的指针,根据消息动作不同而不同。当你决定了消息动作,可以转换消息数据参数到需要的类型。   Message actions:callers and selectors(消息动作:调用者和选择器)。每次插件调用时,会从illustrator收到消息动作。消息动作通知插件事件发生了,插件需要执行对应的动作。传递给插件的消息动作包含2个标识符: **Caller指示消息的发送者(PICA,宿主程序或插件)和动作的通用类型。Slector指定动作类型的执行动作。**所有插件收到至少4类消息动作:reload(重新加载),unload(卸载),startup(启动)和shutdown(关系)。此外,插件可能收到特定插件类型的附加消息。如,illustrator发送给插件菜单消息,它基于2个字符串,当由插件添加的菜单项被点击时:   #define kSPAccessCaller “SP Access”   #define kSPAccessUnloadSelector “Unload”   #define kSPAccessReloadSelector “Reload”   调用和选择标志是C字符串。按照约定,每一个调用字符串都有一个前缀。这样新的消息动作,可以被其他应用程序和插件轻松定义,极少产生冲突。如,illustrator使用AI作为前缀,PICA则采用SP作为前缀。消息动作用来指定插件感兴趣的事件。 在这里插入图片描述

2.2Reload and unload messages(加载和卸载消息)

  不论插件家载入内存或从内存卸载,illustrator发送access消息动作。   #define kSPAccessCaller “SP Access”   #define kSPAccessUnloadSelector “Unload”   #define kSPAccessReloadSelector “Reload”   消息包括access caller和a reload或unload selector。这是你的插件的执行安装,恢复和保存状态信息的时机。Access caller/selector排除了其他callers和selectors。Access消息排除了其他消息。Reload是你的插件首先收到的消息。Unload是最后一个。在这个过程中,你的插件必须请求和释放suites,除了那些建入了illustrator中的。

2.3Start-up and shut-down message(启动和关闭消息)

  当插件与程序交互时,Illustrator有两个核心的接口消息动作。   #define kSPInterfaceCaller “SP Interface”   #define kSPInterfaceStartupSelector “Startup”   #define kSPInterfaceShutdownSelector “Shutdown”   当illustrator启动时,发送给每一个它能找到的插件一个Startup消息。这样可以使插件分配全局内存,添加用户接口,注册suites,执行其他初始化。启动消息包括interface caller(kSPInterfaceCaller)和start-up selector(kSPInterfaceStartupSelector)。   当用户退出illustrator时,它发送每个插件一个shutdown消息。启动消息包括interface caller(kSPInterfaceCaller)和start-up selector(kSPInterfaceStartupSelector)。关闭用来更新文件,保存参数,不是简单的销毁。导出suite的插件不能销毁插件全局变量和suite信息,因为它关闭后,可能被其他插件关闭时调用。如,你的插件实现一个preferences suite被其他插件使用,可能在你关闭后,他们关闭处理时仍然要调用。

3.Notifiers(通告)

  一些动作消息同样被归于通告。指示用户改变了illustrator的一些东西。如,用户选择了一个对象。插件必须注册它们感兴趣的通告。Notifier suite用来注册或移除通告请求(参看AINotifierSuite)。插件同样可以创建它们自身的通告,用来向其他插件广播变化。

3.1Handling callers and selectors

  你的插件管理很大程度上基于收到的消息。通常,你的插件必须通过caller和selector参数来决定消息动作。如:

extern "C" ASAPI ASErr PluginMain(char *caller, char *selector, void *message)
{
    ASErr error = kNoErr;
    if( strcmp( caller, kspAccessCaller ) == 0 )
    {
        if( strcmp( selector, kspAccessReloadSelector ) == 0)
            error = MyRestorGlobals( message );
        else if( strcmp ( selector, kspAccessUnloadSelector ) == 0)
            error = MySaveGlobals( message );
    }
    else if( strcmp( caller, kspInterfaceCaller) == 0)
    {
        if( strcmp ( selector, kSPInterfaceStartupSelector) == 0)
        {
            error = MyStartupPlugin( message );
        }
        else if( strcmp( selector, kSPInterfaceShutdownSelector) == 0)
        {
            error = MyShutdownPlugin( message );
        }
    }
    else if( strcmp ( caller, kCallerAIMenu ) == 0) && strcmp( selector, kSelectorAIGoMenuItem) == 0) )
        error = MyHandleMenu( message);
    }
}
3.2Message data(消息内容)

  最后一个传入你插件入口点的指针是一个消息数据结构体,它包括这个消息动作的相关信息。如,当一个鼠标点击消息接收到时,消息结构体包括鼠标的位置。消息结构体的内容取决于消息,在你的插件定义这个后,才能知道。由于消息内容不同,按照约定,所有消息结构体由相同字段组成,组合到SPMessageData结构体中。

typedef struct SPMessageData
{
    long SPCheck;
    struct SPPlugin *self;
    void *globals;
    struct SPBasicSuite *basic;
} SPMessageData;

  如果是有效的消息,SPCheck字段包含kSPValidSPMessageData。self字段是被调用插件的引用。用来添加插件suites,adapters和其他插件数据给illustrator。Illustrator用附加数据存储这些值。如有必要,它可以用来重新调用你的插件。**globas指针被你的插件用来保存需要的调用信息。**通常,它是一个指向你插件启动时分配的一块内存。当你的插件卸载时,这个值被illustrator保存,调用插件时,又装回到插件中。插件利用这个块来保存在卸载和装载间的任何需要保持的状态信息。 注意:很重要的是globas是用illustrator的内存分配API来分配的。否则,当插件卸载时,内存可能被操作系统释放。basic字段是指向Basic suite的指针(参看 SPBasicSuite),它可以允许你的插件请求其他suites和提供基本的内存管理。当illustartor或插件想要发送一个消息到你的插件时,它传递一个对应的消息数据结构体。下面有一些例子。

CallerMessage typeDescritionkSPAccessCallerSPAccessMessageContains SPMessageDatakSPInterfaceCallerSPInterfaceMessageContains SPMessageDatakCallerAIMenuAIMenuMessageContains SPMessageData and a reference to a menu item that was chosen
if ( strcmp ( caller, kSPAccessCaller) == 0)
{
    SPAccessMessage *accessMsg = static_cast(message);
    // access accessMsg
}
else if( strcmp( caller, kSPInterfaceCaller) == 0 )
{
    SPInterfaceMessage *interfaceMsg = static_cast(message);
    // access interfaceMsg
}
else if( strcmp( caller, kCallerAIMenu ) == 0)
{
    AIMenuMessage *menuMsg = static_cast(message);
    // access menuMsg;
}
4.作者答疑

  代码长度过长,如需全部项目,请留言。

提示: 作者知了-联系方式1 提示: 作者知了-联系方式2

关注
打赏
1665481431
查看更多评论
立即登录/注册

微信扫码登录

0.0419s