1

次のようなグローバルマウスフック関数をインストールしました。

mouseEventHook = ::SetWindowsHookEx( WH_MOUSE_LL, mouseEventHookFn, thisModule, 0 );

フック関数は次のようになります。

RESULT CALLBACK mouseEventHookFn( int code, WPARAM wParam, LPARAM lParam )
{
    if ( code == HC_ACTION ) {
        PMSLLHOOKSTRUCT mi = (PMSLLHOOKSTRUCT)lParam;
        // .. do interesting stuff ..
    }
    return ::CallNextHookEx( mouseEventHook, code, wParam, lParam );
}

さて、私の問題は、「面白いことをする」部分にかかる時間を正確に制御できないことです。特に、Windowsレジストリで定義されているLowLevelHooksTimeoutよりも時間がかかる場合があります。これは、少なくともWindows XPでは、システムがマウスイベントをフック機能に配信しなくなったことを意味します。これを避けたいのですが、同時に、ターゲットGUIがイベントを受信する前に、「面白いことをする」部分を実行する必要があります。

mouseEventHookFn上記がワーカースレッドにメッセージを投稿してすぐに実行できるように、別のスレッドで「興味深いもの」の作業を行うことでこれを解決しようとしましたreturn 1;(これによりフック機能は終了しますが、イベントがGUIに渡されることはありません) )。アイデアは、ワーカースレッドが終了すると、CallNextHookEx呼び出し自体を実行するというものでした。

ただし、これにより内部でCallNextHookExクラッシュが発生します(実際、クラッシュはという内部関数の内部で発生します。フック関数の外部PhkNextValidから呼び出すのは安全ではないと思いますが、これは本当ですか?CallNextHookEx

もしそうなら、GUIがイベントを受信する前にコード(アプリケーションのGUIスレッドと対話する必要がある)を実行し、フック関数が長時間ブロックされないようにする方法を他の誰かが知っていますか?

4

3 に答える 3

1

なぜマウス イベント フックを使用しているのですか? マウスを一般的にフックしていますか、それとも特定のウィンドウだけにフックしていますか? 特定のウィンドウ用の場合は、フックを使用する代わりに、実際にターゲット ウィンドウをサブクラス化する必要があります。

これは通常 2 段階のプロセスです。実際にメッセージを処理するプロセス (およびスレッド) のコンテキストでフックを実行する必要があるため、フックは常に dll 内にある必要があります。

したがって、メッセージが送信されると、HWND で SetWindowLong を呼び出して GWL_WINDOWPROC を新しいウィンドウ プロシージャに置き換えるフック dll を作成することから始めます。

WindowProc では、メッセージを処理するのに必要なだけ時間がかかります。

于 2010-05-26T22:44:50.513 に答える
1

フック関数の外から CallNextHookEx を呼び出すのは安全ではないと思いますが、これは本当ですか?

これは本当だと思います。

低レベルのマウス フックを介して受け取ることができる操作の数には限りがあるため、実行時間の長い操作が終了したら、それらをキューに入れ、受信ウィンドウに再ポストすることができます。長期実行を別のスレッドに置くと、UI を「ロック」するのではなく、単にユーザー アクションを「食べる」または「延期」します。他のフックが発生しないようにするには、1 を返します。ブール値フラグを使用して、イベントを収集するか (長時間実行される操作をまだ実行する必要があるため)、イベントを再投稿するか (したがって、それらをフックしてはなりません) を示します。

キャンセルしようとしている他の低レベルのフックがシステムに (m) 存在する可能性はほとんどありませんが、状況に応じてこのメカニズムを徹底的にテストする必要があります。操作を延期するのではなく、前に操作をブロックする(マウスの右クリックを殺す)ためだけに使用しました。

于 2010-05-26T23:44:02.713 に答える
1

コードを高速化する必要があります。これらのフックは、ユーザー インターフェイスの応答性に非常に悪影響を及ぼす可能性があります。タイムアウトが構成可能であったとしても、文書化されることはありません。それは、そもそもタイムアウトを設定するという目的を無効にします。

于 2010-05-26T14:23:13.287 に答える