InDesign Plugin SDK: ICommandInterceptorの実装方法
コマンドの実行に割り込めるという便利な仕組みの ICommandInterceptor だが、なんにしても情報が少なすぎる。sdksamples にも何の言及もないし、ネット上にもまともな情報がほとんどない…。
結論から言うと、StartupShutdownService と一緒に実装するとよい。
ClassDescriptionTableに以下のような感じで記述。
Class { kXXXXXXStartupShutdownServiceBoss, kInvalidClass, { IID_ISTARTUPSHUTDOWN, kXXXXXXStartupShutdownServiceImpl, IID_IK2SERVICEPROVIDER, kCMainThreadStartupShutdownProviderImpl, IID_ICOMMANDINTERCEPTOR, kXXXXXXCommandInterceptorImpl, } },
CommandInterceptor自体は以下のような感じで記述。
自分の目的のコマンド以外は無視して kCmdNotHandled を返す。
class XXXXXXCommandInterceptor : public CPMUnknown<ICommandInterceptor> { public: XXXXXXCommandInterceptor(IPMUnknown* boss) : CPMUnknown<ICommandInterceptor>(boss) {} virtual ~XXXXXXCommandInterceptor() {} virtual InterceptResult InterceptProcessCommand(ICommand *cmd); virtual InterceptResult InterceptScheduleCommand(ICommand *cmd) { return kCmdNotHandled; } virtual InterceptResult InterceptExecuteDynamic(ICommand * cmd) { return kCmdNotHandled; } virtual void InstallSelf() {} virtual void DeinstallSelf() {} virtual InterceptResult InterceptExecuteImmediate(ICommand * cmd) { return kCmdNotHandled; } }; CREATE_PMINTERFACE(XXXXXXCommandInterceptor, kXXXXXXCommandInterceptorImpl) ICommandInterceptor::InterceptResult XXXXXXCommandInterceptor::InterceptProcessCommand(ICommand *cmd) { switch (cmd->GetCreatorID()) { case kQuitCmdBoss: case kCloseAllAndQuitCmdBoss: // do something break; } return kCmdNotHandled; }
StartupShutdownServiceのほうは以下のような感じで記述。
ここで CommandInterceptor のインストール・アンインストールをしている。
(アンインストールが正常に動いているかは不明。そもそもアンインストールは不要かも)
class XXXXXXStartupShutdownService : public CPMUnknown<IStartupShutdownService> { public: XXXXXXStartupShutdownService(IPMUnknown* boss) : CPMUnknown<IStartupShutdownService>(boss) {} virtual ~XXXXXXStartupShutdownService() {} virtual void Startup(); virtual void Shutdown(); }; CREATE_PMINTERFACE(XXXXXXStartupShutdownService, kXXXXXXStartupShutdownServiceImpl) void XXXXXXStartupShutdownService::Startup() { InterfacePtr<ICommandInterceptor> commandInterceptor(this, UseDefaultIID()); if (commandInterceptor) { InterfacePtr<ICommandProcessor> commandProcessor(GetExecutionContextSession()->QueryCommandProcessor()); if (commandProcessor) { commandProcessor->InstallInterceptor(commandInterceptor); } } } void XXXXXXStartupShutdownService::Shutdown() { InterfacePtr<ICommandInterceptor> commandInterceptor(this, UseDefaultIID()); if (commandInterceptor) { InterfacePtr<ICommandProcessor> commandProcessor(GetExecutionContextSession()->QueryCommandProcessor()); if (commandProcessor) { commandProcessor->DeinstallInterceptor(commandInterceptor); } } }