Tooltip verschieben

  • Hi,

    ich habe nur nen kleines Problem, hoffe es gibt da ne schicke Lösung für :D

    Und zwar lasse ich mir im Moment ein paar infos über nen Tooltip anzeigen

    [autoit]

    ToolTip("This is a tooltip", 0, 0)

    [/autoit]

    Jedoch habe ich das Problem, dass ich das dingen nicht verschieben kann, wenn es im weg ist.

    Hat da jemand ne idee?
    Tooltip selbst scheint es ja leider nicht zu können
    Balloon Tip ebenso :(

    21 is only half the truth.

  • Vielleicht schaust du dir dieses Script einmal an:

    Spoiler anzeigen
    [autoit]

    ; ===============================================================================
    ;~ This script gets the control under the mouse pointer (active or inactive)
    ;~ The information then can be used with in conjunction with control functions.
    ;~ Requires AutoIt v3.3.6.0 or later to run and to view apps maximized.
    ;~ Big thanks to SmOke_N and Valik their help in creating it.
    ; ===============================================================================
    #include <WinAPI.au3>
    #include <Array.au3>
    #include <WindowsConstants.au3>

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

    AutoItSetOption("MustDeclareVars", 1)
    AutoItSetOption("MouseCoordMode", 1)
    AdlibRegister("_Mouse_Control_GetInfoAdlib", 10)
    HotKeySet("^!c", "MyExit") ; Press Ctrl+Alt+c to stop the script
    ;~ #AutoIt3Wrapper_run_debug_mode=Y

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

    Global $pos1 = MouseGetPos()
    Global $pos2 = MouseGetPos() ; must be initialized
    Global $appHandle = 0

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

    While 1
    Sleep(0xFFFFFFF)
    WEnd

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

    ; ===============================================================================
    ;~ Retrieves the information of a Control located under the mouse and displayes it in a tool tip next to the mouse.
    ;~ Function uesd
    ;~ _Mouse_Control_GetInfo()
    ;~ GetDlgCtrlID
    ; ===============================================================================
    Func _Mouse_Control_GetInfoAdlib()
    $pos1 = MouseGetPos()
    If $pos1[0] <> $pos2[0] Or $pos1[1] <> $pos2[1] Then ; has the mouse moved?
    Local $a_info = _Mouse_Control_GetInfo()
    Local $aDLL = DllCall('User32.dll', 'int', 'GetDlgCtrlID', 'hwnd', $a_info[0]) ; get the ID of the control
    If @error Then Return
    ToolTip("Handle = " & $a_info[0] & @CRLF & _
    "Class = " & $a_info[1] & @CRLF & _
    "ID = " & $aDLL[0] & @CRLF & _
    "Mouse X Pos = " & $a_info[2] & @CRLF & _
    "Mouse Y Pos = " & $a_info[3] & @CRLF & _
    "ClassNN = " & $a_info[4] & @CRLF & _ ; optional
    "Parent Hwd = " & _WinAPI_GetAncestor($appHandle, $GA_ROOT))
    $pos2 = MouseGetPos()
    EndIf
    EndFunc ;==>_Mouse_Control_GetInfoAdlib

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

    ; ===============================================================================
    ;~ Retrieves the information of a Control located under the mouse.
    ;~ Uses Windows functions WindowFromPoint and GetClassName to retrieve the information.
    ;~ Functions used
    ;~ _GetHoveredHwnd()
    ;~ _ControlGetClassnameNN()
    ;~ Returns
    ;~ [0] = Control Handle of the control
    ;~ [1] = The Class Name of the control
    ;~ [2] = Mouse X Pos (converted to Screen Coord)
    ;~ [3] = Mouse Y Pos (converted to Screen Coord)
    ;~ [4] = ClassNN
    ; ===============================================================================
    Func _Mouse_Control_GetInfo()
    Local $client_mpos = $pos1 ; gets client coords because of "MouseCoordMode" = 2
    Local $a_mpos
    ;~ Call to removed due to offset issue $a_mpos = _ClientToScreen($appHandle, $client_mpos[0], $client_mpos[1]) ; $a_mpos now screen coords
    $a_mpos = $client_mpos
    $appHandle = GetHoveredHwnd($client_mpos[0], $client_mpos[1]) ; Uses the mouse to do the equivalent of WinGetHandle()

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

    If @error Then Return SetError(1, 0, 0)
    Local $a_wfp = DllCall("user32.dll", "hwnd", "WindowFromPoint", "long", $a_mpos[0], "long", $a_mpos[1]) ; gets the control handle
    If @error Then Return SetError(2, 0, 0)

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

    Local $t_class = DllStructCreate("char[260]")
    DllCall("User32.dll", "int", "GetClassName", "hwnd", $a_wfp[0], "ptr", DllStructGetPtr($t_class), "int", 260)
    Local $a_ret[5] = [$a_wfp[0], DllStructGetData($t_class, 1), $a_mpos[0], $a_mpos[1], "none"]
    Local $sClassNN = _ControlGetClassnameNN($a_ret[0]) ; optional, will run faster without it
    $a_ret[4] = $sClassNN

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

    Return $a_ret
    EndFunc ;==>_Mouse_Control_GetInfo

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

    ; ===============================================================================
    ; Retrieves the Handle of GUI/Application the mouse is over.
    ; Similar to WinGetHandle except it used the current mouse position
    ; Taken from <a href='http://www.autoitscript.com/forum/index.php?showtopic=444962' class='bbc_url' title=''>http://www.autoitscript.com/forum/index.php?showtopic=444962</a>
    ; Changed to take params to allow only one set of coords to be used.
    ; Params
    ;~ $i_xpos - x position of the mouse - usually from MouseGetPos(0)
    ;~ $i_ypos - x position of the mouse - usually from MouseGetPos(1)
    ; ===============================================================================
    Func GetHoveredHwnd($i_xpos, $i_ypos)
    Local $iRet = DllCall("user32.dll", "int", "WindowFromPoint", "long", $i_xpos, "long", $i_ypos)
    If IsArray($iRet) Then
    $appHandle = $iRet[0]
    Return HWnd($iRet[0])
    Else
    Return SetError(1, 0, 0)
    EndIf
    EndFunc ;==>GetHoveredHwnd

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

    ; ===============================================================================
    ;~ Gets the ClassNN of a control (Classname and Instance Count). This is checked with ControlGetHandle
    ;~ The instance is really a way to uniquely identify classes with the same name
    ;~ Big thanks to Valik for writing the function, taken from - <a href='http://www.autoitscript.com/forum/index.php?showtopic=97662' class='bbc_url' title=''>http://www.autoitscript.com/forum/index.php?showtopic=97662</a>
    ;~ Param
    ;~ $hControl - the control handle from which you want the ClassNN
    ;~ Returns
    ;~ the ClassNN of the given control

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

    ; ===============================================================================
    Func _ControlGetClassnameNN($hControl)
    If Not IsHWnd($hControl) Then Return SetError(1, 0, "")
    Local Const $hParent = _WinAPI_GetAncestor($appHandle, $GA_ROOT) ; get the Window handle, this is set in GetHoveredHwnd()
    If Not $hParent Then Return SetError(2, 0, "")

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

    Local Const $sList = WinGetClassList($hParent) ; list of every class in the Window
    Local $aList = StringSplit(StringTrimRight($sList, 1), @LF, 2)
    _ArraySort($aList) ; improves speed
    Local $nInstance, $sLastClass, $sComposite

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

    For $i = 0 To UBound($aList) - 1
    If $sLastClass <> $aList[$i] Then ; set up the first occurrence of a unique classname
    $sLastClass = $aList[$i]
    $nInstance = 1
    EndIf
    $sComposite = $sLastClass & $nInstance ;build the ClassNN for testing with ControlGetHandle. ClassNN = Class & ClassCount
    ;if ControlGetHandle(ClassNN) matches the given control return else look at the next instance of the classname
    If ControlGetHandle($hParent, "", $sComposite) = $hControl Then
    Return $sComposite
    EndIf
    $nInstance += 1 ; count the number of times the class name appears in the list
    Next
    Return SetError(3, 0, "")

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

    EndFunc ;==>_ControlGetClassnameNN

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

    ; ===============================================================================
    ;~ Functions not used anymore.
    ; ===============================================================================

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

    ; ===============================================================================
    ;~ Translates client coordinates into screen coordinates, [0] = x and [1] = y from the return array.
    ;~ Requires - AutoItSetOption("MouseCoordMode", 2)
    ;~ Params
    ;~ $h_wnd - Identifies the window whose client area is used for the conversion.
    ;~ $i_x - x pos of the client coord
    ;~ $i_y - Y pos of the client coord
    ;~ Returns
    ;~ Screen coordinates
    ; ===============================================================================
    Func _ClientToScreen($h_wnd, $i_x, $i_y)
    ;~ ConsoleWrite("Client here, " & $i_x & "," & $i_y & @ CRLF)
    Local $t_point = DllStructCreate("int;int")
    DllStructSetData($t_point, 1, $i_x)
    DllStructSetData($t_point, 2, $i_y)
    DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $h_wnd, "ptr", DllStructGetPtr($t_point))
    Local $a_ret[2] = [DllStructGetData($t_point, 1), DllStructGetData($t_point, 2)]
    ;~ ConsoleWrite("Screen here, " & $a_ret[0] & "," & $a_ret[1] & @CRLF)
    Return $a_ret
    EndFunc ;==>_ClientToScreen

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

    ;~ Finds a matching window with the given handle
    Func matchWinHandle($hParent)
    Local $aWinList = WinList()
    Local $flag = 0;
    For $i = 0 To UBound($aWinList) - 1
    If $aWinList[$i][1] = $hParent Then
    ConsoleWriteError("hParent match is " & $aWinList[$i][0] & @LF)
    $flag = 1
    ;~ _ArrayDisplay($aWinList)
    ExitLoop
    EndIf
    Next
    If $flag = 0 Then
    ConsoleWriteError("No windows handle match found in WinList" & @LF)
    EndIf
    EndFunc ;==>matchWinHandle

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

    Func MyExit() ; stops the script
    ConsoleWrite("Script Stoppted By User" & @CR)
    Exit
    EndFunc ;==>MyExit

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

    ;==> Recersive version. No need now that I am using $GA_ROOT with get _WinAPI_GetAncestor
    Func matchWinHandleRec($hParent)
    Local $aWinList = WinList()
    Local $flag = 0;
    For $i = 0 To UBound($aWinList) - 1
    If $aWinList[$i][1] = $hParent Then
    ConsoleWriteError("hParent match is " & $aWinList[$i][0] & @LF)
    $flag = 1;
    ExitLoop
    Return
    EndIf
    Next
    If $flag = 0 Then
    ConsoleWriteError("No windows handle match found in WinList. Calling it again" & @LF)
    matchWinHandle(_WinAPI_GetAncestor($hParent))
    Local $sClassList = WinGetClassList($hParent)
    Local $aClassList = StringSplit(StringTrimRight($sClassList, 1), @LF, 2)

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

    For $i = 0 To UBound($aClassList) - 1
    ConsoleWrite($aClassList[$i] & @LF)
    Next
    EndIf

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

    EndFunc ;==>matchWinHandleRec

    [/autoit]

    Es erzeugt einen Tooltip, der der Maus folgt. Damit wäre es nicht mehr im Weg.
    Ansonsten kannst du ja damit überprüfen, ob der Tooltip unter der Maus ist, und wenn er dort ist kannst du beim linksklick mit ziehen den Tooltip verschieben.
    Ich hoffe es hilft dir weiter :)

    Viel Glück noch!

  • Hm hab es jetzt über MouseGetPos() gelöst.
    Hatte eher gehofft man könne es quasi verschieben :D
    Aber danke für deienn Vorschlag

    21 is only half the truth.

    • Offizieller Beitrag

    Du kannst den Tooltip durch Klicken & Ziehen bewegen, indem du MouseDown / MouseMove / MouseUp verwendest um bei diesen Aktionen den ToolTip zu bewegen, wenn diese Mausaktionen auf der Tooltipfläche stattfinden:

    Spoiler anzeigen
    [autoit]

    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    OnAutoItExitRegister('OnAutoItExit')

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

    Global Const $HC_ACTION = 0
    Global $hStub_MouseProc = DllCallbackRegister("_MouseProc", "long", "int;wparam;lparam")
    Global $hmod = _WinAPI_GetModuleHandle(0)
    Global $hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($hStub_MouseProc), $hmod)
    Global $fLeftPressDown = False, $fMove = False

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

    HotKeySet('^!{F9}', '_exit') ; Ctrl+Alt+F9 zum Beenden

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

    Global $fActive = False
    Global $hToolTip

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

    Global $sTitleToolTip = "Das ist ein Test" ; zwingend als Variable anlegen, um den richtigen Tooltip zu treffen

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

    ToolTip($sTitleToolTip)

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

    While True
    $hToolTip = _GetToolTipHwnd()
    If Not $fActive Then
    If $hToolTip <> 0 Then $fActive = True
    Else
    If Not $hToolTip Then $fActive = False
    EndIf
    Sleep(50)
    WEnd

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

    Func _GetToolTipHwnd()
    If WinExists($sTitleToolTip) Then
    Return WinGetHandle($sTitleToolTip)
    Else
    Return 0
    EndIf
    EndFunc

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

    Func _exit()
    Exit
    EndFunc

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

    Func _MouseProc($nCode, $wParam, $lParam)
    Local $event, $info, $iX, $iY
    $info = DllStructCreate("int X;int Y;dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo", $lParam)
    $iX = DllStructGetData($info, 1)
    $iY = DllStructGetData($info, 2)
    $mouseData = DllStructGetData($info, 3)
    If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    If $nCode = $HC_ACTION Then
    Switch $wParam
    Case $WM_MOUSEMOVE
    _ToolTipMove($iX, $iY)
    Case $WM_LBUTTONDOWN
    If _ToolTipMove($iX, $iY, True) = 1 Then $fLeftPressDown = True
    Case $WM_LBUTTONUP
    If _ToolTipMove($iX, $iY) = 1 Then
    $fLeftPressDown = False
    $fMove = False
    EndIf
    EndSwitch
    EndIf
    Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    EndFunc

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

    Func _ToolTipMove($_x, $_y, $_fSet=False)
    If $hToolTip = 0 Then Return 0
    Local $aPos = WinGetPos($hToolTip)
    Local Static $xLast, $yLast
    If $_fSet Then
    If $_x < $aPos[0] Or $aPos[0]+$aPos[2] < $_x Or $_y < $aPos[1] Or $aPos[1]+$aPos[3] < $_y Then Return 0
    $xLast = $_x
    $yLast = $_y
    $fMove = True
    Return 1
    EndIf
    If Not $fMove Then Return 0
    Local $xDiff = ($_x) - ($xLast)
    Local $yDiff = ($_y) - ($yLast)
    $xLast = $_x
    $yLast = $_y
    WinMove($hToolTip, '', $aPos[0]+($xDiff), $aPos[1]+($yDiff))
    Return 1
    EndFunc

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

    Func OnAutoItExit()
    _WinAPI_UnhookWindowsHookEx($hHook)
    DllCallbackFree($hStub_MouseProc)
    EndFunc ;==>OnAutoItExit

    [/autoit]