I have code that allows a user to hover over a control, and it will respond. However, I\'d like the hovering to fire a little quicker. Is there a way to speed up the hover r
Yes you can. The hover in Windows Forms is not following the global system setting and it has been set in NativeMethods.TRACKMOUSEEVENT to 100 milliseconds in the dwHoverTime
field.
Then in WndProc
method of the native window of the control, WM_MOUSEMOVE
has been trapped to call TrackMouseEvent
which in turn cause a WM_MOUSEHOVER
. You can see the source code here.
So you can handle WM_MOUSEMOVE
and call TrackMouseEvent by setting desired timeout for mouse hover as dwHoverTime
field of the TRACKMOUSEEVENT. Also handle WM_MOUSEHOVER
and raise a custom event like MyMouseHover
.
Then you can easily handle this custom MyMouseHover
event.
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class SampleControl : Control
{
[DllImport("user32.dll")]
private static extern int TrackMouseEvent(ref TRACKMOUSEEVENT lpEventTrack);
[StructLayout(LayoutKind.Sequential)]
private struct TRACKMOUSEEVENT
{
public uint cbSize;
public uint dwFlags;
public IntPtr hwndTrack;
public uint dwHoverTime;
public static readonly TRACKMOUSEEVENT Empty;
}
private TRACKMOUSEEVENT track = TRACKMOUSEEVENT.Empty;
const int WM_MOUSEMOVE = 0x0200;
const int WM_MOUSEHOVER = 0x02A1;
const int TME_HOVER = 0x1;
const int TME_LEAVE = 0x2;
public event EventHandler MyMouseHover;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_MOUSEMOVE)
{
track.hwndTrack = this.Handle;
track.cbSize = (uint)Marshal.SizeOf(track);
track.dwFlags = TME_HOVER | TME_LEAVE;
track.dwHoverTime = 500;
TrackMouseEvent(ref track);
}
if(m.Msg == WM_MOUSEHOVER)
{
MyMouseHover?.Invoke(this, EventArgs.Empty);
}
base.WndProc(ref m);
}
}
Notes
The system-wide SystemInformation.MouseHoverTime
setting is used for ToolTip
. But the MouseHover
event is following the value of dwHoverTime
field of NativeMethods.TRACKMOUSEEVENT which is set to 100 milliseconds.
You can find a similar implementation in my post for handling hover event on title bar of a form: Handle Mouse Hover on Titlebar of Form.
As another option I also tried setting value of dwHoverTime
field of the private trackMouseEvent
field of the control and this solution also seems to be working.
You can find VB version of the code here.