May
17
2008

Repeated MouseHover events in C#



Comments available as RSS 2.0

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.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay

Comments

Leave a Comment

Login using OpenID or enter your details below to leave a comment.

OpenID
Anonymous


Comment

Powered by WP Hashcash