おお、KanaInputにバグだ。設定ダイアログだけど。
設定ダイアログを、バックグラウンドに持っていき、隠れている間にCaps LockやらカナLockの状態を変更して、設定ダイアログを再表示させると、変更したロック状態が反映されない。何かのキーを押すか、ボタンのフォーカスを変えると直ります。
正確な再現手順は以下の通り:
- KanaInput設定ダイアログを立ち上げる。Caps LockはOFFにしておく。
- 別の画面に移る。Today 画面でOK。
- Caps LockをONにする。
- KanaInput設定ダイアログを再表示するのだが、このとき、キーボードを使用してはいけない。[スタート]→[プログラム]から jk78 KanaInput のアイコンをスタイラスで、一瞬だけタッチしてすぐ離す(笑)。
- KanaInput設定ダイアログが表示されるが、Caps Lock表示がOFFのままである。
よくもこんなバグらしいバグが残ってたねえ。でも確かにこのテストケースを考えた覚えが無い。
KanaInput設定ダイアログの状態ページは、システムが管理するCaps LockとカナLockの状態を表示する。KanaInput常駐部も独自にLock状態を管理しているが、そちらの値は使わない。システムのキーLock状態はGetKeyState()で取得する。このAPIで得られる値こそが、アプリケーションに直接影響するからである。もし万が一、システムの状態とKanaInputの状態が食い違った場合、画面を見て明らかになるからである。問題があることが判れば、KanaInputを再立ち上げするなどして、解決することができる。(実際にはKanaInput設定ダイアログ開始時に常駐部の状態とシステム状態を強制的に一致させます)
まあいいや。WM_ACTIVATEで更新すりゃ良いんでしょ。簡単だ。と思ったが甘かった。デスクトップWindowsではWM_ACTIVATEで更新すれば良いのだが、Pocket PCではWM_ACTIVATEを受け取っても、システムのキー状態テーブルが更新されていないらしく、GetKeyState()が古い値を返してしまう。バグじゃん(笑)。バグは仕様の始まり、ってことか。う~む。散々悩んだ結果、入力イベント(マウス・キーボードイベント)を受け取った時点でテーブルがアップデートされると判断。WM_ACTIVATE処理でkeybd_event()かmouse_event()を使って副作用のなさそうなイベントを投げておけば、次のWM_PAINT迄には入力イベントを処理していることでしょう。こんなんで良いのか。(追記:WM_MOUSEWHEELを送ってみたところ、PPC2003SEエミュレーターでは動きましたが、Window Mobile 5/6ではキー状態テーブルが更新されませんでした。涙)
アップデートする理由ができましたな。

