IMEの前後参照変換機能に対応するには
連続して入力しない場合でも、カーソル位置の前後にある既に入力済みの文字(単語)を参考にして文脈に合った漢字変換を提供する機能が Windows にはあります。この場では「前後参照変換機能」と呼ぶことにします。
例えば、
- 【花が】「さいた」 →[花が咲いた]
- 【布を】「さいた」 →[布を裂いた]
- 【時間を】「さいた」 →[時間を割いた]
【】の中の文字(花が、布を、時間を)を予め入力して(IMEを使わないコピー&ペーストが良い)おいてから、「さいた」とキーボードから入力して変換します。この「前後参照変換機能」が有効になっていれば、[]の中のように、それぞれ異なった変換が行われます。
秀丸エディタの ver7βで対応したようで、今話題(?)の機能ですが、Google検索ではヒットしなかったので、実装方法について調べてみました。次の通りです。
- ウインドウプロシージャで、(uMsg, wParam) = (WM_IME_REQUEST, IMR_DOCUMENTFEED) のメッセージが来た時に、構造体 RECONVERTSTRING と 文字列の長さ分のバイト数を返す
- その後にIMEは反応して、返したバイト数分のデータを格納できるバッファポインタを lParam に入れて再度 (WM_IME_REQUEST,IMR_DOCUMENTFEED) のメッセージを投げてくるので、そのバッファに対して必要なデータを格納して返す
文字列は、いわゆる段落1つ分(つまり改行から改行までの)文字列で良いようです。
#include <imm.h> LRESULT wndsubproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_IME_REQUEST) { if (wParam == IMR_DOCUMENTFEED) { if (lParam != 0) { //lParam != 0 の時(2回目の呼び出し)は //lParam を RECONVERTSTRING と 文字列格納バッファに使用する RECONVERTSTRING *pReconv = (RECONVERTSTRING*)lParam; char* pszParagraph = (char*)pReconv + sizeof(RECONVERTSTRING); pReconv->dwSize = sizeof(RECONVERTSTRING); pReconv->dwVersion = 0; pReconv->dwStrLen = <文字列の長さ> ; pReconv->dwStrOffset = sizeof(RECONVERTSTRING); pReconv->dwCompStrLen = 0; pReconv->dwCompStrOffset = 0; pReconv->dwTargetStrLen = 0; pReconv->dwTargetStrOffset = <文字列の先頭からのカーソル位置> ; strcpy(pszParagraph, <文字列の元のバッファ>, <文字列の長さ>); } //lParam == 0 の時(1回目の呼び出し)は、バッファのサイズを返すだけ。 //lParam が、0でも!0でも指定する返値は同じ return sizeof(RECONVERTSTRING) + <文字列の長さ> ; } } //それ以外のメッセージは、本来のウインドウプロシージャを実行する return CallWindowProc((WNDPROC)Org_WndProc, hwnd, uMsg, wParam, lParam); }