プラグインから起動中のプラグインを取得したい

  1. 「Mery」の開発ありがとうございます。

    プラグインを使用したアプリの開発にどっぷりと浸かっていますが、自分では解決できない項目があります。

    「Mery」に添付されている「アウトライン」や今回ソースを公開している「アウトライン」が、「起動されているかどうか」を取得したいです。
    フォーラムの過去ログには「マクロでは機能がないがプラグインなら可能」という情報がありました。

    「Editor_CustomBarOpen カスタムバーを開きます」を試してみましたが違うみたいです。

    お忙しいとは思いますが、取得方法のアドバイスをお願いします。

     |  大石剛司  |  返信
  2. こんばんは。開発、お疲れさまです。

    こちらは、なかなか Mery の開発に時間が割けず、進捗はかなりスローペースになっています ^^;

    > 「Mery」に添付されている「アウトライン」や今回ソースを公開している「アウトライン」が、「起動されているかどうか」を取得したいです。
    > フォーラムの過去ログには「マクロでは機能がないがプラグインなら可能」という情報がありました。

    プラグインが起動しているかどうかは、コマンドがオンになっているかどうかで判別できるため、Editor_QueryStatusを使えば確認できる……はずだったのですが、実際に試してみると少し挙動が怪しい感じでした。

    通常のコマンドであればオン/オフの状態はリアルタイムに更新されるのですが、プラグインのオン/オフ状態については、プラグイン本体に問い合わせる必要があるため、リアルタイムでは更新されない仕様になっていました。

    そのため、状態が更新されるのは [ツール] > [プラグイン] メニューを開いたタイミングのみ、という仕様になっており、Editor_QueryStatusを使っても、状況によっては最新の状態を取得できないケースがあるようです。

    というわけで、次のバージョンではEditor_QueryStatusで正しい状態が取得できるように、対応しておきますね。(モチベーション次第ですが、今週の土日あたりにでも次のバージョンを…)

     |  Kuro  |  返信
  3. アドバイスありがとうございます。

    以前の私の質問への回答にヒントがあったので組み込んでみました。
    現状のままでも、プラグインの起動中の検出はできました。
    情報が埋もれてしまはないようにソースを記載しておきます。

    function CheckPlugin(PluginName: String): Boolean;
    var
      iRow1: Integer;
      iFind1: Integer;
      iPos1: Integer;
      iCnt1: Integer;
      bVisible1: Boolean;
      StrList1: TStringList;
      CsvList1: TStringList;
      sStr1: String;
      sStr21: String;
      sStr31: String;
      IniFile: TMemIniFile;
      LChecked1: LongBool;
    begin
    {
    Mery.ini
    
    [Plugins]
    Count=8
    
    [Plugins\Plugin0]
    FileName=Plugins\MeryQuickAccess.dll
    Visible=1
    }
    
      //確保
      StrList1 := TStringList.Create;
      CsvList1 := TStringList.Create;
    
      //ポータブル版
      if GetIniFileNamePortable(sStr21) = TRUE then
      begin
        //確保
        IniFile := TMemIniFile.Create(sStr21, TEncoding.UTF8);
        //設定
        iCnt1   := IniFile.ReadInteger('Plugins', 'Count',    0);
        //取得
        for iRow1 := 0 to iCnt1-1 do
        begin
          sStr1     := IniFile.ReadString('Plugins\Plugin' + IntToStr(iRow1), 'FileName',  '');
          bVisible1 := IniFile.ReadBool  ('Plugins\Plugin' + IntToStr(iRow1), 'Visible', TRUE);
          if sStr1 <> '' then
          begin
            if bVisible1 = TRUE then
            begin
              StrList1.Add(sStr1 + #09 + '1');
            end
            else
            begin
              StrList1.Add(sStr1 + #09 + '0');
            end;
          end;
        end;
        //破棄
        IniFile.Free;
      end;
      //インストーラ版
      if GetIniFileNameInstaller(sStr31) = TRUE then
      begin
        //確保
        IniFile := TMemIniFile.Create(sStr31, TEncoding.UTF8);
        //設定
        iCnt1   := IniFile.ReadInteger('Plugins', 'Count',    0);
        //取得
        for iRow1 := 0 to iCnt1-1 do
        begin
          sStr1     := IniFile.ReadString('Plugins\Plugin' + IntToStr(iRow1), 'FileName',  '');
          bVisible1 := IniFile.ReadBool  ('Plugins\Plugin' + IntToStr(iRow1), 'Visible', TRUE);
          if sStr1 <> '' then
          begin
            if bVisible1 = TRUE then
            begin
              StrList1.Add(sStr1 + #09 + '1');
            end
            else
            begin
              StrList1.Add(sStr1 + #09 + '0');
            end;
          end;
        end;
        //破棄
        IniFile.Free;
      end;
    
      //検索
      iFind1 := -1;
      for iRow1 := 0 to StrList1.Count-1 do
      begin
        //展開
        CsvList1.Clear;
        StringToCsvList(StrList1.Strings[iRow1], CsvList1);
        iPos1 := Pos(UpperCase('Plugins\' + PluginName), UpperCase(CsvList1[0]));
        if iPos1 = 1 then
        begin
          iFind1 := iRow1;
          Break;
        end;
      end;
      //未発見
      if iFind1 = -1 then
      begin
        Result := FALSE;
      end
      //発見
      else
      begin
        //情報取得
        //プラグインの先頭番号+先頭からの位置を指定して実行中かどうかを取得
        Editor_QueryStatus(EditorHwnd, MEID_PLUGINS + iFind1, @LChecked1);
        //設定
        if LChecked1 = TRUE then
        begin
          Result := TRUE;
        end
        else
        begin
          Result := FALSE;
        end;
      end;
      //破棄
      StrList1.Free;
      CsvList1.Free;
    end;
     |  大石剛司  |  返信
  4. ご返信ありがとうございます。

    > 現状のままでも、プラグインの起動中の検出はできました。

    おそらく、プラグイン バーを表示されているのではないかと思います。プラグイン バーを表示している場合には、オン/オフの状態が正しく反映されますね。

    これは Delphi の仕様によるもので、コンテナのコントロールが表示されているときに限り、TActionOnUpdateイベントが発生するためです。そのため、上記のケースでは問題が発生しません。

    一方、プラグイン バーを表示していない場合はOnUpdateイベントが発生しないため、[ツール] > [プラグイン] メニューにアクセスするまでは、プラグインのオン/オフ状態を正しく取得できませんでした。

    特に、プラグイン バーを表示していない状態で Mery を起動し、自動的にプラグインが起動したようなケースでは、オン/オフ状態を正しく認識できないことがあります。

    こちらの件については、次のバージョンで修正予定ですので、今しばらくお待ちくださいませ。

    ちなみに、プラグインのコマンド ID はEditor_GetCmdIDで取得できるので、INI ファイルを解析しなくても、以下のような感じで実装できるかと思います。

    procedure TMainForm.Button1Click(Sender: TObject);
    var
      ID: Cardinal;
      LChecked: BOOL;
      LDllHandle: HMODULE;
    begin
      LDllHandle := GetModuleHandle('Outline.dll');
      if LDllHandle <> 0 then
      begin
        ID := Editor_GetCmdID(FEditor, LDllHandle);
        LChecked := False;
        Editor_QueryStatus(FEditor, ID, @LChecked);
      end;
    end;
    
     |  Kuro  |  返信
スポンサーリンク