4

を使用してメッセージフィルターを登録しました

Application.AddMessageFilter(m_messageFilter);

これを使用して、ユーザーがアプリケーションのユーザー インターフェイスで行ったすべてのマウス クリックをログに記録できます。

ただし、次のようなコードを使用して、1 つのダイアログが別のスレッドで実行されます。

void Run()
{
    using( MyDialog dialog = new MyDialog() )
    {
        dialog.ShowDialog();
    }
}

Thread thread = new Thread(Run);

私が設定したメッセージ フィルタは、このウィンドウに送られるメッセージを表示しません。どうすればそれらを入手できますか (理想的にはあまり邪魔にならないように)。

MyDialog.PreProcessMessage をオーバーライドしようとしましたが、これが呼び出されないようで混乱しています。

ありがとう。

4

3 に答える 3

3

AddMessageFilter を含むほとんどすべてのアプリケーション メソッドは、スレッド固有です。したがって、他のスレッドでメッセージをフィルタリングする場合は、そのスレッドで AddMessageFilter を呼び出す必要があります。

Run メソッドを次のように変更するだけです。

void Run()
{
    using( MyDialog dialog = new MyDialog() )
    {
        Application.AddMessageFilter(new MyMessageFilter());
        Application.Run(dialog); 
    }
}
于 2009-07-31T17:58:54.867 に答える
1

刺すだけですが、 volatileキーワードを活用できる場合があります。これは、volatile bool を使用して異なるスレッドのプロセス間の状態をチェックする例です。

おそらく、その方法論をニーズに合わせて適応させることができます。メッセージが2番目のダイアログに出くわしたかどうかに応じて反転します

{編集} PreProcessMessage に関しては、マウスではなくキーボード入力のみであると思います。これらのイベントを取得するには、おそらく WndProc をオーバーライドする必要があります。これが、オーバーライドされた PreProcessMessage が起動しない理由である可能性が最も高いです。

幸運を!

于 2009-07-28T17:02:02.890 に答える
1

次のようにコードを書き直す必要があると思います

void Run()
{
    using( MyDialog dialog = new MyDialog() )
    {
        Application.Run();
        dialog.ShowDialog();
    }
}

または多分

Application.Run(dialog);

内部で { ... } を使用しても機能します

Application.Run() は、現在のスレッドで標準アプリケーション メッセージ ループの実行を開始します。通常、メッセージ ループはメイン スレッドでのみ機能します。Application.Run() がないと、標準メッセージ ループは 2 番目のスレッドで開始されません。

同様の手法が使用された別のスレッドでスプラッシュ スクリーン フォームを作成するという記事があります。この2番目のスレッドで。

この記事からわかるように、異なるスレッドでフォームを実行するには、開発者がフォームを閉じたり破棄したりする方法について非常に注意する必要があります。

于 2009-07-31T16:17:14.183 に答える