【问题标题】:Can the hover interval be changed?可以更改悬停间隔吗?
【发布时间】:2012-04-26 19:30:02
【问题描述】:

我的代码允许用户将鼠标悬停在控件上,它会做出响应。但是,我希望悬停更快地开火。有没有办法加快悬停反应?

【问题讨论】:

  • 怀疑,但放慢速度一点也不难。
  • 如何确定悬停?什么活动?您是否尝试过 MouseEnter 或一些 Preview... 事件?
  • @Denis - 我正在使用 MouseHover 事件。

标签: c# winforms hover


【解决方案1】:

在生成MouseHover 事件之前有一个SystemInformation.MouseHoverTime 毫秒的故意时间延迟,作为一个简单的替代方案,您可以改用MouseEnter 事件,它会立即触发。

【讨论】:

  • 该设置用于工具提示。但是MouseHover 事件遵循NativeMethods.TRACKMOUSEEVENTdwHoverTime 字段的值,该字段设置为100 毫秒。
【解决方案2】:

是的,你可以。 Windows 窗体中的悬停不遵循全局系统设置,在 NativeMethods.TRACKMOUSEEVENT 字段中已将其设置为 100 毫秒。

然后在控件的本机窗口的WndProc 方法中,WM_MOUSEMOVE 已被捕获以调用TrackMouseEvent,这反过来又导致WM_MOUSEHOVER。可以看源码here

因此,您可以通过将鼠标悬停所需的超时设置为dwHoverTimeTRACKMOUSEEVENT 字段来处理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 事件遵循NativeMethods.TRACKMOUSEEVENTdwHoverTime 字段的值,该字段设置为100 毫秒。

  • 您可以在我的帖子中找到类似的实现,用于处理表单标题栏上的悬停事件:Handle Mouse Hover on Titlebar of Form

  • 作为另一种选择,我还尝试设置控件的私有 trackMouseEvent 字段的 dwHoverTime 字段的值,并且该解决方案似乎也有效。

  • 可以找到VB版代码here

【讨论】:

    【解决方案3】:

    如果您为此使用ToolTip 组件,则可以将其InitialDelay 属性设置为小于默认值500(半秒)的值。

    顺便说一句,AutoPopDelayReshowDelay 属性也很有用,它们分别确定了鼠标重新进入控件客户区时的显示时间和延迟。

    【讨论】:

    • 我没有回复文本反馈,我正在通过更改其 BackColor 属性来“突出显示”TextBox。
    • @ClayShannon:所以您正在尝试调整鼠标悬停时间本身,对吗?这是每个用户的 Windows 设置,您可以使用 TweakUI(在 XP 上)或直接编辑注册表(HKCU\Control Panel\Mouse\MouseHoverTime)进行更改。
    • 好的,那时可能不可行。用户必须多一点耐心。
    • @ClayShannon:哦,并不是所有的东西都丢失了,你总是可以围绕它编写你自己的组件,比如说,使用 MouseEnter/MouseMove/MouseLeave 事件(或它们的虚拟方法对应物)和一个计时器。
    猜你喜欢
    • 1970-01-01
    • 2012-11-25
    • 2018-10-05
    • 2017-06-12
    • 1970-01-01
    • 2014-12-23
    • 1970-01-01
    • 2023-02-09
    • 1970-01-01
    相关资源
    最近更新 更多