LoginSignup
4
2

More than 3 years have passed since last update.

WinMergeのプラグインについて(開発者向け)

Last updated at Posted at 2019-09-21

この記事は
https://github.com/WinMerge/winmerge/blob/master/Docs/Developers/Plugins.html
を自分用に翻訳したメモです。

実際にプラグインを作成する場合、
http://uktaniyama.web.fc2.com/winmerge/WinMergePlugins.html
が参考になるかもしれません。


なお、ドキュメント化されていないが、 2.14.0-jp-63からは

FILE_FOLDER_PACK_UNPACK(ファイルを複数のファイルに展開)

というイベントが使用できるようで、WinMergeに同梱されているスクリプトレット(*.sct)のいくつかはこのAPIを使用している。

また、PrediffLineFilter.sctでは、BUFFER_PREDIFFが使用されているので、現在はスクリプトレットの制限は緩和されているようだ。


Plugins

Quick description

プラグインはActiveXインターフェースを使用します。
プラグインは、このインターフェイスをサポートする任意の形式で記述できます。

使用可能な例:

  • C++ COM component
  • VB ActiveX dll
  • Scriptlets (VBS, JS)
  • Delphi

制限: ScriptletsはEDITOR_SCRIPT プラグインでのみ動作します。

Propertiesはプラグインに関する情報を表示するために使用します。

Methodsはデータを処理するために使用されます。
メソッド名とSyntaxは、EventsとAPIに依ります(以下を参照)。

Events

EDITOR_SCRIPT

エディタービューで、現在の選択範囲に関数を適用します。

PREDIFF

差分をとる前に、ファイルを前処理します。プラグインは、エディターに表示されるテキストには適用されません。
これは、左右のテキストのコピーにのみ適用され、このコピーがスキャンされて差分リストが作成されます。
今現在:

  • 一つの列の削除や、変数名を変更できます。
  • 行の追加/削除/移動はできません。

PACK_UNPACK

表示可能な形式でファイルを変換します(例:ファイルを解凍します)。

  • エディターは、解凍されたデータを表示します。
  • ファイルが再圧縮されている場合があります(zip形式のファイル...)。 もちろん追加の関数が必要です。
  • プラグインの作成者がこの関数を作成した場合、ファイルは再び圧縮形式で保存されます。
  • それ以外の場合、ファイルはテキスト形式でのみ保存できます。 問題を回避するため、変更されたファイルを保存するときにファイル名を変更することをお勧めします。

API

一部のイベントには2つのAPIがあります。 1つはBSTR(メモリ)を介してデータを交換し、もう1つは入力/出力ファイルを介して交換します。

FILE_PREDIFF データは入力ファイルと出力ファイルを介して交換されます
BUFFER_PREDIFF データはBSTRを介して交換されます
FILE_PACK_UNPACK データは入力ファイルと出力ファイルを介して交換されます
BUFFER_PACK_UNPACK データは SafeArrayを介して交換されます (パックされたデータはテキストではない可能性があるため、BSTRは使用できません)
EDITOR_SCRIPT データはBSTRを介して交換されます

イベントを処理するAPIを1つだけ定義する必要があります。 お好みのものを定義します。

Properties

名前 必須 Events
PluginEvent yes all
PluginDescription no all
PluginFileFilters no PACK_UNPACK, PREDIFF
PluginIsAutomatic PluginFileFilters が定義されている場合 PACK_UNPACK, PREDIFF

PluginIsAutomaticおよびPluginFileFiltersは自動モード用です:

  • PluginIsAutomaticがfalseの場合、プラグインは自動モードで使用されません。
  • PluginIsAutomaticがtrueの場合、PluginFileFiltersは両方のファイルのファイル名と比較されます。 1つのファイルがフィルターに一致する場合、プラグインが適用されます。

Methods

API Method name
EDITOR_SCRIPT 関数名は自由です
注:1つのEDITOR_SCRIPTプラグインでいくつかの関数を定義できます
BUFFER_PREDIFF PrediffBufferW
FILE_PREDIFF PrediffFile
BUFFER_PACK_UNPACK UnpackBufferA
PackBufferA
FILE_PACK_UNPACK UnpackFile
PackFile

注: PACK_UNPACK関数は追加のパラメーターを使用します。 値はUnpackBuffer時に設定できます。 ファイルが変更されると、値はPackBufferに転送されます。 目標は、UnpackBufferからPackBufferにパラメーターを渡すことです。
たとえば、プラグインはいくつかの圧縮形式を処理し、この値を使用して元の形式のファイルを再圧縮します。 このパラメーターは、関数のSyntaxに必須です。 ただし、使用しない場合は値を設定する必要はありません。

Syntax

Properties syntax

PluginEvent

C++ STDMETHODIMP CWinMergeScript::get_PluginEvent(BSTR * pVal)
VB Public Property Get PluginEvent() As String
VBS Function get_PluginEvent()

PluginDescription

C++ STDMETHODIMP CWinMergeScript::get_PluginDescription(BSTR * pVal)
VB Public Property Get PluginDescription() As String
VBS Function get_PluginDescription()

PluginFileFilters

";"で区切られたfileFiltersで構成される文字列

C++ STDMETHODIMP CWinMergeScript::get_PluginFileFilters(BSTR * pVal)
VB Public Property Get PluginFileFilters() As String

PluginIsAutomatic

C++ STDMETHODIMP CWinMergeScript::get_PluginIsAutomatic(VARIANT_BOOL * pVal)
VB Public Property Get PluginIsAutomatic() As Boolean

