プラグインからマクロの実行が可能です。

実行したいマクロをファイルで保存して、保存したマクロファイルを実行させます。

マクロの結果をプラグインから取得したい場合は、マクロで結果をファイルに保存して、プラグインでファイルを読み込みます。

ここでは、ファイルに保存ファイルの実行を説明します。

 

procedure DrawCustomColor(hwnd: HWND);
var
  sStr1: String;
  sStr2: String;
  sStr3: String;
  sStr12: String;
  sStr13: String;
  StrList11: TStringList;
  LChecked1: LongBool;
  LpPPoint1: PPoint;
  LpPathName: array [0..MAX_PATH - 1] of Char;
  LpFileName: array [0..MAX_PATH - 1] of Char;

//  iDoc1: Integer;
//  iDoc2: Integer;
//  iDoc3: Integer;
//  iDoc4: Integer;
begin
  //書込禁止
  //// 3.3.2
  if Editor_Info(hwnd, MI_GET_READ_ONLY, 0) = 1 then
  begin
    LChecked1 := TRUE;
//  Editor_SetStatus(hwnd, PChar('TRUE  ' + inttostr(idoc1) + ' ' + inttostr(hwnd) + ' ' + inttostr(IntColorMode)));
  end
  else
  begin
    LChecked1 := FALSE;
//  Editor_SetStatus(hwnd, PChar('FALSE ' + inttostr(idoc1) + ' ' +inttostr(hwnd) + ' ' + inttostr(IntColorMode)));
  end;

  //書き込み禁止 ON
  if LChecked1 = TRUE then
  begin
    if IntColorMode <> 2 then
    begin
      //設定
      IntColorMode := 2;
      // 3.2.6
      // MACROS_WRITE_BACK_SETTING = 'editor.WriteSettingInteger("Display", "GeneralBackColor", 0xFFFFFF)';
      // MACROS_WRITE_FONT_SETTING = 'editor.WriteSettingInteger("Display", "GeneralForeColor", 0x000000)';
      // MACROS_READ_SETTING  = 'editor.ReadSettings()';
      sStr1 := MACROS_WRITE_BACK_SETTING;
      sStr1 := StringReplace(sStr1,  '0xFFFFFF', IntToStr(ReadOnlyBackColor), []);
      sStr2 := MACROS_WRITE_FONT_SETTING;
      sStr2 := StringReplace(sStr2,  '0x000000', IntToStr(ReadOnlyFontColor), []);
      sStr3 := MACROS_READ_SETTING;
      //
      sStr12 := ExtractFilePath(ParamStr(0)) + MACROS_FOLDER_NAME + '\' + MACROS_FILE_NAME_READONLY;
      //保存
      StrList11 := TStringList.Create;
      try
        StrList11.Add(sStr1);
        StrList11.Add(sStr2);
        StrList11.Add(sStr3);
        StrList11.SaveToFile(sStr12, TEncoding.UTF8);
      finally
        StrList11.Free;
      end;

      //Editor_RunMacro(hwnd: THandle;
      //                nFlags: Cardinal;
      //                nDefMacroLang: Cardinal;
      //                pszMacroFile: PChar;
      //                pszText: PChar;
      //                pptErrorPos: PPoint): HRESULT;
      New(LpPPoint1);
      try
        FillChar(LpPathName, SizeOf(LpPathName), 0);
        StrPCopy(PChar(@LpPathName[0]), sStr12);
        FillChar(LpFileName, SizeOf(LpFileName), 0);
        Editor_RunMacro(hwnd, RUN_FILE, MACRO_LANG_JSCRIPT, LpPathName, LpFileName, LpPPoint1);
      finally
        Dispose(LpPPoint1);
      end;

    end;
  end
  //書き込み禁止 OFF
  else
  begin
    if IntColorMode <> 1 then
    begin
      //設定
      IntColorMode := 1;
      // MACROS_WRITE_BACK_SETTING = 'editor.WriteSettingInteger("Display", "GeneralBackColor", 0xFFFFFF)';
      // MACROS_WRITE_FONT_SETTING = 'editor.WriteSettingInteger("Display", "GeneralForeColor", 0x000000)';
      // MACROS_READ_SETTING  = 'editor.ReadSettings()';
      sStr1 := MACROS_WRITE_BACK_SETTING;
      sStr1 := StringReplace(sStr1,  '0xFFFFFF', IntToStr(NormalBackColor), []);
      sStr2 := MACROS_WRITE_FONT_SETTING;
      sStr2 := StringReplace(sStr2,  '0x000000', IntToStr(NormalFontColor), []);
      sStr3 := MACROS_READ_SETTING;
      //
      sStr13 := ExtractFilePath(ParamStr(0)) + MACROS_FOLDER_NAME + '\' + MACROS_FILE_NAME_NORMAL;
      //保存
      StrList11 := TStringList.Create;
      try
        StrList11.Add(sStr1);
        StrList11.Add(sStr2);
        StrList11.Add(sStr3);
        StrList11.SaveToFile(sStr13, TEncoding.UTF8);
      finally
        StrList11.Free;
      end;
      //Editor_RunMacro(hwnd: THandle;
      //                nFlags: Cardinal;
      //                nDefMacroLang: Cardinal;
      //                pszMacroFile: PChar;
      //                pszText: PChar;
      //                pptErrorPos: PPoint): HRESULT;
      New(LpPPoint1);
      try
        FillChar(LpPathName, SizeOf(LpPathName), 0);
        StrPCopy(PChar(@LpPathName[0]), sStr13);
        FillChar(LpFileName, SizeOf(LpFileName), 0);
        Editor_RunMacro(hwnd, RUN_FILE, MACRO_LANG_JSCRIPT, LpPathName, LpFileName, LpPPoint1);
      finally
        Dispose(LpPPoint1);
      end;
    end;
  end;
