2011-09-18 9 views
11

私はフックといくつかのことをしようとしてきた、とフックがメッセージキューを使用しなければならない理由を私は理解していないと使用することは、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); 

ブーストスレッドを使用するとバリアが機能しません。フックとアンフックの間の待ち合わせが別のやり方でできないのはなぜですか?

EDIT:

実行するループも

(私はそれが大きな違いを作るとは思わない)、決して私はこのサンプルを作成したとき、私は、ミスをしなかった私はWH_KEYBOARD_LLフックを作成し、WH_KEYBOARDありませんGetMessage関数でのみ待機します。

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

RELATED:

C++ SetWindowsHookEx WH_KEYBOARD_LL Correct Setup

How can I set up a CBT hook on a Win32 console window?

答えて

26

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

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

低レベルのフックを好む、彼らは多くは行くのが簡単です。しかし、ポンプを作動させても機能しません。タイムアウトに注意してください。十分な応答が得られない場合、Windowsは予告なしにフックを壊します。リンクについて

Understanding the low-level mouse and keyboard hook (win32)

+0

これを正しく理解すれば、WindowsはGet/PeekMessage()コール中にしかコールバックを呼び出せません。 – Ha11owed

+2

正しく理解しています。コールをスレッドに安全に挿入する方法は他にありません。アイドル状態にする必要があります。これがメッセージループが存在する理由です。 –

+0

@HansPassantを明確にするには、WH_KEYBOARDという名前のパイプのようなグローバルフックを使って自分のプログラムに情報を渡して、そのプログラムがメッセージポンプを必要としないことを示唆していますか? – dave

4

WindowsのフックのWindowsメッセージループフック:http://msdn.microsoft.com/en-us/library/ms644959#wh_keyboardhook

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

コンソールアプリケーションでは、コンソールプロセスはメッセージ自体を増幅しません。したがって、プロセスがメッセージループを持っていなければ動作しません。

参照:

How can I set up a CBT hook on a Win32 console window?

C++ SetWindowsHookEx WH_KEYBOARD_LL Correct Setup

+0

おかげで、私はそれらのすべてをトラフ行きましたが、私はまだのGetMessageが横に待っているん理解していません。私の場合(コンソールアプリケーション)は、スレッドに終了メッセージを投稿するときに実行する唯一の時間です。 – Ha11owed

+0

また、GetMessageは待機しているので、これは、コンソールがメッセージをポンピングしてから終了するまでの間ではないことを意味していませんか? – Ha11owed

+0

Hanの答えを参照してください - Windowsはスレッドがアイドル状態であることを知っているときにのみスレッドを呼び出します。そして、スレッドがGetMesasge()でブロックされている場合、Windowsは何もしていないことを知っています。 – shf301

関連する問題