vb.net - .Net TrackMouseEvent 不适用于子菜单项

标签 vb.net winapi custom-controls contextmenu

我正在向我创建的自定义 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

最佳答案

我必须采取另一种方式来解决这个问题。我将把它留在这里给任何需要它的人。

我为动态子菜单项创建了 MouseMove 和 MouseLeave 处理程序。

鼠标移动内部

If Not _mouseSubOver Then

    _tsmi = sender

    _itemDelayTimer = New Timer()
    _itemDelayTimer.Interval = Math.Max(1, 1500)
    AddHandler _itemDelayTimer.Tick, AddressOf OnDelayTimerExpire
    _itemDelayTimer.Start()

    _mouseSubOver = True

End If

鼠标离开内部

If _itemDelayTimer IsNot Nothing Then
    _itemDelayTimer.Stop()
    _itemDelayTimer.Dispose()
    _itemDelayTimer = Nothing
End If

_mouseSubOver = False

OnDelayTimerExpire 内部

 Private Sub OnDelayTimerExpire(sender As Object, e As EventArgs)
        If _itemDelayTimer IsNot Nothing Then

            _itemDelayTimer.Stop()
            _itemDelayTimer.Dispose()
            _itemDelayTimer = Nothing

        End If

        'Do your sub menu stuff here
 End Sub

关于vb.net - .Net TrackMouseEvent 不适用于子菜单项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7336500/

相关文章:

Javascript RIA 与 .NET GUI

javascript - ASP .Net 在文本更改回发时更新 asp 页面上的单个元素

.net - 如何以编程方式(在运行时)向类添加接口(interface)

c++ - 直接从已安装的 Windows 光栅(位图)字体获取位图

c++ - Win32 C++ 可以通过过程发送额外信息

sql-server - 如何将具有现有键的 DataTable 插入 SQL Server 表

c - 如何使用 Win32 API 确定打印机的 postscript 支持?

android - 使自定义 View 可聚焦

.net - 当我调整标签的大小时,代码垃圾会在新的空白区域短暂显示

delphi - 组件编辑器不会立即提示保存新的属性值