悬停间隔可以更改吗?
本文关键字:悬停 | 更新日期: 2023-09-27 18:32:19
我有允许用户将鼠标悬停在控件上的代码,它会响应。但是,我希望悬停更快地发射。有没有办法加快悬停反应?
在生成 MouseHover
事件之前有意存在 SystemInformation.MouseHoverTime
毫秒的时间延迟,作为一个简单的替代方法,您可以改用 MouseEnter
事件,这将立即触发。
是的,你可以。Windows 窗体中的悬停不遵循全局系统设置,并且在dwHoverTime
字段中设置为NativeMethods.TRACKMOUSEEVENT
到 100 毫秒。
然后在控件的本机窗口WndProc
方法中,WM_MOUSEMOVE
已被捕获以调用TrackMouseEvent
进而导致WM_MOUSEHOVER
。您可以在此处查看源代码。
因此,您可以通过将鼠标悬停的所需超时设置为TRACKMOUSEEVENT
字段dwHoverTime
来处理WM_MOUSEMOVE
并调用TrackMouseEvent
。还要处理WM_MOUSEHOVER
并引发自定义事件,例如 MyMouseHover
。
然后,您可以轻松处理此自定义MyMouseHover
事件。
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);
}
}
笔记
系统范围的
SystemInformation.MouseHoverTime
设置用于ToolTip
。但是MouseHover
事件遵循设置为 100 毫秒的dwHoverTime
NativeMethods.TRACKMOUSEEVENT
字段的值。您可以在我的帖子中找到类似的实现,用于处理表单标题栏上的悬停事件:在表单标题栏上处理鼠标悬停。
作为另一种选择,我还尝试设置控件的私有
trackMouseEvent
字段的dwHoverTime
字段的值,并且此解决方案似乎也有效。您可以在此处找到代码的VB版本。
ToolTip
组件用于此目的,则可以将其 InitialDelay
属性设置为小于默认 500(半秒)的值。
顺便说一下,AutoPopDelay
和 ReshowDelay
属性也很有用,它们分别确定鼠标重新进入控件工作区时的显示时间和延迟。