end;

 

 

タイマーを使用する場合は「確保」「破棄」「実行」を記述します。



procedure TMyTimer.OnMyTimer(Sender: TObject);
var
  sStr6: String;
begin
  //リセット
  MyTimer.Enabled := FALSE;


    //書込禁止
    if sStr6 = MACROS_FILE_NAME_RESULT_TRUE then
    begin
      //タブ無効
      //// 0.0.0
      if Editor_Info(EditorHwnd, MI_IS_WINDOW_COMBINED, 0) = 0 then
      begin
        //判定
        if PublicForm.FFlistCount > 1 then
        begin
          //
          if IntRunMode = 1 then
          begin
            //表示
            DrawCustomColor(EditorHwnd);
          end;
          //
          if IntRunMode = 2 then
          begin
            //表示
            InvertColor(EditorHwnd);
          end;
        end;
      end;
    end;
end;
procedure TReadOnlyFrame.OnEvents(hwnd: HWND; nEvent: Cardinal; lParam: LPARAM);
begin
  //
  if (nEvent and EVENT_CREATE_FRAME) <> 0 then
  begin
    //Ini
    ReadIniFile(hwnd);
    //Ini
    ReadMeryIniFile(hwnd);
    //確保
    MyTimer := TMyTimer.Create(nil);
    with MyTimer do
    begin
      Interval := 100;
      Enabled  := FALSE;
      OnTimer  := OnMyTimer;
    end;
  end;
  //
  if (nEvent and EVENT_CLOSE) <> 0 then
  begin
    //破棄
    FreeAndNil(MyTimer);
  end;
  //
  if (nEvent and EVENT_CLOSE_FRAME) <> 0 then
  begin
    if FForm <> nil then
    begin
      ;
    end;
  end;
  //
  if ((nEvent and EVENT_FILE_OPENED)       <> 0) or
     ((nEvent and EVENT_SET_FOCUS)         <> 0) or
     ((nEvent and EVENT_DOC_SEL_CHANGED)   <> 0) then
  begin
    IntColorMode := 0;
    EditorHwnd := hwnd;
    //タイマー起動
    MyTimer.Enabled := TRUE;
  end;
  //
  if ((nEvent and EVENT_IDLE)              <> 0) then
  begin
    //タブ無効
    //// 0.0.0
    if Editor_Info(hwnd, MI_IS_WINDOW_COMBINED, 0) = 0 then
    begin
      //判定
      if PublicForm.FFlistCount = 1 then
      begin
        //
        if IntRunMode = 1 then
        begin
          //表示
          DrawCustomColor(hwnd);
        end;
        //
        if IntRunMode = 2 then
        begin
          //表示
          InvertColor(hwnd);
        end;
      end;
    end
    //タブが有効
    else
    begin
      //
      if IntRunMode = 1 then
      begin
        //表示
        DrawCustomColor(hwnd);
      end;
      //
      if IntRunMode = 2 then
      begin
        //表示
        InvertColor(hwnd);
      end;
    end;
  end;

