Can the hover interval be changed?

后端 未结 3 1518
失恋的感觉
失恋的感觉 2021-01-18 15:18

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

相关标签:
3条回答
  • 2021-01-18 15:22

    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.

    0 讨论(0)
  • 2021-01-18 15:36

    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.

    0 讨论(0)
  • 2021-01-18 15:48

    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.

    0 讨论(0)
提交回复
热议问题