1

ウィンドウをサブクラス化せずに特定のウィンドウ メッセージをフックする方法はありますか。

WH_GETMESSAGE がありますが、パフォーマンスの問題が発生しているようです。

これら以外に、パフォーマンスを低下させないソリューションはありますか?

4

1 に答える 1

3

AFAIKあなたが言ったことよりも良い解決策はありません。そしてもちろん、ウィンドウのサブクラス化は、スレッドのすべてのメッセージをフックするよりも優れています。

メッセージがウィンドウによって処理されるまでに通過するパスを考えてみましょう。

  1. PostMessageメッセージは、 /への明示的な呼び出しSendMessageまたはOSによる暗黙的な呼び出しのいずれかによって、ウィンドウに投稿または送信されます。
  2. 投稿されたメッセージのみ:最終的に、スレッドはこのメッセージをメッセージキューからポップし(呼び出しGetMessageまたは同様の方法で)、次にを呼び出しますDispatchMessage
  3. OSは、を呼び出すCallWindowProc(または同様の)ことによってウィンドウのプロシージャを呼び出します。
  4. CallWindowProc、ウィンドウに関連付けられているウィンドウ手順を識別します(GetClassLong/を介してGetWindowLong
  5. 上記の手順を呼び出します。

サブクラス化-ターゲットウィンドウのウィンドウプロシージャを置き換えることを意味します。これは最良の変種のようです。フラグ付きのフックをインストールWH_GETMESSAGEすると、メッセージキューに投稿されたすべてのメッセージが監視されます。これは次の理由で悪いです:

  1. パフォーマンス上の理由。
  2. 特定のスレッドで作成されたウィンドウについてのみ通知が届きます
  3. 投稿されたメッセージについてのみ通知が届きます(送信されたメッセージは表示されません)
  4. 「投稿された」メッセージは、必ずしも「配信された」という意味ではありません。つまり、メッセージループによってフィルタリングされる可能性があります(を呼び出さずに破棄されますDispatchMessage)。
  5. 実際のウィンドウが何をして、そのメッセージに対して返されるかを確認することはできません。

そのため、サブクラス化ははるかに優れているようです。

もう1つの解決策-特定のメッセージが(送信されるのではなく)投稿された場​​合、メッセージループをオーバーライドし、取得されたメッセージごとに前処理/後処理を行うことができます

于 2010-05-06T13:34:06.217 に答える