end;

プラグイン プログラム構成 後編

 

イベント処理 mRowCol.pas の中に必要な処理を書きます。

ここで渡される「hwnd: HWND」は、開いている文書毎に変わるのが重要な項目です。

 

procedure SetRowCol(hwnd: HWND);
var
  sStr1: String;
  sStr2: String;
  sStr4: String;
  sStr6: WideString;
  sStr7: WideString;
  sStr9: String;
  iValue1: Integer;
  iValue2: Integer;
  iRow1: Integer;
  iLen2: Integer;
  iLen3: Integer;
  iLen5: Integer;
  iNum2: Integer;
  iMod2: Integer;
  iPosX: Integer;
  iPosY: Integer;
  LpPPoint1: PPoint;
  Text: array [0..MAX_LINE_LENGTH-1] of Char;
  LpBuffer: array [0..MAX_PATH - 1] of Char;
  OutPutText: array [0..MAX_LINE_LENGTH-1] of Char;
  LineInfo: TGetLineInfo;
begin
  //カーソル位置
  New(LpPPoint1);
  try
    Editor_GetCaretPos(hwnd, POS_LOGICAL, LpPPoint1);
    iPosX := LpPPoint1.X;
    iPosY := LpPPoint1.Y;
  finally
    Dispose(LpPPoint1);
  end;

  //該当行の文字列を取得
  FillChar(Text, SizeOf(Text), 0);
  LineInfo.flags := POS_LOGICAL;
  LineInfo.cch := Length(Text);
  LineInfo.yLine := iPosY;
  Editor_GetLine(hwnd, @LineInfo, Text);
  sStr4 := Text;
  //設定
  sStr6 := Copy(sStr4, 1, iPosx);

  //桁位置を計算
  iNum2 := 0;
  iLen2 := 0;
  sStr9 := ' ';
  for iRow1 := 0 to iPosX-1 do
  begin
    //1文字設定
    sStr7 := MecsCopyC(sStr6, iRow1+1, 1);
    FillChar(LpBuffer, SizeOf(LpBuffer), 0);
    StrPCopy(PChar(@LpBuffer[0]), sStr7);
    //該当文字のエレメント数
    iLen3 := MecsCCSLength(sStr6, iRow1+1);
    //各エレメントの内容
    iValue1 := Ord(LpBuffer[0]);
    iValue2 := Ord(LpBuffer[1]);
    //エレメントが1以上
    if iLen3 > 1 then
    begin
      if      ((iValue1 and $D83C) = $D83C) and ((iValue2 and $DFFD) = $DFFD)  then
      begin
        iLen5 := 0;
      end
      else if ((iValue1 and $D83C) = $D83C) and ((iValue2 and $DFFF) = $DFFF)  then
      begin
        iLen5 := 0;
      end
      else
      begin
        iLen5 := 2;
      end;
    end
    //エレメントが1
    else
    begin
      if      iValue1 = $0000 then  //情報なし
      begin
        iLen5 := 0;
      end
      else if iValue1 = $200D then  //特殊文字
      begin
        iLen5 := 0;
      end
      else if iValue1 > $00FF then  //半角エリア外
      begin
        iLen5 := 2;
      end
      else if iValue1 = $0009 then  //タブ
      begin
        iLen5 := IntTabSize;
      end
      else
      begin
        iLen5 := 1;                 //該当外なので半角
      end;
    end;
    //とりあえず加算
    iLen2 := iLen2+ iLen5;

    //余り
    iMod2 := iLen2 mod IntTabSize;
    //無し
    if      iMod2 = 0 then
    begin
      iNum2 := iNum2 + iLen5;
      iLen2 := 0;
    end
    //有り
    else
    begin
      //タブ
      if iLen5 = IntTabSize then
      begin
        iNum2 := iNum2 + iLen5 - iMod2;
        iLen2 := 0;
      end
      //タブ以外
      else
      begin
        iNum2 := iNum2 + iLen5;
      end;
    end;

    //設定
    sStr9 := sStr9 + IntToStr(irow1+1) + '@' + sStr7 + '@' + IntToStr(iLen3) + '$' +
                     IntToHex(Ord(LpBuffer[0]), 4)   + '$' + IntToHex(Ord(LpBuffer[1]), 4) + ' ';
  end;

  //設定
  sStr1 := ' ' +
           Format('%d',[iPosY+1]) + ' 行, ' +
           Format('%d',[iNum2+1]) + ' 桁'   ;

  //設定
  sStr1 := sStr1 + ' ('                             +
                   Format('%d',[iPosY+1]) + ' 行, ' +
                   Format('%d',[iPosX+1]) + ' 列) ' +
                   'タブ=' + IntToStr(IntTabSize);

  //詳細
  if BoolShowDetail = TRUE then
  begin
    sStr1 := sStr1 + sStr9
  end;

  //指定桁オーバー
  if BoolShowAddMark= TRUE then
  begin
    if iNum2 > IntLineWrap then
    begin
      sStr1 := '●' + sStr1;
    end
    else
    begin
      sStr1 := '  ' + sStr1;
    end;
  end
  else
  begin
      sStr1 := '  ' + sStr1;
  end;

  //現在の内容を取得
  FillChar(OutPutText, SizeOf(OutPutText), 0);
  Editor_GetOutputString(hwnd, MAX_LINE_LENGTH, OutPutText);
  sStr2 := StrPas(OutPutText);
  //前回と異なる
  if (sStr1 <> sStr2) then
  begin
    //アウトプットバー
    if BoolShowOutPutBar= TRUE then
    begin
      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);
      Editor_SetStatus(hwnd, nil);
    end
    //ステータスバー
    else
    begin
      Editor_SetStatus(hwnd, PChar(sStr1));
      Editor_OutputString(hwnd, nil, FLAG_CLEAR_OUTPUT);
      Editor_OutputString(hwnd, nil, FLAG_CLOSE_OUTPUT);
    end;
  end;

