◆フックの種類
・ローカルフック
自分のプロセスに属するスレッドのメッセージを監視
・グローバルフック(別名:システムフック or リモートフック)
別プロセスに属するスレッドのメッセージを監視
システム上の全てのスレッドのメッセージを監視
DLLにて提供しなければならない
◆実装の流れ
1.SetWindowsHookEx
(フックタイプ、フックプロシージャ、監視スレッド指定)
2.フックプロシージャ
(メッセージ取得、加工)
3.UnhookWindowsHookEx
(フック解除)
◆各関数の概要
1.SetWindowsHookEx
HHOOK SetWindowsHookEx(
int idHook, // フックタイプ
HOOKPROC lpfn, // フックプロシージャ
HINSTANCE hMod, // アプリケーションインスタンスのハンドル
DWORD dwThreadId // スレッドの識別子
);
戻り値:
成功:フックプロシージャのハンドル
失敗:NULL
第1引数:idHook -> フックタイプを指定
・WH_GETMESSAGE // PostMessage監視
・WH_CALLWNDPROC // SendMessage監視
・WH_MOUSE // マウスメッセージ監視
・WH_KEYBOARD // キーボードメッセージ監視
第2引数:lpfn -> フックプロシージャアドレス指定
第3引数:hMod -> インスタンスのハンドル指定
第4引数:dwThreadId -> 監視するスレッドID指定(0なら全スレッド)
2.フックプロシージャ
SetWindowsHookExのフックタイプ指定によって
渡されるメッセージが変わる
WH_GETMESSAGEの場合
LRESULT CALLBACK GetMsgProc(
int code, // フックコード
WPARAM wParam, // 削除オプション
LPARAM lParam // メッセージ
);
・codeが0未満の場合、メッセージを処理せずCallNextHookExに渡し
この関数の戻り値を返す
・lParamをLPMSGにてキャストし、各メッセージの値を取り出す
WH_KEYBOARDの場合
LRESULT CALLBACK KeyboardProc(
int code, // フックコード
WPARAM wParam, // 仮想キーコード
LPARAM lParam // キーストロークメッセージの情報
);
・codeが0未満の場合、メッセージを処理せずCallNextHookExに渡し
この関数の戻り値を返す
・wParamでキーを特定。
(lParam & 0x80000000)==0の場合,Keyが押されている(KeyDown)状態
(lParam & 0x80000000)==1の場合,Keyが離されている(KeyUp)状態
3.UnhookWindowsHookEx
BOOL UnhookWindowsHookEx(
HHOOK hhk // 削除対象のフックプロシージャのハンドル
);
・hhkには、SetWindowsHookEx関数の戻り値であるフックハンドルを指定
◆留意点
・Unhookする場合に必要となるフックプロシージャのハンドルは
共有メモリへ記憶させ、必ず初期化する。
例(vc):
#pragma data_seg("shared")
HHOOK g_hhk = NULL; // フックハンドル
#pragma data_seg()
#pragma comment(linker, "/section:shared,rws")
CallNextHookEx関数の第一引数はNULLでも問題無し。
つまり、フックハンドルはわざわざ共有セグメントに置かなくても
コードの書き方によっては問題ないらしい。