Jump to content

Get tooltip text


jake
 Share

Recommended Posts

I am attempting to retrieve the tooltip text from a minimised program (or running behind other windows) however i'm not getting very far.

I've tried using the _GUIToolTip_GetText function however the control I want to get the tooltip from does not have an ID that is required by the function.

The Window Info program returns the following information about the control.

>>>> Control <<<<
Class:  Button
Instance:   2
ClassnameNN:    Button2
Advanced (Class):   [CLASS:Button; INSTANCE:2]
ID: 
Text:   
Position:   5, 433
Size:   22, 21
ControlClick Coords:    5, 11
Style:  0x5000000B
ExStyle:    0x00000000
Handle: 0x001F0636

Is there an alternative method to get the tooltip text?

Link to comment
Share on other sites

I am attempting to retrieve the tooltip text from a minimised program (or running behind other windows) however i'm not getting very far.

I've tried using the _GUIToolTip_GetText function however the control I want to get the tooltip from does not have an ID that is required by the function.

The Window Info program returns the following information about the control.

>>>> Control <<<<
Class:  Button
Instance:   2
ClassnameNN:    Button2
Advanced (Class):   [CLASS:Button; INSTANCE:2]
ID: 
Text:   
Position:   5, 433
Size:   22, 21
ControlClick Coords:    5, 11
Style:  0x5000000B
ExStyle:    0x00000000
Handle: 0x001F0636

Is there an alternative method to get the tooltip text?

What program is it? That might not be an actual ToolTip control attached to the Button2 control. It might just be a mouse-over event triggering a separate ToolTip window. I have posted an example that gets the ToolTip text from the System Tray toolbar control's buttons, but I'm not sure tooltips can be attached that way outside of a toolbar.

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

I'm attempting to retrieve the signal strength from my mobile broaband software, "Virgin Mobile Broadband Home".

The signal strength is only displayed in a tooltip when you hover over the signal icon from the main window.

This bit of code by "martin" picks it up however I don't think this will work when not hovering over the tooltip.

#include <array.au3>
#include <windowsconstants.au3>

$lastList = ''
$gui = GUICreate("test tool tip reading")
$but1 = GUICtrlCreateButton("sample button",50,50,120,22)
GUICtrlSetTip(-1,"this is the tooltip for $But1")
$but2 = GUICtrlCreateButton("Another one",50,150,120,22)
GUICtrlSetTip(-1,"Tooltip for $but2, but try controls in any other app too.")
GUISetState()
While GUIGetMsg() <> -3
    
    $List = ''
    $wl = WinList("[class:tooltips_class32]");get all th etooltips

    For $n = 1 To $wl[0][0]
        If BitAND(WinGetState($wl[$n][1]), 2) Then;if visible
            $List &= WinGetTitle($wl[$n][1]) & '; '; read the title, which for a tooltip is the text
        EndIf
    Next
        If $List <> $lastList And $List <> '' Then
            ConsoleWrite($List & "Previous = " & $lastlist & @CRLF)
            $lastList = $List
        EndIf

WEnd
Link to comment
Share on other sites

I'm attempting to retrieve the signal strength from my mobile broaband software, "Virgin Mobile Broadband Home".

The signal strength is only displayed in a tooltip when you hover over the signal icon from the main window.

This bit of code by "martin" picks it up however I don't think this will work when not hovering over the tooltip.

The problem with GuiCtrlSetTip() is that you don't get the handle to the tooltip back, and I can't see how to get that after the fact. This demo almost does the job:
#include <GuiToolBar.au3>
#include <GuiToolTip.au3>
#include <array.au3>
#include <windowsconstants.au3>

Global $hGUI = GUICreate("test tool tip reading")

Global $idButton1 = GUICtrlCreateButton("sample button", 50, 50, 120, 22)
Global $hButton1 = ControlGetHandle($hGUI, "", $idButton1)
Global $hToolTip1 = _GUIToolTip_Create($hButton1)
_GUIToolTip_AddTool($hToolTip1, $hGUI, "Button One:  This is the tooltip for Button1")
_GUIToolTip_Activate($hToolTip1)

