web-dev-qa-db-ja.com

SetWindowsHookExをWindowsメッセージキューで使用する必要があるのはなぜですか

フックを使っていくつかのことを試してきましたが、メッセージキューでフックを使用する必要がある理由がわかりません

_hook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
        TranslateMessage(&msg);
        DispatchMessage(&msg);
}
UnhookWindowsHookEx(hook);
_

なぜこのようなものが機能しないのですか?

_hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, 0);
cin >> aKey;
UnhookWindowsHookEx(hook);
_

ブーストスレッドを使用すると、バリアも機能しません。フックとフック解除の間の待機を別の方法で実行できないのはなぜですか?

編集:

このサンプルを作成したときに間違いを犯しました。WH_KEYBOARDではなくWH_KEYBOARD_LLフックを作成しました(大きな違いはないと思います)

また、ループは決して実行されず、GetMessage関数を待機するだけです。

ループは、終了メッセージPostThreadMessage(id, WM_QUIT, 2323, NULL);を投稿したときにのみ実行されるため、待機以外に何が行われるのかわかりません。内部処理はありますか?

関連:

C++ SetWindowsHookEx WH_KEYBOARD_LL正しいセットアップ

Win32コンソールウィンドウにCBTフックを設定するにはどうすればよいですか?

16
Ha11owed

低レベルのフック、WH_KEYBOARD_LLおよびWH_MOUSE_LLは、他のすべてのフックとは異なります。ターゲットプロセスにDLLを挿入する必要はありません。代わりに、Windowsは独自のプロセス内でフックコールバックを直接呼び出します。これを機能させるには、メッセージループが必要です。 Windowsがメインスレッドでコールバックを作成する他のメカニズムはありません。コールバックは、Windowsが制御できるようにGet/PeekMessage()を呼び出した場合にのみ発生します。

WH_KEYBOARDのようなグローバルフックは大きく異なります。 DLLが必要で、キーボードメッセージを処理するプロセス内でコールバックが発生します。独自のプログラムにこれを認識させるには、何らかのプロセス間通信が必要です。名前付きパイプが通常です。それ以外の場合はもちろん、この挿入されたプロセスがメッセージループをポンピングする必要があります。それ以外の場合はキーボードメッセージを取得しません。

低レベルのフックを優先します。それらははるかに簡単に実行できます。しかし、ポンプを使用しないと機能しません。また、タイムアウトに注意してください。十分な応答がない場合、Windowsは通知なしにフックを強制終了します。

低レベルのマウスとキーボードのフック(win32)を理解する

33
Hans Passant

WindowsフックはWindowsメッセージループをフックします: http://msdn.Microsoft.com/en-us/library/ms644959#wh_keyboardhook

WH_KEYBOARDフックを使用すると、アプリケーションは、GetMessage関数またはPeekMessage関数によって返されるWM_KEYDOWNおよびWM_KEYUPメッセージのメッセージトラフィックを監視できます。 WH_KEYBOARDフックを使用して、メッセージキューに投稿されたキーボード入力を監視できます。

コンソールアプリケーションは、メッセージ自体をポンプしません-コンソールプロセスはポンプします。したがって、プロセスにメッセージループがない限り、機能しません。

見る:

Win32コンソールウィンドウにCBTフックを設定するにはどうすればよいですか?

C++ SetWindowsHookEx WH_KEYBOARD_LL正しいセットアップ

4
shf301