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
There is an intentional time delay of SystemInformation.MouseHoverTime
milliseconds before the MouseHover
event is generated, as a simple alternative you can use the MouseEnter
event instead, which will trigger immediately.
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.
If you use the ToolTip
component for this purpose, you can set its InitialDelay
property to a value smaller than the default 500 (half a second).
By the way, the AutoPopDelay
and ReshowDelay
properties are also useful, determining the display time and the delay upon the mouse re-entering the control's client area, respectively.