Global $idButton2 = GUICtrlCreateButton("Another one", 50, 150, 120, 22)
Global $hButton2 = ControlGetHandle($hGUI, "", $idButton2)
Global $hToolTip2 = _GUIToolTip_Create($hButton2)
_GUIToolTip_AddTool($hToolTip2, $hGUI, "Button Two:  This is the tooltip for Button2")
_GUIToolTip_Activate($hToolTip2)

GUISetState()
Sleep(1000)
GUISetState(@SW_MINIMIZE)

HotKeySet("x", "_CheckToolTip")

Do
    Sleep(10)
Until GUIGetMsg() = -3

Func _CheckToolTip()
    Local $iToolCount1, $iToolCount2, $sToolText, $avToolInfo
    
; Verify the globals
    ConsoleWrite("Debug: $hGUI = " & $hGUI & @LF)
    ConsoleWrite("Debug: $hButton1 = " & $hButton1 & @LF)
    ConsoleWrite("Debug: $hButton2 = " & $hButton2 & @LF)
    ConsoleWrite("Debug: $hToolTip1 = " & $hToolTip1 & @LF)
    ConsoleWrite("Debug: $hToolTip2 = " & $hToolTip2 & @LF)

; Get count of tools in ToolTips
    $iToolCount1 = _GUIToolTip_GetToolCount($hToolTip1)
    ConsoleWrite("Debug: $iToolCount1 = " & $iToolCount1 & @LF)
    $iToolCount2 = _GUIToolTip_GetToolCount($hToolTip2)
    ConsoleWrite("Debug: $iToolCount2 = " & $iToolCount2 & @LF)

; List text of all the tools in the ToolTips
    For $n = 0 To $iToolCount1 - 1
        $sToolText = _GUIToolTip_GetText($hToolTip1, $hGUI, $n); window handle first
        ConsoleWrite("Debug: Button1 " & $n & ":  " & $sToolText & @LF)
        $avToolInfo = _GUIToolTip_GetToolInfo($hToolTip1, $hGUI, $n)
        _ArrayDisplay($avToolInfo, "$avToolInfo, Button1, Tool: " &  $n)
    Next
    For $n = 0 To $iToolCount2 - 1
        $sToolText = _GUIToolTip_GetText($hToolTip2, $hGUI, $n); tooltip handle first
        ConsoleWrite("Debug: Button2 " & $n & ":  " & $sToolText & @LF)
        $avToolInfo = _GUIToolTip_GetToolInfo($hToolTip1, $hGUI, $n)
        _ArrayDisplay($avToolInfo, "$avToolInfo, Button1, Tool: " &  $n)
    Next
EndFunc  ;==>_CheckToolTip

The text is read from the tips by two different methods, even if the window is minimized.

Two problems:

1. The actual tips don't come up in the demo GUI when you mouse over the buttons, and I don't know why.

2. If it is the window from another app, I don't know how you'll get the ToolTip handles you need.

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Here's a screenshot of the tooltip text i'm trying to retrieve if it helps.

Oh, you may be in luck! That looks like a status bar, and there is a function for that: _GUICtrlStatusBar_GetTipText()

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

@Jake

if the status bar function PsaltyDS suggested doesn't pan out, try this.

as Martin's example works with your app, the tooltips are tooltips_class32 and not some custom class, so this should work.

finds tooltip handle for given application window title or handle and tooltip text to search for (app can be minimized, or behind window)

note: some tooltips have text when hidden (as in this media player demo), others are created only when triggered by mouseover.

same goes for tray icon tooltips, some only have tooltip text after mouseover.

a window can have one tooltip control and many tooltips,

or many tooltip controls with one or more tooltips per control (Windows Media Player).

YMMV

some button tooltips may not be readable at all,

or your going to have to use mouse control

to hover over the button first to activate the tooltip.

