プラグインから縦書きと行番号の設定を取得したい

  1. 「Mery」の開発ありがとうございます。
    現在、プラグインで開発を行っていますが、以下の2点を教えていただけますでしょうか?
    公開されているプラグインのソースを調査したり「mPlugin.pas」を見ましたが情報は見つかられませんでした。

    使用環境は以下です。
    Mery: 3.7.17 (x86, Portable)
    OS: Windows 10 (Version 22H2, OS Build 19045.5965, 64-bit Edition)

    1:「表示」で「縦書き」の状態を設定すると切り替えが可能ですが、プラグインからこの状態を取得したいと思います。
    以下を実行しましたが常時「0 PortLate」になりますが、「MI_GET_VERTICAL」は違う用途なのでしょうか?

    if Editor_Info(EditorHwnd, MI_GET_VERTICAL, 0) = 0 then
    begin
    __Label15.Caption := '0 PortLate';
    end
    else
    begin
    __Label15.Caption := '1 Vertoical';
    end;

    「プラグインから「縦書き」の状態の取得機能」の追加を希望します。

    2:「表示」で「行番号」の状態を設定すると切り替えが可能ですが、プラグインからこの状態を取得したいと思います。
    「Mery.ini」から以下を実行すると取得は可能でしたが、「ShowLineNumbers」の状態は「Mery」を一度終了しないと変更されないようです。

    if IniFile.ReadInteger('General', 'ShowLineNumbers', 0) = 0 then
    begin
    __Label16.Caption := '0 Notshow';
    end
    else
    begin
    __Label16.Caption := '1 Show';
    end;

    「変更したらその場で書き込む」または「プラグインから「行番号」の状態の取得機能」の追加を希望します。

    よろしくお願いします。

     |  大石剛司  |  返信
  2. ご愛用いただき、ありがとうございます。

    > 1:「表示」で「縦書き」の状態を設定すると切り替えが可能ですが、プラグインからこの状態を取得したいと思います。
    > 以下を実行しましたが常時「0 PortLate」になりますが、「MI_GET_VERTICAL」は違う用途なのでしょうか?

    MI_GET_VERTICALは、[オプション] > [表示] > [詳細] > [縦書き] に対応するコマンドで、この設定はエディター全体に共通するものです。(これをオンにすると新規タブも常に縦書きになります)

    一方、[表示] メニューの [縦書き] オプションは、タブ (エディター) ごとの設定であり、上記のグローバルな設定とは連動していません。

    現在のタブの縦書き状態を取得するには、Editor_QueryStatusメソッドを使います。

    var
      LChecked: Boolean;
    begin
      Editor_QueryStatus(FEditorHwnd, MEID_VIEW_VERTICAL, @LChecked);
    

    このようにすると、LCheckedに縦書きのオン/オフ状態が返されます。

    > 2:「表示」で「行番号」の状態を設定すると切り替えが可能ですが、プラグインからこの状態を取得したいと思います。
    > 「Mery.ini」から以下を実行すると取得は可能でしたが、「ShowLineNumbers」の状態は「Mery」を一度終了しないと変更されないようです。

    Mery.ini は、ファイル書き換えを伴うためリアルタイムには更新されず、基本的に [オプション] 画面で [OK] を押すか、Mery を終了したタイミングで保存されます。

    [行番号] のオン/オフ状態の取得も、縦書きと同様にEditor_QueryStatusメソッドで可能です。

    var
      LChecked: Boolean;
    begin
      Editor_QueryStatus(EditorHwnd, MEID_VIEW_SHOW_LINE_NUMBERS, @LChecked);
    

    ちなみに、他のオン/オフが可能なコマンドについても、同様の方法で状態を取得できます。

     |  Kuro  |  返信
  3. アドバイスありがとうございます。
    試行錯誤しましたが、どうしても解決できていません。
    基本的な所が理解できていないような気がします。

    以下のプログラムで、複数のファイルを開いて、タブの操作で切り替えると、ファイル名が正しく表示される事は確認しています。

    function GetFileName(hwnd: HWND): string;
    begin
      SetLength(Result, (MAX_PATH + 1));
      Editor_Info(hwnd, MI_GET_FILE_NAME, LPARAM(@Result[1]));
      Result := string(PChar(Result));
    end;
    
    procedure OnEvents(hwnd: HWND; nEvent: Cardinal; lParam: LPARAM); stdcall;
    var
      sStr1: String;
    begin
      if   ((nEvent and EVENT_DOC_SEL_CHANGED) <> 0) then
      begin
        sStr1 := GetFileName(hwnd);
        Editor_SetStatus(hwnd, PChar(sStr1));
      end;
    end;

    状況を取得するために、以下のプログラムでファイルを開く場合は「Mery」は正常に起動します。

    procedure OnEvents(hwnd: HWND; nEvent: Cardinal; lParam: LPARAM); stdcall;
    var
      LChecked1: Boolean;
      LChecked2: Boolean;
    begin
      if   ((nEvent and EVENT_DOC_SEL_CHANGED) <> 0) then
      begin
        Editor_QueryStatus(hwnd, MEID_VIEW_VERTICAL, @LChecked1);
        Editor_QueryStatus(hwnd, MEID_VIEW_SHOW_LINE_NUMBERS, @LChecked2);
      end;
    end;

    状況を取得するために、以下のプログラムでファイルを開くと、「Mery」の起動時に落ちてしまいます。

    procedure OnEvents(hwnd: HWND; nEvent: Cardinal; lParam: LPARAM); stdcall;
    var
      LChecked1: Boolean;
      LChecked2: Boolean;
    begin
      if   ((nEvent and EVENT_DOC_SEL_CHANGED) <> 0) then
      begin
        Editor_QueryStatus(hwnd, MEID_VIEW_VERTICAL, @LChecked1);
        Editor_QueryStatus(hwnd, MEID_VIEW_SHOW_LINE_NUMBERS, @LChecked2);
        if LChecked1 = TRUE then
        begin
          sStr1 := sStr1 + ' ' + '縦';
        end
        else
        begin
          sStr1 := sStr1 + ' ' + '横';
        end;
      end;
    end;

    Editor_QueryStatus の hwnd は、OnEvents で渡される hwnd で大丈夫なのでしょうか?
    開発環境は「Embarcadero® Delphi 12 バージョン 29.0.52631.8427 」です。
    よろしくお願いします。

     |  大石剛司  |  返信
  4. ご返信ありがとうございます。

    すみません、サンプルとして書いたコードにちょっと間違いがあったかもしれません。

    今、手元に Delphi 12 の環境がなくて、こちらではエラーを再現できず申し訳ないのですが、BooleanLongBoolに変えてみてもらえますか?

    procedure OnEvents(hwnd: HWND; nEvent: Cardinal; lParam: LPARAM); stdcall;
    var
      LChecked1: LongBool;
      LChecked2: LongBool;
    

    まずはこの変更だけでうまく動くか、試してみていただけると助かります。

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

    LongBool で、正常に取得できました。
    試しに Delphi XE2 ターゲットは32Bits で作成してみました。
    結果は以下になりました。

    Delphi XE2 Bool 正常
    Delphi XE2 LongBool 正常
    Delphi XE12 Bool 異常
    Delphi XE12 LongBool 正常

    対応は
    1:コンパイラにより変更する
    2:どちらでも動作する LonnBool で設定する
    となりますが、どちらが良いのでしょうか?

    これで先に進めます。

    ありがとうございました。

     |  大石剛司  |  返信
  6. 追加の情報です。

    公開されている mery-plugin-outline-master ですが、Delphi 12 でエラーになり、以下のように修正しました。

    Embarcadero® Delphi 12 バージョン 29.0.51961.7529

    unit mPerMonitorDpi;
    
    procedure TScaledForm.DoShow;
    var
      LFont: TFont;
    begin
      LFont := TFont.Create;
      try
        with LFont do
        begin
          Assign(FDefaultFont);
          Height := MulDiv(Height, Self.PixelsPerInch, Screen.PixelsPerInch);
        end;
        with Font do
          if (Name <> LFont.Name) or (Height <> LFont.Height) or (Charset <> LFont.Charset) then
          begin
    //      大石変更
    //      ChangeScale(Abs(LFont.Height), Abs(Height));
            ChangeScale(Abs(LFont.Height), Abs(Height), FALSE);
            Assign(LFont);
          end;
      finally
        LFont.Free;
      end;
      inherited;
    end;

    Delphi 12 Comunity Edition ですが、何故か Windows10 では頻繁に落ちるので、こまめに保存しています。あと、Windows11 では頻度が少ないですが、やはり落ちます。という事で、だましだまし、使っていきます。

    よろしくお願いします。

     |  大石剛司  |  返信
  7. ご確認いただき、ありがとうございます。

    Mery の開発環境が Delphi XE2 なので、お手数をおかけしました。

    その後、Delphi 12 の環境を用意して検証してみたところ、こちらではBooleanを使ってもクラッシュはしませんでした。ただ、値は正しく取れていないようでした。

    > 対応は
    > 1:コンパイラにより変更する
    > 2:どちらでも動作する LonnBool で設定する
    > となりますが、どちらが良いのでしょうか?

    この件については、コンパイラに関係なくLongBoolBOOLを使っていただければ OK です。

    Booleanは使わないようお願いします。XE2 ではたまたま動いていただけみたいですね。

    SDK のmPlugin.pasにあるEditor_QueryStatusは、後日こちらで修正しておきます。(アドレスを渡してるだけなので、今のままでも一応動作はします)

    function Editor_QueryStatus(hwnd: THandle; nCmdID: Cardinal; pbChecked: PBOOL): Boolean;
    begin
      Result := Boolean(SendMessage(hwnd, ME_QUERY_STATUS, WPARAM(nCmdID), LPARAM(pbChecked)));
    end;
    

    プラグインを C++ でも開発できるようにしている関係で、Delphi のBooleanと C++ のBOOLって互換性がないんですよね。

    そのため、プラグインと本体との間でポインタを介してやりとりする部分では、LongBoolBOOLを使う必要がありました。

    ちなみに、mPlugin.pasの他の箇所もざっと見てみましたが、Booleanを使っているところは単にキャストして渡しているだけなので、特に問題はないと思います。

     |  Kuro  |  返信
  8. アドバイス、ありがとうございます。
    「LongBool」を使用していきます。
    考えていたように動作すると嬉しいですよね。

    オリジナルのプラグインと、アウトラインの機能追加版を作成中です。
    完成しましたら報告させていただきます。

    今回も、ありがとうございました。

     |  大石剛司  |  返信
  9. 私もアウトラインプラグインを Delphi 12 でビルドしてみました。

    > 公開されている mery-plugin-outline-master ですが、Delphi 12 でエラーになり、以下のように修正しました。

    これは本来、TForm のChangeScaleを呼び出す処理なのですが、Delphi 12 では TFont にも同名のChangeScaleメソッドが追加されており、そちらが呼ばれてしまうためにエラーが発生しているようです。

    そのため、明示的にSelfを付けて TForm のChangeScaleを呼ぶようにします。第 3 引数は不要です。

    Self.ChangeScale(Abs(LFont.Height), Abs(Height));
    

    また、Delphi 12 では標準で Per-Monitor DPI に対応しているため、mPerMonitorDpi.pasにある独自の DPI 対応処理と競合してしまい、うまく動作しません。

    Delphi 12 の標準機能を活かすため、mPerMonitorDpi.pasの TCustomScaledForm は削除し、以下のように簡素化しました。

    unit mPerMonitorDpi;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes,
      Vcl.Graphics, Vcl.Controls, Vcl.Forms;
    
    type
      TScaledForm = class(TForm)
      private
        { Private 宣言 }
        class var FDefaultFont: TFont;
        class constructor Create;
        class destructor Destroy;
        class procedure SetDefaultFont(const Value: TFont); static;
      protected
        { Protected 宣言 }
        procedure DoShow; override;
      public
        { Public 宣言 }
        class property DefaultFont: TFont read FDefaultFont write SetDefaultFont;
      end;
    
    implementation
    
    { TScaledForm }
    
    class constructor TScaledForm.Create;
    begin
      FDefaultFont := TFont.Create;
    end;
    
    class destructor TScaledForm.Destroy;
    begin
      if Assigned(FDefaultFont) then
        FreeAndNil(FDefaultFont);
    end;
    
    procedure TScaledForm.DoShow;
    var
      LFont: TFont;
    begin
      LFont := TFont.Create;
      try
        with LFont do
        begin
          Assign(FDefaultFont);
          Height := MulDiv(Height, Self.PixelsPerInch, Screen.PixelsPerInch);
        end;
        with Font do
          if (Name <> LFont.Name) or (Height <> LFont.Height) or (Charset <> LFont.Charset) then
          begin
            Self.ChangeScale(Abs(LFont.Height), Abs(Height));
            Assign(LFont);
          end;
      finally
        LFont.Free;
      end;
      inherited;
    end;
    
    class procedure TScaledForm.SetDefaultFont(const Value: TFont);
    begin
      FDefaultFont.Assign(Value);
    end;
    
    end.
    

    このようなかたちにしておけば、Delphi XE2 では Per-Monitor DPI は使えなくなってしまいますが、Delphi 12 では標準機能で Per-Monitor DPI に対応できるようになります。

    確認するには、マルチディスプレイ環境で、片方のディスプレイのスケールを 150% などメインディスプレイと違う設定にしてみてください。

    その状態で、アウトラインプラグインの [プロパティ] ダイアログをドラッグしてディスプレイをまたいでみると、きちんとスケーリングされるかどうかが確認できます。

     |  Kuro  |  返信
  10. アドバイスありがとうございます。
    変更してコンパイルしてエラーは出ませんでした。

    >その状態で、アウトラインプラグインの [プロパティ] ダイアログをドラッグしてディスプレイをまたいでみると、きちんとスケーリングされるかどうかが確認できます。

    動作確認できました。
    ただ、「Mery」を表示しているモニタのスケーリングを変更しても、アウトラインの文字の大きさは変わりませんでした。
    この状態で、アウトラインを「OFF」して「ON」を行うと、アウトラインの文字の大きさは大きくなりますが、本体の文字よりも大きくなってしまいます。

    なお、「Mery」に添付されている「OutLine.dll」では、正常に動作しています。

    よろしくお願いします。

     |  大石剛司  |  返信
  11. ご返信ありがとうございます。

    > ただ、「Mery」を表示しているモニタのスケーリングを変更しても、アウトラインの文字の大きさは変わりませんでした。

    そういえば、注意事項があったのをすっかり忘れていました。

    Delphi 12 では、TFormPixelsPerInchプロパティが直接書き換えられなくなってしまったようです。

    Delphi の [ツール] > [オプション] > [ユーザーインターフェース] > [フォームデザイナ] > [高 DPI] にある「VCL デザイナ高 DPI モード」を「ユーザー編集可能」に設定し、TFormScaled := TrueにすればPixelsPerInchを変更できるという公式情報があるのですが、この設定を試しても変更は反映されませんでした。

    【参考】https://docwiki.embarcadero.com/RADStudio/Athens/en/High_DPI

    PixelsPerInch := 144;
    OutputDebugString(PChar(IntToStr(PixelsPerInch))); // → 96 のままで変更されない
    

    そのため、アウトラインプラグインのmMain.pas内でPixelsPerInchを変更しようとしても、まったく効果がありません。

    Delphi 側の設定で何か見落としている点があるのかもしれませんが、現時点では有効な方法が見つかっていない状況です。もしかすると Delphi 側の不具合の可能性もあります…。

    ということで、もし対応される場合は、mMain.pasTMainFormFPixelsPerInch: Integer;を定義し、FormCreateの中でFPixelsPerInch := PixelsPerInch;と初期化しておきます。

    あとは、mMain.pas内でPixelsPerInchまたはSelf.PixelsPerInchと記述されている箇所をすべて FPixelsPerInchに置き換えることで、アウトラインプラグイン側で DPI に対応できるようになるかと思います。

     |  Kuro  |  返信
  12. アドバイスありがとうございます。
    変更を行い、動作確認もできました。
    今回は、ありがとうございました。

     |  大石剛司  |  返信
  13. 運用を開始しましたが不具合が出ました。

    テキストのスケールを「100%」にして、「Mery」と「アウトライン」を起動します。
    「150%」を指定すると、「Mery」と「アウトライン」も正常に追従します。

    この「150%」の状態で「アウトライン」の表示を無効にして、再度「有効」にすると「アウトライン」が起動された時に「Mery」よりも大きなフォントで表示されます。
    オリジナルの「アウトライン」でも、大きく表示される不具合が発生しています。

    今回検索していたら下記にもありました。こちらも変更した方がよいのでしょうか?

    unit mPerMonitorDpi;
    procedure TScaledForm.DoShow;
    var
      LFont: TFont;
    begin
      LFont := TFont.Create;
      try
        with LFont do
        begin
          Assign(FDefaultFont);
    ////      追加で変更してみましたが、変化はありませんでした
    ////      Height := MulDiv(Height, Self.PixelsPerInch, Screen.PixelsPerInch);
          Height := MulDiv(Height, FPixelsPerInch, Screen.PixelsPerInch);
        end;
        with Font do
          if (Name <> LFont.Name) or (Height <> LFont.Height) or (Charset <> LFont.Charset) then
          begin
            Self.ChangeScale(Abs(LFont.Height), Abs(Height));
            Assign(LFont);
          end;
      finally
        LFont.Free;
      end;
      inherited;
    end;

    よろしくお願いします。

     |  大石剛司  |  返信
  14. > 今回検索していたら下記にもありました。こちらも変更した方がよいのでしょうか?

    TScaledForm.DoShowについてはPixelsPerInchを取得しているだけなので、そのままで問題ないと思いますが、自信はありません。

    私の環境では、同様の操作を行ってもアウトラインの文字サイズは Mery 本体と同じになりました。

    【検証環境】

    • メインディスプレイのスケール: 100% (再起動済)
    • サブディスプレイのスケール: 100%

    この状態で、サブディスプレイに Mery とアウトラインを表示。

    その後、サブディスプレイのスケールを 150% に変更すると、アウトラインの文字サイズは Mery に追従しました。

    さらに、アウトラインを一度オフにしてから再度オンにすると、アウトラインの文字サイズは Mery に追従しました。

    Windows のテキストスケーリングの仕組みはかなり複雑で、

    • 表示しているディスプレイ (メインかサブか)
    • スケール変更後に Windows を再起動したかどうか

    といった条件によって挙動が変わってきます。

    より詳しく調査するには、以下の情報が参考になるかもしれません。

    • メインディスプレイのスケール (例: 100%)

    • メインディスプレイのスケール変更後、Windows を再起動したかどうか
      → 再起動するとシステム DPI が変更されます。
      → 再起動しない場合、システム DPI はそのままで、表示上の DPI のみが変わります。

    • サブディスプレイのスケール (例: 150%)
      → サブディスプレイのスケールはシステム DPI には影響しません。

    • Mery をどちらのディスプレイで起動したか?

    これらの条件の組み合わせによって挙動が変化するため、現象が発生するケースを特定できれば、調査も進めやすくなると思います。

    また、修正されたアウトラインプラグインのソースコードの詳細が不明なため、もしかすると修正漏れなどの可能性もあるかもしれません。

    いずれにしても、現時点で緊急の対応が必要でない場合は、Delphi 12 向けの最新版アウトラインプラグインのソースコードも公開予定ですので、それをお待ちいただければ、同じソースコード上での検証が可能となり、原因の特定もしやすくなるかと思います。

     |  Kuro  |  返信
  15. 確認して下さった方法を試しましたが、こちらでは、やはり大きく表示されました。

    こちらで確認した内容です。

    ・メインディスプレイのスケール: 100% (再起動済)
    ・サブディスプレイのスケール: 100%

    ・この状態で、サブディスプレイでなく、メインディスプレイに Mery とアウトラインを表示。

    ・その後、サブディスプレイでなく、メインディスプレイのスケールを 150% に変更すると、アウトラインの文字サイズは Mery に追従しました。

    さらに、アウトラインを一度オフにしてから再度オンにすると、アウトラインの文字サイズは Mery に追従しなくて、大きく表示されました。

    >Delphi 12 向けの最新版アウトラインプラグインのソースコードも公開予定

    同じ環境にしたいので、公開まで待つことにします。

    よろしくお願いします。

     |  大石剛司  |  返信
  16. ご確認いただきありがとうございます。

    環境と条件を揃えて、こちらでも確認してみましたが、アウトラインプラグインの文字サイズは Mery に追従しているようでした。

    やはり、最新版のアウトラインプラグインのソースコードで、一度ご確認いただくのがよさそうですね。

    今週は少し立て込んでいて時間が取れそうにないのですが、週末〜土日のどこかで対応できればと思っています。今しばらくお待ちくださいませ。

    ……とはいえ、Delphi 12 の期限があと 27 日なので、遅くてもそれまでにはなんとか公開しておかないとですね ^^;

     |  Kuro  |  返信
  17. アウトラインプラグインのソースコード、公開が楽しみです。

    別件ですが、Delphi12 Comunity Edition が頻繁に落ちるので、様子を見るために別の複数の PC にインストールしていたら、ライセンスの上限に達してしまい、サポートに連絡したら、上限をリセットしてくれました。

    同様に Delphi XE2 も別の PC にインストールしたら、こちらも上限に達してしまい、同じようにサポートに連絡したら、このライセンスは無効との事でした。

    「Mery」は XE2 で開発しているようなので、パソコンの交換には注意が必要です。

    >お客様がお持ちのDelphiのシリアル番号は「永続ライセンス」ですが、無期限での製品利用が保証されるものではなく、継続的な利用には有効なアップデートサブスクリプションが必要です。
    >Serial Number: ****-******-******-**** 実際には有効な番号です
    >上記はDelphi XE2のライセンスでございますが、お客様のEDNアカウントに紐付けられているライセンス( シリアル番号)を確認しましたところ、アップデートサブスクリプションが有効なライセンスをお持ちではありませんでした。

    古いパソコンで Delphi XE2 、新しいパソコンで Delphi 12 で開発していくか、それとも、古いパソコンで開発を継続するか考えてみます。

    以上、情報でした。よろしくお願いします。

     |  大石剛司  |  返信
  18. こんにちは。

    Delphi 12 向けのアウトライン プラグインのソースコードの準備ができましたので、お知らせします。

    今回のソースコードは、これまでのように mery-plugin-outline リポジトリではなく、SDK にサンプルとして同梱するかたちにしました。

    https://github.com/haijinboys/mery-plugin-sdk

    Delphi 12 対応にあたり、以下の変更を加えています。

    • Delphi 12 に対応 (XE2 でも一応ビルド可能ですが、Per-Monitor DPI には非対応)
    • 設定の保存先をMery.iniからPlugins\Outline.iniに変更
    • System.IniFiles.pasの書き換えが不要に (文字列を"で囲むことでトリムを回避)
    • StringBuffer.pasを削除し、代わりにTStringBuilderを使用

    また、Mery に同梱されている標準のアウトライン プラグインと異なる点は以下のとおりです。

    • プロパティ ダイアログのダーク モードには非対応
    • ツリー ビューのスクロール バーのマイカ効果には非対応
    • Delphi 側の潜在的な不具合はそのまま

    これらは、Delphi の VCL ソースコードを一部書き換えている都合によるものです。

    さらに、今回のバージョンは Ver 3.2.4 となっており、Mery Ver 3.7.17 に同梱されている Ver 3.2.3 よりも新しいベースになっています。(特定の条件下で発生していたダーク モード関連の不具合に対応済みです)

    > 別件ですが、Delphi12 Comunity Edition が頻繁に落ちるので、様子を見るために別の複数の PC にインストールしていたら、ライセンスの上限に達してしまい、サポートに連絡したら、上限をリセットしてくれました。

    ひえっ、Delphi 12 Community Edition にもライセンス上限があるんですね…!無料版だから自由に使えるのかと思ってました。

    > 同様に Delphi XE2 も別の PC にインストールしたら、こちらも上限に達してしまい、同じようにサポートに連絡したら、このライセンスは無効との事でした。
    >
    > 「Mery」は XE2 で開発しているようなので、パソコンの交換には注意が必要です。

    そうなんですよね…。以前はサポートにお願いすれば上限を増やしてもらえたのですが、数年前に「これが最後」と通告されてしまいました。

    XE2 は同じ PC でも、OS をクリーンインストールするだけでライセンスを 1 つ消費してしまいます。もし PC が壊れたら、Mery の開発もそこでおしまいです (あるいはサブスクで 20 万円コース…^^;)

    それにしても、正規に購入した製品版ライセンスを「無効」とされてしまうのは、なんとも納得いかない話ですよね…。

    > 古いパソコンで Delphi XE2 、新しいパソコンで Delphi 12 で開発していくか、それとも、古いパソコンで開発を継続するか考えてみます。

    新しい PC に VirtualBox などで仮想環境を構築して、その中に XE2 をインストールするという手もありますね。そうすれば PC を買い替えても環境をそのまま移行できます。

    …ただ、その肝心の XE2 ライセンスが使えないことには、どうにもならないですね。ほんと困ったものです。

     |  Kuro  |  返信
  19. ソースファイルの公開ありがとうございます。

    こちらの環境でも、拡大縮小に追従することを確認しました。
    ありがとうございました。

    これから OutLine に、自分で追加した部分を反映させていきます。

    私の場合は、Delphi 12 のみで開発を行う事にしました。
    Windows Xp は対象から外れてしまいますが、時代の流れとして割り切る事にしました。

    よろしくお願いします。

     |  大石剛司  |  返信
  20. プラグインの開発を継続していますが、プラグインでアウトプットバーに文字列を表示した時のアウトプットバーへのフォーカスの移動について教えて下さい。
    Mery: 3.7.17 (x86, Portable)
    OS: Windows 10 (Version 22H2, OS Build 19045.6093, 64-bit Edition)

    過去ログを調べましたが、マクロでアウトプットバーへ表示したときは、通常はフォーカスを移動しないで、フォーカスを設定する機能を追加しています。
    これに伴って、プラグインでも以下になっています。

    // Editor_OutputString
    //   アウトプットバーに文字列を追加します
    // パラメータ
    //   hwnd:     ウィンドウのハンドル
    //   szString: 追加する文字列
    //   nFlags:   フラグ
    // 戻り値
    //   成功するとTrueを返します
    // 備考
    //   FLAG_OPEN_OUTPUT:  アウトプットバーを開きます
    //   FLAG_CLOSE_OUTPUT: アウトプットバーを閉じます
    //   FLAG_FOCUS_OUTPUT: アウトプットバーにフォーカスを設定します
    //   FLAG_CLEAR_OUTPUT: アウトプットバの文字列をクリアします

    プラグインに同梱されている「ToolBar」を変更して確認しました。

    ファイルを読み込み、編集部分にカーソルがある状態でクリックすると、1回目はアウトプットバーにフォーカスに移動します。
    編集部分にカーソルを戻してからクリックすると、2回目はアウトプットバーにフォーカスは移動しません。

    procedure TMainForm.ToolButton1Click(Sender: TObject);
    var
      sStr1: String;
    begin
    //  Editor_Insert(FEditorHandle, PChar(TToolButton(Sender).Caption));
      sStr1 := 'sss';
      Editor_OutputString(FEditorHandle, nil, FLAG_OPEN_OUTPUT);
      Editor_OutputString(FEditorHandle, nil, FLAG_CLEAR_OUTPUT);
      Editor_OutputString(FEditorHandle, PChar(sStr1), FLAG_OPEN_OUTPUT);
    end;

    1回目の移動を阻止したいのですが、何か方法はありますか?

    よろしくお願いします。

     |  大石剛司  |  返信
  21. 過去ログを見ていて気が付きました。
    毎回フォーカスをアウトプットバーに移動して、次のペインへ移動する事で対応できました。

    procedure TMainForm.ToolButton1Click(Sender: TObject);
    var
      sStr1: String;
    begin
    //  Editor_Insert(FEditorHandle, PChar(TToolButton(Sender).Caption));
      sStr1 := 'sss';
      Editor_OutputString(hwnd, nil, FLAG_OPEN_OUTPUT);
      Editor_OutputString(hwnd, nil, FLAG_CLEAR_OUTPUT);
      Editor_OutputString(hwnd, PChar(sStr1), FLAG_OPEN_OUTPUT);
      Editor_OutputString(hwnd, nil, FLAG_FOCUS_OUTPUT);  //追加
      Editor_ExecCommand(hwnd, MEID_WINDOW_NEXT_PANE);    //追加
    end;

    よろしくお願いします。

     |  大石剛司  |  返信
  22. こんばんは。

    アウトプットバーへのフォーカス移動に関しては、マクロのほうでは「移動しない」ように対応済みなのですが、プラグインについてはこれまで特にご要望をいただいたことがなかったため、従来の動作のままになっていました。

    とはいえ、マクロと同様に「デフォルトではフォーカスを移動させない」仕様のほうが、いろいろと融通が利く場面が多そうですね。

    次のバージョンでは、プラグイン側もそのように挙動を修正しておきますね。

    > Editor_ExecCommand(hwnd, MEID_WINDOW_NEXT_PANE); //追加

    たしかに、この方法でも実用上はほとんど問題ないですね。

    ただ、MEID_WINDOW_NEXT_PANEは「次のペインに移動する」コマンドなので、ウィンドウ分割などを使っていると、元のペインに戻れなくなる可能性があります。

    なので、次のようにすると、最後にアクティブだったエディターペインにフォーカスを復元できます。

    Editor_ExecCommand(hwnd, MEID_WINDOW_ACTIVE_PANE);
    

    また、プラグインからマクロ機能を呼び出すこともできるので、たとえば以下のように書けば、そういった小細工をしなくても、最初からフォーカスを移動させずにアウトプットバーを表示することも可能です。

    Editor_RunMacro(hwnd, RUN_TEXT, MACRO_LANG_JSCRIPT, nil, 'outputBar.Visible = true;', nil);
    
     |  Kuro  |  返信
  23. アドバイスありがとうございます。

    Editor_ExecCommand(hwnd, MEID_WINDOW_ACTIVE_PANE);

    私の環境では、原因は判りませんが、上手く動作しませんでした。

    Editor_RunMacro(hwnd, RUN_TEXT, MACRO_LANG_JSCRIPT, nil, 'outputBar.Visible = true;', nil);

    私の環境では、ToolBarに組み込んだ場合は大丈夫でしたが、使用したいプラグインに組み込むとMeryが落ちてしまいました。
    対応版が公開されるまでは、現状のままで使用します。

    よろしくお願いします。

     |  大石剛司  |  返信
スポンサーリンク