end;

procedure TRowColFrame.OnEvents(hwnd: HWND; nEvent: Cardinal; lParam: LPARAM);
begin
  if (nEvent and EVENT_CREATE_FRAME) <> 0 then
  begin
    //Ini
    ReadIniFile(hwnd);
    //Ini
    ReadMeryIniFile(hwnd);
    //リセット
    BoolClear := FALSE;
  end;

  if (nEvent and EVENT_CLOSE_FRAME) <> 0 then
  begin
    if FForm <> nil then
    begin
      ;
    end;
  end;

  if ((nEvent and EVENT_FILE_OPENED)       <> 0) or
     ((nEvent and EVENT_DOC_SEL_CHANGED)   <> 0) or
     ((nEvent and EVENT_IDLE)              <> 0) or
     ((nEvent and EVENT_CHANGED)           <> 0) or
     ((nEvent and EVENT_CARET_MOVED)       <> 0) then
  begin
    //Status
    ReadStatus(hwnd);
    //表示
    if ((BoolRun = TRUE) and (IntZenMode = 0))         or
       ((IntZenMode = 1) and (BoolShowZenMode = TRUE)) then
    begin
      //表示
      SetRowCol(hwnd);
      //更新
      BoolClear := TRUE;
    end
    else
    begin
      //クリア
      if BoolClear = TRUE then
      begin
        //ステータスバー
        Editor_SetStatus(hwnd, nil);
        //アウトプットバー
        Editor_OutputString(hwnd, nil, FLAG_CLEAR_OUTPUT);
        Editor_OutputString(hwnd, nil, FLAG_CLOSE_OUTPUT);
      end;
      //更新
      BoolClear := FALSE;
    end;
  end;