good luck

Edit forgot to kill the timer

#include <WinAPI.au3>
#include <GUIConstantsEX.au3>
#include <WindowsConstants.au3>
#include <Timers.au3>
#include <GuiToolTip.au3>


Opt("MustDeclareVars", 1)


Global $sLastTitle, $hTooltip, $sBuffer, $iToolCount, $aTip, $iTimer
Global $hWIN, $hGUI, $Msg, $sTooltipText, $sTitle, $hStub_EnumChildProc


;$sTooltipText = "Signal strength"
;$sTitle = "Virgin Mobile Broadband Home";  title of your app or use class from windows info tool

$sTooltipText = "Select playlist options"
$sTitle = "Windows Media Player"

Run(@ProgramFilesDir & "\Windows Media Player\wmplayer.exe")
Sleep(2000)


$hWIN = WinGetHandle($sTitle)
ConsoleWrite('!Title: ' & $sTitle & @CRLF)
ConsoleWrite('!hWnd: ' & $hWIN & @CRLF)
If Not IsHWnd($hWIN) Then Exit

$hStub_EnumChildProc = DllCallbackRegister("_EnumChildProc", "int", "hwnd;ptr")
DllCall("user32.dll", "int", "EnumChildWindows", "hwnd", _WinAPI_GetDesktopWindow(), _
        "ptr", DllCallbackGetPtr($hStub_EnumChildProc), "ptr", 0)

;continue to main loop after enumerating tooltips
DllCallbackFree($hStub_EnumChildProc)
If Not IsHWnd($hTooltip) Then Exit
$iToolCount = _GUIToolTip_GetToolCount($hTooltip)
ConsoleWrite('-Tooltip control hWnd: ' & $hTooltip & @CRLF)
ConsoleWrite('-Tooltip count: ' & $iToolCount & @CRLF & @CRLF)
If Not $iToolCount Then Exit

; for scripts without a GUI form - hwnd from GUI form needed for Timers UDF
AutoItWinSetTitle("Timer-Test"); rename hidden window 'AutoIt v3'
$hGUI = WinGetHandle("Timer-Test", ""); get handle of hidden window for Timers UDF
Local $iTimer = _Timer_SetTimer($hGUI, 2000, "_Timer"); create timer and set polling rate

Sleep(5000)
_GUIToolTip_UpdateTipText($hTooltip, $aTip[1], $aTip[2], "Changed tooltip 'Select playlist options'")
;_GUIToolTip_Update($hTooltip)
ConsoleWrite("+Tooltip text: " & $aTip[0] & @CRLF)

While 1
    $Msg = GUIGetMsg()
    Switch $Msg
        Case $GUI_EVENT_CLOSE
                        _Timer_KillTimer($hGUI, $iTimer)
            Exit
    EndSwitch
WEnd

Func _Timer($hWnd, $Msg, $iIDTimer, $dwTime); polled every 2 seconds
    #forceref $hWnd, $Msg, $iIDTimer, $dwTime
    If IsHWnd($hTooltip) And WinExists($hWIN) Then
        For $i1 = 0 To $iToolCount - 1
            $aTip = _GUIToolTip_EnumToolsText($hTooltip, $i1)
    ;_GUIToolTip_GetTitleText($hTooltip)
    ;_GUIToolTip_Update($hTooltip)
    ;If StringInStr($aTip[0], $sTooltipText) Then
            If $sBuffer <> $aTip[0] Then
        ;Beep(1000,5)
                $sBuffer = $aTip[0]
                ConsoleWrite("+Tooltip text: " & $sBuffer & @CRLF)
            EndIf
    ;EndIf
        Next
    Else
        Exit
    EndIf
EndFunc ;==>_Timer

