キーボードの状態取得

キーボードの状態を取得すると言えばGetKeyboardStateなんだけど,コマンドプロンプトから実行するといろいろやっても起動時の状態しか取得できない.pygameでウィンドウを作ってやってみると,アクティブになっているときは状態を取得できているが非アクティブになると取得できない.おかしいと思ってリファレンスを見てみると,またしてもスレッドとメッセージキューの話だったorz

アプリケーションはこの関数を呼び出して、すべての仮想キーの現在の状態を一度に取得できます。スレッドがメッセージキューからキーボードメッセージを削除すると、仮想キーの状態が変化します。キーボードメッセージがスレッドのメッセージキューにポストされたり、他のスレッドのメッセージキューへのキーボードメッセージのポストや削除が発生しても、状態は変化しません。

他のスレッド(他のウィンドウ)がアクティブになっているときはメッセージが現在のスレッドに来ないため仮想キーの状態が変化しなかったというのが原因らしい.

非アクティブでもキーの状態を取得するにはグローバルフックやGetAsyncKeyStateを使う方法があるが,Pythonから手軽に使えるGetAsyncKeyStateの方を使うことにした.問題としては,GetKeyboardStateは一回呼び出すだけで256個の仮想キーの状態を取得できるけど,GetAsyncKeyStateだと256回関数を呼び出さないといけないので遅くなる可能性があること.

実際に時間を測ってみるとこんな感じ.どちらにしろ一回当たりには1ミリ秒もかかっていないので気にしないことにする.

GetKeyboardState       * 1000 : 0.0988119300079(sec)
GetAsyncKeyState * 256 * 1000 : 0.451285568417(sec)
(Intel Core2 T7200 2.0GHz)