English help on website



変換モジュール(DLL版)作成方法(.hmf/.hmf64)(Ver9.35対応版)
目次変換モジュール− 変換モジュール(DLL版)作成方法(.hmf/.hmf64)
この説明は、変換モジュール作成キットにある説明の抜粋です。

変換モジュール開発キットの説明

■1.変換モジュールの概要

 変換モジュールは、秀丸エディタV5.00以降からサポートされた機能で、各種の変換処理を変換モジュールという形で実現して、それを秀丸エディタに組み込めるようにする仕組みです。

 変換モジュールは、範囲選択した内容をそのまま受け取って、それを変換して返すというただそれだの仕組みですが、必ずしも変換を実行しなくてもいいです。例えば範囲選択した中の単語の数を数えてメッセージ表示したりってことでもかまいません。


■2.変換モジュールの呼び出しインタフェース

 変換モジュールは、いわゆるDLLの形式になってないとダメですが、ファイルの拡張子は「.hmf」という風にしてもらう必要があります。
 64bit版のDLLの場合の拡張子は「.hmf64」とする必要があります。

 変換モジュールは、変換用の関数をエクスポートしつつ、それらの関数アドレスのテーブルをEnumHidemaruFilterという関数にて返してやる必要があります。さらに、HidemaruFilterGetVersionという関数にて、変換モジュールのバージョンを返すように作ってください。

 EnumHidemaruFilter関数の返すテーブルは、HIDEMARUFILTERINFOという構造体になっている必要があります。
 EnumHidemaruFilter関数の返すテーブルに、変換する関数のアドレスを格納します。


■3.変換関数

 変換する関数は、HIDEMARUFILTERFUNC型に合うような、以下のような関数になります。

  HGLOBAL _cdecl Test( HWND hwndHidemaru, WCHAR* pwszIn, char* pszParam, int cbParamBuffer ) {
    ...
  }

 hwndHidemaruは、呼び出し元の秀丸エディタのウィンドウハンドルです。
 入力専用です。
 
 pwszInは、選択されているテキストです。NULL文字終端の単一のテキストです。
 入力専用です。
 複数選択の場合は、関数が複数回が呼ばれます。
 マクロの場合は互換性の配慮から、通常は単一選択相当で一回しか呼ばれません。
 マクロで複数選択に対応するには、setcompatiblemode 0x100000;としておくと複数回呼ばれます。
 
 pszParamは、変換モジュール側で自由に決めることができるパラメータです。
 入力と出力の両方に使います。
 変換メニューから実行した場合は、出力のために使います。文字数ゼロの文字列を指すポインタになっています。キー操作の記録中に変換メニューから実行した場合に、どのような変換を行ったかなどの任意の情報を文字列にして返すことができます。
 キー操作の再生時は、入力のために使います。記録されたときの文字列がpszParamに格納されて再び呼び出され、同じことを再生できるように使うことができます。
 マクロのfilter文(またはfilter関数)では、入力のために使います。マクロが指定する自由なパラメータです。

 cbParamBufferは、pszParamの指すバッファサイズの上限です。
 入力専用です。

 返り値は、HGLOBALのメモリハンドルです。
 GlobalAllocでメモリ確保されたハンドルで、解放は秀丸エディタ側で行います。
 NULLを返すと何も変換をしません。
 複数選択の場合、NULLを返すとそこで変換は中断されます。

 関数の実際の使い方の例は、付属のHmFilter.hファイルおよびサンプルプログラムを参照ください。


■4.秀丸エディタの呼び出し

 変換モジュールから秀丸エディタの各種情報を取得するためのインタフェースがあります。
 DLL側から呼び出せる秀丸エディタの関数と、情報取得のメッセージがあります。
 それぞれ、秀丸エディタのマクロヘルプを参照してください。


■5.HIDEMARUFILTERINFO構造体の説明

    UINT                cbStructSize;          構造体のサイズをここに入れる必要があります。
    const char*         pszExportName;         関数名をここに入れます。
    const char*         pszNameJapan;          日本語版秀丸エディタでメニューに表示する文字列を指定します。
    const char*         pszNameUs;             英語語版秀丸エディタでメニューに表示する文字列を指定します。
    BYTE                chAccel;               メニュー上のアクセラレータキーを指定します。
    BYTE                fMustLineUnit;         行単位で範囲選択されてないと実行できないフラグ指定。
    BYTE                bReserve;              //リザーブ領域なので、現在の所0を入れておく必要があります。
    BYTE                bFlags;                //改行コードの渡し方をFILTERFLAG_*で指定します。