Func _GUIToolTip_EnumToolsText($hWnd, $iIndex)
;combined _GUIToolTip_EnumTools() and _GUIToolTip_GetText()
    Local $aRet[3], $iToolInfo, $pToolInfo, $tToolInfo, _
            $pBuffer, $tBuffer, $pMemory, $tMemMap, $fResult, $pText

    $tBuffer = DllStructCreate("wchar Text[4096]")
    $pBuffer = DllStructGetPtr($tBuffer)
    $tToolInfo = DllStructCreate($tagTOOLINFO)
    $pToolInfo = DllStructGetPtr($tToolInfo)
    $iToolInfo = DllStructGetSize($tToolInfo)
    
    DllStructSetData($tToolInfo, "Size", $iToolInfo)
    If Not IsHWnd($hWnd) Then Return ""; when closing app sometimes meminit error message complains about invalid handle
    $pMemory = _MemInit($hWnd, $iToolInfo, $tMemMap)
    _MemWrite($tMemMap, $pToolInfo, $pMemory, $iToolInfo)
    _SendMessage($hWnd, $TTM_ENUMTOOLSW, $iIndex, $pMemory, 0, "wparam", "ptr")
    _MemRead($tMemMap, $pMemory, $pToolInfo, $iToolInfo)
    _MemFree($tMemMap)

    If Not IsHWnd($hWnd) Then Return ""; when closing app sometimes meminit error message complains about invalid handle
    $pMemory = _MemInit($hWnd, $iToolInfo + 4096, $tMemMap)
    $pText = $pMemory + $iToolInfo
    DllStructSetData($tToolInfo, "Text", $pText)
    _MemWrite($tMemMap, $pToolInfo, $pMemory, $iToolInfo)
    _SendMessage($hWnd, $TTM_GETTEXTW, 0, $pMemory, 0, "wparam", "ptr")
    _MemRead($tMemMap, $pText, $pBuffer, 81)
    _MemFree($tMemMap)

    $aRet[0] = DllStructGetData($tBuffer, "Text")
    $aRet[1] = DllStructGetData($tToolInfo, "hWnd")
    $aRet[2] = DllStructGetData($tToolInfo, "ID")

    Return $aRet
EndFunc ;==>_GUIToolTip_EnumToolsText


Func _EnumChildProc($hWnd, $lParam)
    $hWnd = HWnd($hWnd)
    Local $sClass = _WinAPI_GetClassName($hWnd)
    If $sClass = "tooltips_class32" Then
        Local $hParent = _WinAPI_GetAncestor($hWnd, $GA_ROOTOWNER)
;$hParent = _WinAPI_GetParent($hWnd)
        If $hParent = $hWIN Then
            
;~          $sParentTitle = WinGetTitle($hParent)
;~          If $sLastTitle <> $sParentTitle Then
;~              ConsoleWrite('+Window Title = ' & $sParentTitle & @CRLF)
;~              ConsoleWrite('+Window Hwnd = ' & $hParent & @crlf & @crlf)
;~              $sLastTitle = $sParentTitle
;~          EndIf
;~          ConsoleWrite('-' & $sClass & @crlf)
;~          ConsoleWrite('+Toolcontrol hwnd  = ' & $hWnd & @crlf)
;~          ConsoleWrite('+ToolExists = ' & _GUIToolTip_ToolExists($hWnd) & @crlf); visible = True, hidden = False
            
            $iToolCount = _GUIToolTip_GetToolCount($hWnd); get tooltip count per tool control
    ;ConsoleWrite('+Tooltip GetToolCount  = ' & $iToolCount & @crlf)
            For $i1 = 0 To $iToolCount - 1; enumerate text of all tooltips for a tooltip control (can be 1 or more per control)
                $aTip = _GUIToolTip_EnumToolsText($hWnd, $i1)
        ;ConsoleWrite("+Tooltip text " & $i1 & " = " & $aTip[0] & @CRLF)
                If StringInStr($aTip[0], $sTooltipText) Then
                    $hTooltip = $hWnd
                    Return 1
                EndIf
            Next
        EndIf
    EndIf
    Return 1
EndFunc ;==>_EnumChildProc
Edited by rover

I see fascists...

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...