end;

function TRowColFrame.PluginProc(hwnd: HWND; nMsg: Cardinal; wParam: WPARAM; lParam: LPARAM): LRESULT;
var
  bResult: Boolean;
begin
  Result := 0;
  case nMsg of
    MP_QUERY_PROPERTIES:
      begin
        Result := LRESULT(QueryProperties);
      end;
    MP_SET_PROPERTIES:
      begin
        //確保
        PropatyForm := TPropatyForm.Create(Application);
        //設定
        PropatyForm.EditorHwnd := hwnd;
        //表示
        if PropatyForm.ShowModal = mrOK then
        begin
          bResult := TRUE;
        end
        else
        begin
          bResult := FALSE;
        end;
        //破棄
        PropatyForm.Free;
        //保存
        if bResult = TRUE then
        begin
          //Ini
          ReadIniFile(hwnd);
          //Ini
          ReadMeryIniFile(hwnd);
          //リセット
          BoolClear := TRUE;
          //ステータスバー
          Editor_SetStatus(hwnd, nil);
          //アウトプットバー
          Editor_OutputString(hwnd, nil, FLAG_CLEAR_OUTPUT);
          //表示
          SetRowCol(hwnd);
        end;
        //
        Result := LRESULT(SetProperties);
      end;
  end;
end;

プラグイン プログラム構成2 前編

 

2の場合は複数の画面毎に動作を記述するの必要があります。

 

サンプルプログラムは私の作成したプログラムをダウンロードして下さい。

BonsFM - MeryRowColDll(win)

 

ダウウンロードしたソースファイルを解凍して、MeryRowCol.dpr を Delphi から開きます。  MeryRowCol.dpr の中の OnEvents に LFrame := TRowColFrame.Create; を記述します。

ここで参照される mRowCol.pas の中に必要な処理を書きます。

// -----------------------------------------------------------------------------
// OnEvents
//   イベントが発生した時に呼び出されます
// パラメータ
//   hwnd:   ウィンドウのハンドル
//   nEvent: イベントの種類
//   lParam: メッセージ特有の追加情報
// 備考
//   EVENT_CREATE:             エディタを起動した時
//   EVENT_CLOSE:              エディタを終了した時
//   EVENT_CREATE_FRAME:       フレームを作成された時
//   EVENT_CLOSE_FRAME:        フレームが破棄された時
//   EVENT_SET_FOCUS:          フォーカスを取得した時
//   EVENT_KILL_FOCUS:         フォーカスを失った時
//   EVENT_FILE_OPENED:        ファイルを開いた時
//   EVENT_FILE_SAVED:         ファイルを保存した時
//   EVENT_MODIFIED:           更新の状態が変更された時
//   EVENT_CARET_MOVED:        カーソルが移動した時
//   EVENT_SCROLL:             スクロールされた時
//   EVENT_SEL_CHANGED:        選択範囲が変更された時
//   EVENT_CHANGED:            テキストが変更された時
//   EVENT_CHAR:               文字が入力された時
//   EVENT_MODE_CHANGED:       編集モードが変更された時
//   EVENT_DOC_SEL_CHANGED:    アクティブな文書が変更された時
//   EVENT_DOC_CLOSE:          文書を閉じた時
//   EVENT_TAB_MOVED:          タブが移動された時
//   EVENT_CUSTOM_BAR_CLOSING: カスタムバーを閉じようとした時
//   EVENT_CUSTOM_BAR_CLOSED:  カスタムバーを閉じた時
//   EVENT_TOOL_BAR_CLOSED:    ツールバーを閉じた時
//   EVENT_TOOL_BAR_SHOW:      ツールバーが表示された時
//   EVENT_IDLE:               アイドル時
procedure OnEvents(hwnd: HWND; nEvent: Cardinal; lParam: LPARAM); stdcall;
var
  sStr11: String;
  StrList11: TStringList;
  I: Integer;
  LFrame: TFrame;
