.Net TrackMouseEvent 不适用于子菜单项
我正在向我创建的自定义 ContextMenuStrip 控件添加一些功能。
我需要做的第一件事是增加鼠标悬停在子菜单上下文项上的时间。以下代码非常适合主上下文项,但不会触发子菜单项的鼠标悬停事件。
我相信问题是我需要将 tme.hWnd 句柄设置为子菜单。如果是这种情况,如何在子菜单打开时获取其句柄?
谢谢!
Friend Const WM_MOUSEMOVE As Integer = &H200
Friend Const WM_MOUSELEAVE As Integer = &H2A3
Friend Const TME_LEAVE As Integer = &H2
Private _mouseOver As Boolean = False
Private _mouseOverHandel As IntPtr = Me.Handle
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Select Case m.Msg
Case WM_MOUSEMOVE
If Not _mouseOver Then
Dim tme As New TRACKMOUSEEVENTR()
tme.hWnd = _mouseOverHandel
tme.cbSize = Marshal.SizeOf(GetType(TRACKMOUSEEVENTR))
tme.dwFlags = TMEFlags.TME_HOVER
tme.dwHoverTime = 1000 * 3
TrackMouseEvent(tme)
_mouseOver = True
End If
MyBase.WndProc(m)
Exit Select
Case WM_MOUSELEAVE
_mouseOver = False
MyBase.WndProc(m)
Exit Select
Case Else
MyBase.WndProc(m)
End Select
End Sub
<DllImport("user32.dll")> _
Private Shared Function TrackMouseEvent(ByRef lpEventTrack As TRACKMOUSEEVENTR) As Integer
End Function
<StructLayout(LayoutKind.Sequential)> _
Public Structure TRACKMOUSEEVENTR
Public cbSize As Int32
' using Int32 instead of UInt32 is safe here, and this avoids casting the result of Marshal.SizeOf()
<MarshalAs(UnmanagedType.U4)> _
Public dwFlags As TMEFlags
Public hWnd As IntPtr
Public dwHoverTime As UInt32
Public Sub New(dwFlags As Int32, hWnd As IntPtr, dwHoverTime As UInt32)
Me.cbSize = Marshal.SizeOf(GetType(TRACKMOUSEEVENTR))
Me.dwFlags = dwFlags
Me.hWnd = hWnd
Me.dwHoverTime = dwHoverTime
End Sub
End Structure
''' <summary>
''' The services requested. This member can be a combination of the following values.
''' </summary>
<Flags()> _
Public Enum TMEFlags As UInteger
TME_CANCEL = &H80000000UI
TME_HOVER = &H1
TME_LEAVE = &H2
TME_NONCLIENT = &H10
TME_QUERY = &H40000000
End Enum
I am adding some functionality to a custom ContextMenuStrip control that I have created.
One of the first things that I need to do is increase the mouse hover time on the submenu context items. The following code works perfectly for the main context items, but will not fire my mouse hover event for submenu items.
I believe the problem is that I need to set the tme.hWnd handle to the submenu. If that is the case, how do I get the handle of the submenu as it is opening?
Thanks!
Friend Const WM_MOUSEMOVE As Integer = &H200
Friend Const WM_MOUSELEAVE As Integer = &H2A3
Friend Const TME_LEAVE As Integer = &H2
Private _mouseOver As Boolean = False
Private _mouseOverHandel As IntPtr = Me.Handle
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Select Case m.Msg
Case WM_MOUSEMOVE
If Not _mouseOver Then
Dim tme As New TRACKMOUSEEVENTR()
tme.hWnd = _mouseOverHandel
tme.cbSize = Marshal.SizeOf(GetType(TRACKMOUSEEVENTR))
tme.dwFlags = TMEFlags.TME_HOVER
tme.dwHoverTime = 1000 * 3
TrackMouseEvent(tme)
_mouseOver = True
End If
MyBase.WndProc(m)
Exit Select
Case WM_MOUSELEAVE
_mouseOver = False
MyBase.WndProc(m)
Exit Select
Case Else
MyBase.WndProc(m)
End Select
End Sub
<DllImport("user32.dll")> _
Private Shared Function TrackMouseEvent(ByRef lpEventTrack As TRACKMOUSEEVENTR) As Integer
End Function
<StructLayout(LayoutKind.Sequential)> _
Public Structure TRACKMOUSEEVENTR
Public cbSize As Int32
' using Int32 instead of UInt32 is safe here, and this avoids casting the result of Marshal.SizeOf()
<MarshalAs(UnmanagedType.U4)> _
Public dwFlags As TMEFlags
Public hWnd As IntPtr
Public dwHoverTime As UInt32
Public Sub New(dwFlags As Int32, hWnd As IntPtr, dwHoverTime As UInt32)
Me.cbSize = Marshal.SizeOf(GetType(TRACKMOUSEEVENTR))
Me.dwFlags = dwFlags
Me.hWnd = hWnd
Me.dwHoverTime = dwHoverTime
End Sub
End Structure
''' <summary>
''' The services requested. This member can be a combination of the following values.
''' </summary>
<Flags()> _
Public Enum TMEFlags As UInteger
TME_CANCEL = &H80000000UI
TME_HOVER = &H1
TME_LEAVE = &H2
TME_NONCLIENT = &H10
TME_QUERY = &H40000000
End Enum
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不得不采取另一种方式来解决这个问题。我会把它留在这里给任何需要它的人。
我为动态子菜单项创建了 MouseMove 和 MouseLeave 处理程序。
在鼠标内部移动
在鼠标内部离开
内部 OnDelayTimerExpire
I had to go another way to solve this. I'll leave this here for anyone that needs it.
I created a MouseMove and MouseLeave handler for my dynamic submenu items.
Inside the MouseMove
Inside MouseLeave
Inside OnDelayTimerExpire