CEでキーフック

ちょっとPDA(Windows CE)の事で質問を受けたので、CEプログラミングのネタです(・∀・)


Windows Mobileを使って業務アプリケーションを作成する場合、専用アプリケーションにしたいという要求がよくあります。
専用アプリケーションというのは、業務アプリケーション以外のアプリケーションの実行を禁止するということです。
このために、全画面表示&アプリケーションボタンの無効化を行います。


アプリケーションボタンの無効化については、RegisterHotKey()でボタンを登録して無効化する方法もありますが、ボタンに割り当てられているアプリケーションによってはこれではダメな場合があります。
#あらかじめ変更しておけば良いんですけど


こういった理由や、ちょっと変わったことも出来るように、自分はもっと強力な方法でボタンの制御を行っています。
その方法は、SetWindowsHookExW()によるローレベルキーフックです。


SDK中にはフック関連の定義が用意されていないため、Windows CEではフックが出来ないと思われていますが、core.dllにはちゃんとAPIがあったりします。
#こういう情報は、Platform Builderを弄っているような本職の人が詳しいんでしょうけど


っというわけで、APIの定義さえ行えばフックを利用できます。
定義はこんな感じです。

#define WH_KEYBOARD_LL      20

#define HC_ACTION           0

typedef struct tagKBDLLHOOKSTRUCT {
    DWORD   vkCode;
    DWORD   scanCode;
    DWORD   flags;
    DWORD   time;
    DWORD   dwExtraInfo;
} KBDLLHOOKSTRUCT, FAR *LPKBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;

typedef LRESULT (CALLBACK* HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);

extern "C"
{
    HHOOK WINAPI SetWindowsHookExW(int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId);
    BOOL WINAPI UnhookWindowsHookEx(HHOOK hhk);
    LRESULT WINAPI CallNextHookEx(HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam);
}

1つポイントは、WH_KEYBOARD_LLの値が普通のWindowsと違って20だということです。
これに気がつかずに、Windows CEではフックができないと思うケースもあるかと思います。


あと、フックできる処理も普通のWindowsとは違ってWH_KEYBOARD_LLと他少々です。
WH_CBTが使えたりすると面白いんですけどね(´・ω・`)


なお、自分がこれまで触ってきたPocketPC/CE機では全ての機種でフックが行えましたが、フックでイベントを拾えないボタンを持った機種もありました。
デンソーウェーブ製のハンディターミナルでは、トリガーキー、マジックキーのイベントは拾えませんでした。
また、未確認ですがW-ZERO3の通話関連のボタンもフックできないようです。


Windows Mobile 5.0/Visual Studio 2005になってからはCEプログラミングをほとんどやっていないので、間違っている情報があったらごめんなさい。


今まで作ってきたCE用ライブラリも、Visual Studio 2005でとりあえずビルドは通るようにしたけど、未検証だったりして(´ω`)