グローバルキーフック(Win32 API C++)

色々とメモメモ

アプリケーションが非アクティブでも受け付けるホットキーを実装しようと思った時、手軽なのがWindowsAPIのRegisterHotKey()関数だけど、同一のキーを複数のアプリケーションで使用することはできない。
どんな状況でも確実にキー入力を監視したい、となったらグローバルフックを使うしか無い。

キー入力(WM_KEYDOWNメッセージ)を引っ掛けるには、SetWindowsHookEx関数でフックタイプにWH_KEYBOARDを指定してあげればいいみたい。しかしこの関数、関数を呼び出したプロセスに飛んだメッセージしかフックしてくれない。これではグローバルホットキーにならない。
システムグローバルなフックを実現するには、DLLでSetWindowsHookEx関数を呼び出し、フックプロシージャの処理もDLL内に記述する必要がある。このDLLはすべてのプロセスの仮想アドレス空間にマッピングされ、フックプロシージャ内の処理を行うことを可能にする。

以下は、keyhook.dllを動的リンクしたhoge.exeがdll内のSetWindowHookEx関数(フックタイプWH_KEYBOARD)を呼び出し、メモ帳(notepad.exe)に送られたWM_KEYDOWNメッセージを横取りするイメージ図。いろいろと間違ってるかも。

20140729_keyhook.png

続きを読む »