2011-07-23 30 views
0

キーボードメッセージにフックをかけようとしています。SetWindowsHookExを使用してキーボードメッセージをフックする際の問題

extern __declspec(dllexport) LRESULT CALLBACK HookProc(
    int nCode, 
    WPARAM wParam, 
    LPARAM lParam 
) 
{ 
    // process event 
    //... 
    MessageBox(NULL, 
       TEXT("OK"), 
       TEXT("OK"), 
       MB_OK); 

    return CallNextHookEx(NULL, nCode, wParam, lParam); 
} 

すべてがうまくコンパイルが、私はしようとしているとき:私もHookProc機能を備えたテストのWin32 DLLを作成しました

int _tmain(int argc, _TCHAR* argv[]) 
{ 
HOOKPROC hHookProc; 
HINSTANCE hinstDLL; 
HHOOK hHook; 

hinstDLL = LoadLibrary(TEXT("pathtodll\\KeyHook.dll")); 
hHookProc= (HOOKPROC)GetProcAddress(hinstDLL, "HookProc"); 

hHook = SetWindowsHookEx( 
    WH_KEYBOARD, 
    hHookProc, 
    hinstDLL, 
    0); 

    while (1) {} 

return 0; 
} 

は、私がテストコンソールのWin32アプリケーションを作成しますデバッグ、HookProcが呼び出されることはないようです。実際には勝利7では、私は任意のキーを押すとアプリケーションがハングしますが、Win XPではHookProcは呼び出されません。私はNULL hinstDLL、hHookProc、hHookを取得しません。

私は何を見逃していますか?

答えて

1

SetWindowsHookEx()を呼び出した後でループを空白で実行する代わりに、Peek/GetMessage()を経由して、呼び出し側のスレッドのメッセージキューをループポンプで処理してみてください。いくつかのフックはそれらをインストールするスレッドのコンテキストで実行されるため、OSは必要に応じてそのスレッドに切り替えることができなければなりません。ここでの問題の

+0

それは働いていた:しかし、私は完全に理解できない理由:( – Blim

+0

私は言ったように、いくつかのフックは、それらをインストールするスレッドのコンテキストで実行されます。コンテキストでは、OSはスレッドのメッセージキューを使用するため、スレッドは新しいメッセージのために定期的にメッセージキューをポンピングしてフックを実行する必要があります。 –

+0

問題はGetMessage()が返さないことですが、私はこれらのすべてのものを説明するいくつかのドキュメントを見つけることを試みているが、特定のものを見つけることができず、メッセージキューの必要性に関する何かがフックに関するmsdnドキュメンテーションの一部に記載されていない。 – Blim

0

カップル:

while (1) {} 

はこれをしないでください:あなたのコードは今効果的にアプリが応答しなくなります忙しい(無限)ループがある(そしておそらく全体のデスクトップを作成し、あまりにも低迷ように見えます) 。 GetMessageがここで動作する理由は、制御をOSに戻し、スレッドを忙しく実行するのではなくスリープ状態にするためです。 Sleep(...)を呼び出すだけで同じ効果が得られますが、OSに制御を戻しますが、メッセージをポンピングすることはありません。テストコードの場合、getchar()のようなものはここでうまくいく可能性があります。コンソールウィンドウでEnterキーを押すまで正常にブロックされます。 MessageBox()もここで動作します。

extern __declspec(dllexport) LRESULT CALLBACK HookProc(
{ 
    MessageBox(NULL, 
      TEXT("OK"), 
      TEXT("OK"), 
      MB_OK); 

もう一つの問題:あなたは、一般的にフックコールバックで「複雑な」何かをしたいことはありません - ちょうどメッセージを処理するための最低限の操作を行い、そしてできるだけ早く返します。あなたは確かにブロックすることを望んでいない、これはMessageBoxの機能です。デバッグの目的で、OutputDebugString()やその他のデバッグ指向のAPIがブロックされないようにしてください。

関連する問題