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.
c-sharp, mousehover, win32 api, windows forms