IMEと入力モードの変更
sennという名前のWindowsで動くIMEを自作しています。 sennの言語バーには入力モードを表示・切り替えるボタンがあり、このボタンをクリックするとひらがな入力と直接入力とを切り替えることができます。 この振る舞いは単純なのですが、内部実装はちょっと複雑になっているためここにメモしておきます。
sennはネットワークでつながったフロントエンドとバックエンドで構成されています。 sennの状態はすべてバックエンドで保持されており、入力モードもバックエンド側で管理してます。 フロントエンドは画面の表示のみを担当しています。
入力モードを表示・切り替えるボタンにはITfLangBarItemButtonを利用しています。 ユーザーがこのボタンをクリックすると、以下のように処理が進みます。
- Windowsが(?)フロントエンドにあるボタンの
ITfLangBarItemButton::OnClick
メソッドを実行する - フロントエンドがバックエンドに対して入力モードを切り替えるメソッド (
ToggleInputMode
) を実行する - フロントエンドがWindowsに (?) 対してアイコンアップデートメソッド (
ITfLangBarItemSink::OnUpdate(TF_LBI_ICON)
)を実行する - Windowsが(?)フロントエンドにあるボタンの
GetIcon
メソッドを実行する - ボタン (のコールバック) がバックエンドに対して現在の入力モードを問い合わせる (
GetInputMode
) - フロントエンドが入力モードに応じてアイコンを返却する
シーケンス図は次の通りです。
ITfLangBarItemButtonのアイコンを更新するにはボタン自身にGetIcon
メソッドでアイコンを返却させるという仕組みになっているようで、
外側からsetterでボタンのアイコンを指定するようなことはできなさそうでした。
この事情により、バックエンドはToggleInputMode
メソッドとGetInputMode
メソッドを提供しており、
ToggleInputMode
では更新後の入力モードを返却せず、
GetIcon
メソッド用のGetInputMode
メソッドが別途入力モードを返却するようにしています。
おわりに
ネットワーク越しに状態を更新し、参照するのは、大げさな感がありますが、面白いです。
なお、バックエンドのToggleInputMode
やGetIcon
の処理を担当しているのはstateful-imeです。