Methods syntax

EDITOR_SCRIPT

関数パラメーター(関数名は自由)
C++ STDMETHOD(MakeUpperVB)([in] BSTR inputText, [out, retval] BSTR * outputText);
VB Public Function MakeUpperVB(text As String)
VBS Function MakeUpperVBS(Text)

FILE_PREDIFF

関数名 関数パラメーター
C++ STDMETHOD(PrediffFile) ([in] BSTR fileSrc, [in] BSTR fileDst, VARIANT_BOOL * pbChanged, INT * pSubcode, [out, retval] VARIANT_BOOL * pbSuccess)
VB Public Function PrediffFile (BSTR fileSrc, BSTR fileDst, ByRef bChanged As Boolean, ByRef subcode As Long) As Boolean

BUFFER_PREDIFF

関数名 関数パラメーター
C++ STDMETHOD(PrediffBufferW) ([in] BSTR * pText, [in] INT * pSize, [in] VARIANT_BOOL * pbChanged, [out, retval] VARIANT_BOOL * pbHandled);
VB Public Function PrediffBufferW (ByRef text As String, ByRef size As Long, ByRef bChanged As Boolean) As Boolean

FILE_PACK_UNPACK

関数名 関数パラメーター
C++ STDMETHOD(UnpackFile) ([in] BSTR fileSrc, [in] BSTR fileDst, VARIANT_BOOL * pbChanged, INT * pSubcode, [out, retval] VARIANT_BOOL * pbSuccess)
STDMETHOD(PackFile) ([in] BSTR fileSrc, [in] BSTR fileDst, VARIANT_BOOL * pbChanged, INT pSubcode, [out, retval] VARIANT_BOOL * pbSuccess)
VB Public Function UnpackFile (BSTR fileSrc, BSTR fileDst, ByRef bChanged As Boolean, ByRef subcode As Long) As Boolean
Public Function PackFile (BSTR fileSrc, BSTR fileDst, ByRef bChanged As Boolean, subcode As Long) As Boolean

BUFFER_PACK_UNPACK

関数名 関数パラメーター
C++ STDMETHOD(UnpackBufferA) ([in] SAFEARRAY ** pBuffer, [in] INT * pSize, [in] VARIANT_BOOL * pbChanged, [in] INT * pSubcode, [out, retval] VARIANT_BOOL * pbSuccess)
STDMETHOD(PackBufferA) ([in] SAFEARRAY ** pBuffer, [in] INT * pSize, [in] VARIANT_BOOL * pbChanged, [in] INT subcode, [out, retval] VARIANT_BOOL * pbSuccess)
VB Public Function UnpackBufferA (ByRef buffer() As Byte, ByRef size As Long, ByRef bChanged As Boolean, ByRef subcode As Long) As Boolean
Public Function PackBufferA (ByRef buffer() As Byte, ByRef size As Long, ByRef bChanged As Boolean, subcode As Long) As Boolean

素早くプラグインを書くには?

最も簡単なプラグインはScriptletsです。追加のセクション<implement>があるVBscript(またはJavaScript)だけです。
例を参照してください。
ただし、デバッグは困難です。また、EDITOR_SCRIPTイベントにのみ有効です。

VC++ plugins :

スクラッチから書くのが最も難しい。
Plugins/syntax.txtを参照してください。通常のCOM dllに比べ、3つの追加手順があります。

しかし、既存のプラグインから簡単に記述できます。

  1. 同じAPIのC ++プラグインを選択する。
  2. cpp,def,dsp,idl,rcファイルの名前を変更します。[古いプラグインの名前]を[プラグインの名前]に置き換えます。
  3. すべてのファイルで、[古いプラグインの名前]のすべてのインスタンスを[プラグインの名前]に置き換えます。
  4. カスタムコードを記述します。WinMergeScript.cppにはすべての重要な機能が含まれています。
  5. 新しいGUIDを生成し、.idlファイルに追加します。

Additional steps to write a plugin in C++

  • dllを登録しないでください: '設定'-> 'カスタムビルド'のすべてを削除します。
  • dllを登録しないでください: .rgsファイルおよび.rcファイルのレジストリセクションを削除します。
  • dllを登録しないでください: typeinfoex.h +を追加し、WinMergeScript.hで3つの変更を行います(コメント行を参照)
  • SAFEARRAY:.idlのインターフェースを置き換えます:
    • SAFEARRAY * SAFEARRAY(unsigned char)
    • SAFEARRAY ** SAFEARRAY(unsigned char) *

VC++ pluginsをデバッグするには?

EDITOR_SCRIPT :

  1. Plugins.cppのsafeInvokeAの先頭にブレークポイントを設定します。
  2. WinMergeを実行する。
  3. プラグインを呼び出すために必要なすべての操作(ファイルを開く、メニュー...)を行います。
  4. ブレークポイントがトリガーされます。 プラグインインターフェイスはこの時点でロードされます。 デバッグセッションでプラグインのWinMergeScript.cppソースファイルを開きます。
  5. このファイルのあなたの関数の先頭にブレークポイントを設定します。
  6. F5を押します。関数のブレークポイントがトリガーされます

PREDIFF, PACK_UNPACK :

同じ手順、ポイント1のみが異なります。

  1. Plugins.cppのsafeInvokeWの先頭にブレークポイントを設定します。

注:safeInvokeAではなくsafeInvokeWです。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2