bFlagsに指定する改行コードの渡し方は以下の通りです。
FILTERFLAG_RETURN_CRLF      改行コードをCR+LFに統一して渡します。
FILTERFLAG_RETURN_LFONLY    改行コードをLFに統一して渡します。
FILTERFLAG_RETURN_RAW_CR_LF 改行コードを統一せずそのまま渡します。




//HmFilter.h
typedef HGLOBAL (_cdecl* HIDEMARUFILTERFUNC)( HWND hwndHidemaru, WCHAR* pwszIn, char* pszParam, int cbParamBuffer );

struct HIDEMARUFILTERINFO {
    UINT                cbStructSize;
    const char*         pszExportName;
    const char*         pszNameJapan;
    const char*         pszNameUs;
    BYTE                chAccel;        // アクセラレータキー
    BYTE                fMustLineUnit;  // 行単位でないと実行できないフラグ
    BYTE                bReserve;
    BYTE                bFlags;         // FILTERFLAG_*
};

#define FILTERFLAG_RETURN_MASK		0x03
#define FILTERFLAG_RETURN_CRLF		0x00	//
#define FILTERFLAG_RETURN_LFONLY	0x01	//FILTERFLAG_LFONLYと同じ
#define FILTERFLAG_RETURN_RESERVED	0x02	//未使用
#define FILTERFLAG_RETURN_RAW_CR_LF	0x03	//改行コードの区別をそのまま渡す(V8.89β16以降)

#define FILTERFLAG_LFONLY			0x01	//改行を0x0Aだけにする(V8.85β3以降)//FILTERFLAG_RETURN_LFONLYと同じ

// extern "C" HIDEMARUFILTERINFO* _cdecl EnumHidemaruFilter();
// extern "C" DWORD _cdecl HidemaruFilterGetVersion();




//test.cpp
#include <windows.h>
#include <string>
#include "HmFilter.h"

HINSTANCE	hInstance;

extern "C" __declspec( dllexport )
HGLOBAL _cdecl SampleFilter1( HWND hwndHidemaru, const WCHAR* pwszIn, char* pszParam, int cbParamBuffer ) {
	std::wstring wstr;
	wstr = L"[";
	wstr += pwszIn;
	wstr += L"]";
	size_t cb = (wstr.size() + 1) * sizeof(WCHAR);
	HGLOBAL hGlobal = GlobalAlloc( GMEM_MOVEABLE, cb );
	WCHAR* pwszOut = (WCHAR*)GlobalLock( hGlobal );
	memcpy( pwszOut, wstr.c_str(), cb );
	GlobalUnlock( hGlobal );
	return hGlobal;
}

extern "C" __declspec( dllexport )
HGLOBAL _cdecl SampleFilter2( HWND hwndHidemaru, const WCHAR* pwszIn, char* pszParam, int cbParamBuffer ) {
	std::wstring wstr = pwszIn;
	wstr = L"(";
	wstr += pwszIn;
	wstr += L")";
	size_t cb = (wstr.size() + 1) * sizeof(WCHAR);
	HGLOBAL hGlobal = GlobalAlloc( GMEM_MOVEABLE, cb );
	WCHAR* pwszOut = (WCHAR*)GlobalLock( hGlobal );
	memcpy( pwszOut, wstr.c_str(), cb );
	GlobalUnlock( hGlobal );
	return hGlobal;
}

struct HIDEMARUFILTERINFO aFilterInfo[3] = {
	{ sizeof(HIDEMARUFILTERINFO), "SampleFilter1", "サンプル1", "Sample1", 'A', 0, 0, 0 },
	{ sizeof(HIDEMARUFILTERINFO), "SampleFilter2", "サンプル2", "Sample2", 'A', 0, 0, 0 },
	{ 0, NULL, NULL, NULL, NULL, 0, 0, 0 }
};

extern "C" __declspec( dllexport )
HIDEMARUFILTERINFO* _cdecl EnumHidemaruFilter() {
	return aFilterInfo;
}

extern "C" __declspec( dllexport )
DWORD _cdecl HidemaruFilterGetVersion() {
	return (1 << 16) + (2 * 10) + 3;		// 1.23
}

BOOL WINAPI DllMain( HINSTANCE hInstIn, DWORD fdwReason, LPVOID lpvReserved ) {
	return TRUE;
}