TrackMouseEvent für ein GUI Control

  • Hat jemand eine Idee wie ich die TrackMouseEvent Funktion (WinAPIEx.au3) auf einen Button oder andere Controls anwenden könnte, um herauszufinden wann der Mauszeiger darüber "hovert"?
    In folgendem Script funktioniert das ganze schon mal für die Haupt-GUI:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>
    #include <WindowsConstants.au3>
    #include <GUIButton.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $hGUI = GUICreate("Not Hovering...", 400, 400)
    $hButton = _GUICtrlButton_Create($hGUI, "Test", 50, 50, 60, 25)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    If Not _WinAPI_TrackMouseEvent($hGUI, 1) Then Exit

    [/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg($WM_MOUSEHOVER, "WM_MOUSEHOVER")
    GUIRegisterMsg($WM_MOUSEMOVE, "WM_MOUSEMOVE")

    [/autoit] [autoit][/autoit] [autoit]

    While True
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    Exit
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_MOUSEMOVE($hWnd, $iMsg, $wParam, $lParam)
    WinSetTitle($hGUI, "", "Not Hovering...")

    [/autoit] [autoit][/autoit] [autoit]

    If Not _WinAPI_TrackMouseEvent($hGUI, 1) Then Exit
    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_MOUSEHOVER($hWnd, $iMsg, $wParam, $lParam)
    WinSetTitle($hGUI, "", "Hovering!")

    [/autoit] [autoit][/autoit] [autoit]

    If Not _WinAPI_TrackMouseEvent($hGUI, 1) Then Exit
    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _WinAPI_TrackMouseEvent
    ; Description....: Posts messages when the mouse pointer leaves a window or hovers over a window for a specified amount of time.
    ; Syntax.........: _WinAPI_TrackMouseEvent ( $hWnd, $iFlags [, $iTime] )
    ; Parameters.....: $hWnd - Handle to the window to track.
    ; Return values..: $iFlags - The services requested. This parameter can be a combination of the following values.
    ;
    ; $TME_CANCEL
    ; $TME_HOVER
    ; $TME_LEAVE
    ; $TME_NONCLIENT
    ; $TME_QUERY
    ;
    ; $iTime - The hover time-out (if $TME_HOVER was specified in $Flags), in milliseconds. Can be (-1), which
    ; means to use the system default hover time-out.
    ; Failure - 0 and sets the @error flag to non-zero.
    ; Author.........: Matt Diesel (Mat)
    ; Modified.......: Yashied
    ; Remarks........: None
    ; Related........:
    ; Link...........: @@MsdnLink@@ TrackMouseEvent
    ; Example........: Yes
    ; ===============================================================================================================================

    [/autoit] [autoit][/autoit] [autoit]

    Func _WinAPI_TrackMouseEvent($hWnd, $iFlags, $iTime = -1)

    [/autoit] [autoit][/autoit] [autoit]

    Local $tTME = DllStructCreate('dword;dword;hwnd;dword')

    [/autoit] [autoit][/autoit] [autoit]

    DllStructSetData($tTME, 1, DllStructGetSize($tTME))
    DllStructSetData($tTME, 2, $iFlags)
    DllStructSetData($tTME, 3, $hWnd)
    DllStructSetData($tTME, 4, $iTime)

    [/autoit] [autoit][/autoit] [autoit]

    Local $Ret = DllCall('user32.dll', 'int', 'TrackMouseEvent', 'ptr', DllStructGetPtr($tTME))

    [/autoit] [autoit][/autoit] [autoit]

    If (@error) Or (Not $Ret[0]) Then
    Return SetError(1, 0, 0)
    EndIf
    Return 1
    EndFunc ;==>_WinAPI_TrackMouseEvent

    [/autoit]


    Wenn ich lediglich das Handle bei jedem TrackMouseEvent Aufruf durch $hButton ersetze funktioniert das ganze nicht (kein Call von WM_MOUSEHOVER). Der Button ist ein Child-Window der Haupt-GUI, daran liegt es also nicht.
    Ich habe nicht besonders viel Zeit um das hier zu formulieren, falls Informationen fehlen bitte ich darauf hingewiesen zu werden ^^.

  • Hi,
    da scheint was faul zu sein mit AutoIt?!
    Sämtliche Beispiele funktionieren nicht mehr, auch das von Gary Frost nicht.

    Was ich aber herausgefunden habe:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>
    #include <WindowsConstants.au3>
    #include <GUIButton.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $hGUI = GUICreate("Not Hovering...", 400, 400)
    ;$hButton = _GUICtrlButton_Create($hGUI, "Test", 50, 50, 60, 25)
    GUISetState()
    sleep(3000)
    If Not _WinAPI_TrackMouseEvent($hGUI, 1) Then Exit

    [/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg($WM_MOUSEHOVER, "WM_MOUSEHOVER")
    GUIRegisterMsg($WM_MOUSEMOVE, "WM_MOUSEMOVE")
    GUIRegisterMsg($WM_MOUSELEAVE, "WM_MOUSELEAVE")
    GUIRegisterMsg($WM_NCMOUSEHOVER, "WM_NCMOUSEHOVER")
    GUIRegisterMsg($WM_NCMOUSELEAVE, "WM_NCMOUSELEAVE")

    [/autoit] [autoit][/autoit] [autoit]

    While True
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    Exit
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_MOUSEMOVE($hWnd, $iMsg, $wParam, $lParam)
    WinSetTitle($hGUI, "", "Not Hovering...")
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $hGUI = ' & timerinit() & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit]

    If Not _WinAPI_TrackMouseEvent($hGUI, 1) Then Exit
    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_MOUSEHOVER($hWnd, $iMsg, $wParam, $lParam)
    WinSetTitle($hGUI, "", "Hovering!")
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : HOVERING = ' & timerinit() & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    sleep(200)
    If Not _WinAPI_TrackMouseEvent($hGUI, 1) Then Exit
    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_MOUSELEAVE($hWnd, $iMsg, $wParam, $lParam)
    WinSetTitle($hGUI, "", "LEAVE!")
    sleep(200)
    If Not _WinAPI_TrackMouseEvent($hGUI, 1) Then Exit
    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_NCMOUSEHOVER($hWnd, $iMsg, $wParam, $lParam)
    WinSetTitle($hGUI, "", "NC-Hovering!")
    sleep(200)
    If Not _WinAPI_TrackMouseEvent($hGUI, 1) Then Exit
    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_NCMOUSELEAVE($hWnd, $iMsg, $wParam, $lParam)
    WinSetTitle($hGUI, "", "NC-LEAVE!")
    sleep(200)
    If Not _WinAPI_TrackMouseEvent($hGUI, 1) Then Exit
    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _WinAPI_TrackMouseEvent
    ; Description....: Posts messages when the mouse pointer leaves a window or hovers over a window for a specified amount of time.
    ; Syntax.........: _WinAPI_TrackMouseEvent ( $hWnd, $iFlags [, $iTime] )
    ; Parameters.....: $hWnd - Handle to the window to track.
    ; Return values..: $iFlags - The services requested. This parameter can be a combination of the following values.
    ;
    ; $TME_CANCEL
    ; $TME_HOVER
    ; $TME_LEAVE
    ; $TME_NONCLIENT
    ; $TME_QUERY
    ;
    ; $iTime - The hover time-out (if $TME_HOVER was specified in $Flags), in milliseconds. Can be (-1), which
    ; means to use the system default hover time-out.
    ; Failure - 0 and sets the @error flag to non-zero.
    ; Author.........: Matt Diesel (Mat)
    ; Modified.......: Yashied
    ; Remarks........: None
    ; Related........:
    ; Link...........: @@MsdnLink@@ TrackMouseEvent
    ; Example........: Yes
    ; ===============================================================================================================================

    [/autoit] [autoit][/autoit] [autoit]

    Func _WinAPI_TrackMouseEvent($hWnd, $iFlags, $iTime = -1)

    [/autoit] [autoit][/autoit] [autoit]

    Local $tTME = DllStructCreate('dword;dword;hwnd;dword')

    [/autoit] [autoit][/autoit] [autoit]

    DllStructSetData($tTME, 1, DllStructGetSize($tTME))
    DllStructSetData($tTME, 2, $iFlags)
    DllStructSetData($tTME, 3, $hWnd)
    DllStructSetData($tTME, 4, -1)

    [/autoit] [autoit][/autoit] [autoit]

    Local $Ret = DllCall('user32.dll', 'int', 'TrackMouseEvent', 'ptr', DllStructGetPtr($tTME))

    [/autoit] [autoit][/autoit] [autoit]

    If (@error) Or (Not $Ret[0]) Then
    Return SetError(1, 0, 0)
    EndIf
    Return 1
    EndFunc ;==>_WinAPI_TrackMouseEvent

    [/autoit]

    Script starten, Mauscursor in die Titelleiste, Fenster verschieben und anhalten (Maustaste gedrückt lassen), 400ms warten, tadaaaa Hoverevent...aber erst nachdem das WM_NCMOUSELEAVE gefeuert wurde...wtf?!

  • Falls das Verhalten normal ist, dann ist es zumindest extrem seltsam...
    Schade, dass es für den Moment keine simple Lösung gibt die ich einfach übersehen habe. Fällt jemandem vielleicht eine Alternative ein die ähnlich funktioniert (abgesehen von einer ständigen Überprüfung der Cursorposition in der Hauptschleife)?