Can the hover interval be changed?

柔情痞子 提交于 2019-12-30 19:06:30

问题


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 reaction?


回答1:


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.




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/10340093/can-the-hover-interval-be-changed

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!