WindowsのIMEとのAPIにはいくつかの実装があるのですが、今回は古のWIndows 2000以降ならフルで使えるInput Metod Managerについてです。
非常に優秀なIMEのAPIで、未確定文字列の描画をアプリケーション側で行わない場合には、それを肩代わりしてくれます。
また、変換候補についても自身で表示するかIME側に表示してもらうかを選択できます(たぶん)。
Input Metod Manager概要
アプリケーション側でやることは主に2つです
- IMEに自身の情報を伝える
- IME関連のウィンドウメッセージを処理する
これだけです。
以降は、縦書きエディタで最低限実装するべきことについてざっくりとリストアップします。
共通
IME関連の処理をする際には
HIMC hImc = ImmGetContext(hWnd);
-
hImc
を使って色々やる ImmReleaseContext(hWnd, hImc);
の順序になります。
IMEに自身の情報を伝える
使用するフォントをIMEに伝える
縦書きにおいてはこれが何よりも重要なことになります。
これをすることで、IMEはアプリケーション側で文字列が縦書きになっているということを知ることができます。
-
LOGFONT logfont;
に適切なフォントデータを突っ込む-
logfont.lfEscapement = 2700;
する- 書字方向が上から下
-
logfont.lfOrientation = 2700;
する- 文字を反時計回りに270.0度回す
-
logfont.lfFaceName
のフォント名の先頭には@
を付与する- 縦書き用の字形を使う
-
-
ImmSetCompositionFont(hImc, &logfont);
する
変換候補の位置を教える
IME関連のウィンドウメッセージを処理する
WM_IME_SETCONTEXT
-
lParam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
- もし未確定文字列を自分で描画する場合
return DefWindowProc(hWnd, message, wParam, lParam);
WM_IME_STARTCOMPOSITION
これから未確定文字列がやってくるという予告。
WM_IME_COMPOSITION
- 未確定文字列がやってきたとき
- 未確定文字列に変更があったとき
- 未確定文字列が確定されたとき
以上の3つのときに呼ばれ、アプリケーション側はIMEから未確定文字列や確定された文字列が取得できます。
未確定文字列の取得は少し面倒ですが、時間がないので省略です(すみません)。
WM_IME_ENDCOMPOSITION
もう未確定文字列は無くなったという報告。
WM_IME_NOTIFY
, WM_IME_REQUEST
IMEからの通知です。
ImmSetCandidateWindow(hImc, &form)
で変換候補ウィンドウの位置を教えるなどしましょう。
おわりに
非常に使いやすいAPIで上のことをやれば動くと思います。
さて、明日は地獄のTSF(Text Services Framework)です。
ちなみにTATEditorではTSFのサポートを切って、IMMを使用することもできます。
特にメリットはありませんが、編集中のテキストへIME側からアクセスされなくなります。
参考:
https://msdn.microsoft.com/library/windows/desktop/dd318641.aspx