17 May 2008

Repeated MouseHover events in C#

No Comments Programming

Due to a quirk in the way Windows handles events, once a mouse hover event has been triggered on a windows form control, another event cannot be triggered until the mouse leaves and re-enters the control. Sometimes you might need to process more than one MouseHover event, for example if you have a user control which has draws shapes on itself. As long as you have a record of where the shapes are (by storing them in a collection), you can use the method below as a workaround.

I used this to display a tooltip, so to prevent the MouseHover event being spammed, action is only taken when my tooltip is not visible.

private const uint TME_HOVER = 0x00000001;
private const uint TME_LEAVE = 0x00000002;
private const uint HOVER_DEFAULT = 0xFFFFFFFF;
 
[DllImport("user32.dll")]
public static extern bool TrackMouseEvent(ref TRACKMOUSEEVENT lpEventTrack);
 
public struct TRACKMOUSEEVENT {
    public uint cbSize;
    public uint dwFlags;
    public IntPtr hwndTrack;
    public uint dwHoverTime;
}
 
ToolTip toolTip = new ToolTip();
toolTip.Location = new System.Drawing.Point(290, 80);
 
Rectangle currentActiveShape = new Rectangle(); // the currently active shape (over which the mouse is hovering)
 
this.MouseMove += delegate(object sender, MouseEventArgs e) {
    foreach(Rectangle rect in myShapeCollection) {
        if(rect.Contains(e.Location)) {
            if(currentActiveDay != day.Bounds) {
                toolTip.Hide();
                Console.WriteLine("Hide tooltip");
            }
            currentActiveShape = rect;
            // Set location here
            Console.WriteLine("Entered " + rect.ToString());
        }
    }
};
this.MouseHover += delegate(object sender, EventArgs e) {
    TRACKMOUSEEVENT trackMouseEvent = new TRACKMOUSEEVENT();
    trackMouseEvent.hwndTrack = ((Control)sender).Handle;
    trackMouseEvent.dwFlags = TME_HOVER;
    trackMouseEvent.dwHoverTime = HOVER_DEFAULT;
    trackMouseEvent.cbSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(trackMouseEvent);
    TrackMouseEvent(ref trackMouseEvent);
 
    if(!toolTip.Active) {
        toolTip.Show();
        Console.WriteLine("Show tooltip");
    }
};

As the mouse moves around the control, the location of the tooltip changes, but it’s not shown until the MouseHover event is triggerd.

Due to a quirk in the way Windows handles events, once a mouse hover event has been triggered on a windows form control, another event cannot be triggered until the mouse leaves and re-enters the control. Sometimes you might need to process more than one MouseHover event, for example if you have a user control which has draws shapes on itself. As long as you have a record of where the shapes are (by storing them in a collection), you can use the method below as a workaround.

Tags: , , ,
written by
The author didn‘t add any Information to his profile yet.
No Responses to “Repeated MouseHover events in C#”

Leave a Reply