0

いくつかの Application.Idle ハンドラーを使用してフォーム上のコントロールのステータスを変更する Windows フォーム アプリケーションがあります。

ListView をフォームに追加した後、マウス カーソルが ListView の上にあるときに Idle-Handlers が頻繁に呼び出されることに気付きました。Spy++ を使用すると、マウス カーソルがコントロール上にある (動かない) ときに、コントロールが WM_MOUSEHOVER メッセージを受け取り、それがアイドル イベントをトリガーすることがわかりました (メッセージ キューが空になった後)。同じことが TreeView-Controls にも当てはまります。

どうすればこの動作を無効にできますか?

コマンド プロンプトからこのコードを実行すると、意味が表示されます。

using System;
using System.Windows.Forms;

public class IdleTest {

    public static void Main() {

        Application.Idle += delegate {
           Console.WriteLine( 
                DateTime.Now.ToString() + " idle!" ) ;
        };

        Form f = new Form(){ Width=300 };
        f.Controls.Add(new ListView(){ Left=0,   Width=100 } );
        f.Controls.Add(new TreeView(){ Left=100, Width=100 } );
        f.Controls.Add(new TextBox() { Left=200, Width=100 } );

        Application.Run(f) ;
    }
}
4

1 に答える 1

1

フォームで WndProc メソッドを試してオーバーライドすることができます。次に、カーソル位置を使用して、WM_MOUSEHOVER メッセージを処理する場合と処理しない場合にフィルター処理します。

このようなもの:

public partial class MyForm: Form
{
    private const int WM_MOUSEHOVER = 0x02A1; 

    protected override void WndProc(ref Message message)
    { 
        Point mousePosition = this.PointToClient(Cursor.Position);

        if ((message.Msg == WM_MOUSEHOVER) && (<useTheMousePositionToDoSomeFiltering>))
        {
            return;
        }
        base.WndProc(ref message);
    }    
}

編集: とはいえ、カスタムの ListView と TreeView を (組み込みの .NET のものを派生させるだけで) 作成し、新しいコントロールで WndProc ルーチンをオーバーライドして、常に WM_MOUSEHOVER を除外する方がよい場合があります。

于 2010-03-25T09:57:56.783 に答える