有没有办法设置鼠标必须在控件上的时间段才能触发其 MouseHover 事件?
Is there a way to set the period of time that the mouse must be over a control in order to trigger its MouseHover event?
我需要一种方法来设置 MouseHoverTime 属性,或者其他一些方法,以便在事件开始之前鼠标需要在控件上停留指定的时间。
我有一组控件需要在鼠标经过它们时执行代码,这可以通过 MouseEnter 或 MouseHover 来完成。但是,当鼠标快速经过这些控件中的许多控件时,每个控件的代码事件都会得到完整的 运行。这使得程序的 运行ning 非常缓慢且不切实际。如果我可以设置鼠标停留在控件上的时间阈值,那么只有当鼠标停留在控件上时才会调用事件,而不是短暂地经过它。
Private Sub Tile_MouseHover(Sender As Object, e As EventArgs)
CODE
CODE
CODE
End Sub
代码确实给出了预期的结果。它只是以蜗牛的速度提供它们,因为每次光标只要刷一个控件,就会执行其中的所有代码。
目标结果如下:
当光标悬停在控件上时,它必须在该控件上停留 1-2 秒才能调用事件。
如果光标在此之前离开,则根本不会调用该事件。
我已经发布了 C# 版本的答案 here,其中包含更多详细信息。
Note: The answer doesn't claim to solve the performance issue which
you shared in the question, but shows how you can increase the mouse
hover delay time.
悬停时间已NativeMethods.TRACKMOUSEEVENT
设置为100毫秒。
您可以处理 WM_MOUSEMOVE
并调用 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 subscribe for MyMouseHover
event. You can find a similar approach in my post for handling hover event on title bar of a form: 。
VB.NET - 带有自定义悬停时间的悬停事件
她是引发 MyMouseHover
事件并延迟 500 毫秒的控件示例:
Imports System
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Public Class SampleControl
Inherits Control
<DllImport("user32.dll")>
Private Shared Function TrackMouseEvent(ByRef lpEventTrack As TRACK_MOUSE_EVENT) _
As Integer
End Function
<StructLayout(LayoutKind.Sequential)>
Private Structure TRACK_MOUSE_EVENT
Public cbSize As UInteger
Public dwFlags As UInteger
Public hwndTrack As IntPtr
Public dwHoverTime As UInteger
Public Shared ReadOnly Empty As TRACK_MOUSE_EVENT
End Structure
Private track As TRACK_MOUSE_EVENT = TRACK_MOUSE_EVENT.Empty
Const WM_MOUSEMOVE As Integer = &H200
Const WM_MOUSEHOVER As Integer = &H2A1
Const TME_HOVER As Integer = &H1
Const TME_LEAVE As Integer = &H2
Public Event MyMouseHover As EventHandler
Protected Overrides Sub WndProc(ByRef m As Message)
If m.Msg = WM_MOUSEMOVE Then
track.hwndTrack = Me.Handle
track.cbSize = CUInt(Marshal.SizeOf(track))
track.dwFlags = TME_HOVER Or TME_LEAVE
track.dwHoverTime = 500
TrackMouseEvent(track)
End If
If m.Msg = WM_MOUSEHOVER Then
RaiseEvent MyMouseHover(Me, EventArgs.Empty)
End If
MyBase.WndProc(m)
End Sub
End Class
我需要一种方法来设置 MouseHoverTime 属性,或者其他一些方法,以便在事件开始之前鼠标需要在控件上停留指定的时间。
我有一组控件需要在鼠标经过它们时执行代码,这可以通过 MouseEnter 或 MouseHover 来完成。但是,当鼠标快速经过这些控件中的许多控件时,每个控件的代码事件都会得到完整的 运行。这使得程序的 运行ning 非常缓慢且不切实际。如果我可以设置鼠标停留在控件上的时间阈值,那么只有当鼠标停留在控件上时才会调用事件,而不是短暂地经过它。
Private Sub Tile_MouseHover(Sender As Object, e As EventArgs)
CODE
CODE
CODE
End Sub
代码确实给出了预期的结果。它只是以蜗牛的速度提供它们,因为每次光标只要刷一个控件,就会执行其中的所有代码。
目标结果如下:
当光标悬停在控件上时,它必须在该控件上停留 1-2 秒才能调用事件。 如果光标在此之前离开,则根本不会调用该事件。
我已经发布了 C# 版本的答案 here,其中包含更多详细信息。
Note: The answer doesn't claim to solve the performance issue which you shared in the question, but shows how you can increase the mouse hover delay time.
悬停时间已NativeMethods.TRACKMOUSEEVENT
设置为100毫秒。
您可以处理 WM_MOUSEMOVE
并调用 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 subscribe for MyMouseHover
event. You can find a similar approach in my post for handling hover event on title bar of a form:
VB.NET - 带有自定义悬停时间的悬停事件
她是引发 MyMouseHover
事件并延迟 500 毫秒的控件示例:
Imports System
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Public Class SampleControl
Inherits Control
<DllImport("user32.dll")>
Private Shared Function TrackMouseEvent(ByRef lpEventTrack As TRACK_MOUSE_EVENT) _
As Integer
End Function
<StructLayout(LayoutKind.Sequential)>
Private Structure TRACK_MOUSE_EVENT
Public cbSize As UInteger
Public dwFlags As UInteger
Public hwndTrack As IntPtr
Public dwHoverTime As UInteger
Public Shared ReadOnly Empty As TRACK_MOUSE_EVENT
End Structure
Private track As TRACK_MOUSE_EVENT = TRACK_MOUSE_EVENT.Empty
Const WM_MOUSEMOVE As Integer = &H200
Const WM_MOUSEHOVER As Integer = &H2A1
Const TME_HOVER As Integer = &H1
Const TME_LEAVE As Integer = &H2
Public Event MyMouseHover As EventHandler
Protected Overrides Sub WndProc(ByRef m As Message)
If m.Msg = WM_MOUSEMOVE Then
track.hwndTrack = Me.Handle
track.cbSize = CUInt(Marshal.SizeOf(track))
track.dwFlags = TME_HOVER Or TME_LEAVE
track.dwHoverTime = 500
TrackMouseEvent(track)
End If
If m.Msg = WM_MOUSEHOVER Then
RaiseEvent MyMouseHover(Me, EventArgs.Empty)
End If
MyBase.WndProc(m)
End Sub
End Class