begin
  if (nEvent and EVENT_CREATE) <> 0 then
  begin
    //確保
    FList := TFrameList.Create;
  end
  else
  begin
    if Assigned(FList) then
    begin
      if (nEvent and EVENT_CREATE_FRAME) <> 0 then
      begin
        LFrame := TRowColFrame.Create;
        with LFrame do
        begin
          Handle := hwnd;
          OnEvents(hwnd, nEvent, lParam);
        end;
        //追加
        FList.Add(LFrame);
      end
      else if (nEvent and EVENT_CLOSE_FRAME) <> 0 then
      begin
        //削除
        LFrame := FList.Find(hwnd);
        if LFrame <> nil then
          with LFrame do
          begin
            OnEvents(hwnd, nEvent, lParam);
            FList.Remove(LFrame);
            Free;
          end;
      end
      else if (nEvent and EVENT_CLOSE) <> 0 then
      begin
        //削除
        for I := FList.Count - 1 downto 0 do
        begin
          FList[I].Free;
        end;
        FList.Free;
      end
      else
      begin
        LFrame := FList.Find(hwnd);
        if LFrame <> nil then
          LFrame.OnEvents(hwnd, nEvent, lParam);
      end;
    end;
  end;
end;

プラグイン プログラム構成1

 

 プラグインのプログラム構成は2種類あります。

1:プラグインのアイコンをクリックしたり、ショートカットで起動するプラグイン

MeryQuickAqcess, MeryTabList

2:常時監視を行うプラグイン

MeryRowCol,  MeryReadOnly, MeryOutLine 

 

1の場合は、比較的簡単に作成できますが、2の場合は少し複雑になります。

2の場合は複数の画面毎に動作を記述するの必要があります。 

最初に、簡単な1の場合を説明します。

 

その前に エンバカデロ から Delphi をダウンロードしてインストールします。

 

次に Mery のプラグインのソフトウェア開発キットをダウンロードして下さい。

GitHub - haijinboys/mery-plugin-sdk: Plugin SDK for Mery

 

サンプルプログラムは私の作成したプログラムをダウンロードして下さい。

BonsFM - MeryTabListDll(win)

 

ダウウンロードしたソースファイルを解凍して、MeryTabList.dpr を Delphi から開きます。

MeryTabList.dpr の中の OnCommand に必要な処理を記述します。

ここでは、TabList を表示させ、TabList の中に必要な処理を書きます。

// -----------------------------------------------------------------------------
// OnCommand
// プラグインを実行した時に呼び出されます
// パラメータ
//   hwnd: ウィンドウのハンドル
procedure OnCommand(hwnd: HWND); stdcall;
var
  bResult: Boolean;
begin
  //実行
  try
    //確保
    FormTabList := TFormTabList.Create(Application);
    //設定
    FormTabList.EditorHwnd := hwnd;
    //表示
    if FormTabList.ShowModal= mrOK then
    begin
      bResult := TRUE;
    end
    else
    begin
      bResult := FALSE;
    end;
    //結果
    if bResult = TRUE then
    begin
      ;
    end;
    //破棄
    FormTabList.Free;
  finally
    ;
  end;
end;