views:

21

answers:

1

I have a Windows Forms application that uses some Application.Idle handlers to change the status of controls on the form.

After I added a ListView to the form I realized the Idle-Handlers get called way too often when the mouse cursor is over the ListView. By using Spy++ I saw that when the mouse cursor is over the control (not moving) the control receives WM_MOUSEHOVER messages over an over which in turn triggers the idle event (after the message queue is empty). The same holds for TreeView-Controls.

I wonder how I can disable this behavior?

Running this code from the command prompt will show what I mean:

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) ;
    }
}
A: 

You could try and override the WndProc method in your form. Then using the cursor position to filter when you do and do not want to handle the WM_MOUSEHOVER message.

Something like this:

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);
    }    
}

EDIT: Just though of something, it might be better to create a custom ListView & TreeView (by simply deriving the built in .NET ones) and then override the WndProc routine in the new controls to always exclude WM_MOUSEHOVER.

ParmesanCodice
Overriding the WndProc of the Form didn't help. The Idle-Handler was still called repeatedly while the mouse is over the ListView.BUT, using a ListView derived class, overriding the WndProc and simply return on WM_HOUSEMOVER solved the problem.Thanks alot, ParmesanCodice!
miasbeck
@miasbeck glad it worked. Just bear in mind that the MouseHoverEvent will (most probably) not fire for you derived class. So if you're using ToolTips on that event you'll need to move them to the MouseMoveEvent
ParmesanCodice