Jump to content

[SOLVED] ToolTip("") doesn't always hide the tooltip when it's set up to follow the mouse cursor


Recommended Posts

I have a weird problem with a ToolTip function.

It seems that I can't reliably remove a tooltip from the screen if I originally created it by setting a tooltip text via variable, not a straight up string.

 

Here's a simple script that I used for testing:

Spoiler
DllCall("user32.dll", "bool", "SetProcessDPIAware")

HotKeySet("{F1}", "DebugMode")
HotKeySet("{ESC}", "Terminate")

Global $debugMode
Global $mousePositionOld = [0, 0]
Global $toolTipMessage

While True
    If $debugMode == True Then
        Local $mousePosition = MouseGetPos()
        If $mousePosition[0] <> $mousePositionOld[0] Or $mousePosition[1] <> $mousePositionOld[1] Then
            DebugToolTip()
            $mousePositionOld = $mousePosition
        EndIf
    Else
        Sleep(100)
    EndIf
WEnd

Func DebugToolTip()
    Local $windowPosition = WinGetPos("[ACTIVE]")
    Local $mousePosition = MouseGetPos()
    $toolTipMessage = WinGetTitle("[ACTIVE]") & @LF & $mousePosition[0] - $windowPosition[0] & ", " & $mousePosition[1] - $windowPosition[1] & @LF & PixelGetColor($mousePosition[0], $mousePosition[1])
    ToolTip($toolTipMessage, $mousePosition[0] + 10, $mousePosition[1] + 10, "", 0, 4)
EndFunc

Func DebugMode()
    $debugMode = Not $debugMode
    If $debugMode == False Then
        ToolTip("")
        $mousePositionOld[0] = 0
        $mousePositionOld[1] = 0
        ClipPut($toolTipMessage)
    EndIf
EndFunc

Func Terminate()
    Exit
EndFunc

 

 

After I remade the script into this, it started working just fine (stopped working after I fixed the array comparison):

Spoiler
DllCall("user32.dll", "bool", "SetProcessDPIAware")

HotKeySet("{F1}", "DebugMode")
HotKeySet("{ESC}", "Terminate")

Global $debugMode
Global $mousePositionOld = [0, 0]

While True
    If $debugMode == True Then
        Local $mousePosition = MouseGetPos()
        If $mousePosition[0] <> $mousePositionOld[0] Or $mousePosition[1] <> $mousePositionOld[1] Then
            DebugToolTip()
            $mousePositionOld = $mousePosition
        EndIf
    Else
        Sleep(100)
    EndIf
WEnd

Func DebugToolTip()
    Local $mousePosition = MouseGetPos()
    Local $windowPosition = WinGetPos("[ACTIVE]")
    ToolTip(WinGetTitle("[ACTIVE]") & @LF & $mousePosition[0] - $windowPosition[0] & ", " & $mousePosition[1] - $windowPosition[1] & @LF & PixelGetColor($mousePosition[0], $mousePosition[1]), $mousePosition[0] + 10, $mousePosition[1] + 10, "", 0, 4)
EndFunc

Func DebugMode()
    $debugMode = Not $debugMode
    If $debugMode == False Then
        ToolTip("")
        $mousePositionOld[0] = 0
        $mousePositionOld[1] = 0
        Local $mousePosition = MouseGetPos()
        Local $windowPosition = WinGetPos("[ACTIVE]")
        ClipPut(WinGetTitle("[ACTIVE]") & @LF & $mousePosition[0] - $windowPosition[0] & ", " & $mousePosition[1] - $windowPosition[1] & @LF & PixelGetColor($mousePosition[0], $mousePosition[1]))
    EndIf
EndFunc

Func Terminate()
    Exit
EndFunc

 

 

Basic idea of the script:

You press F1 and a tooltip with some useful info shows up by the mouse cursor. It follows the cursor around until you press F1 again, then it copies the info to the clipboard and hides the tooltip.

 

It almost seems like if I created a tooltip using a variable to set the text, then ToolTip("") most of the times just repeats the previous use of ToolTip function. If you try to add Sleep(1000) before ToolTip("") in the first draft of the script, you'll see what i mean (if it works the same for everyone, that is).

 

Is this a bug or am I doing something wrong?

Edited by endtro
Link to comment
Share on other sites

First of all, do not compare arrays like you do (result of MouseGetPos).

#include <Constants.au3>

Local $arr1 = [1,2,3]
Local $arr2 = $arr1

MsgBox ($MB_SYSTEMMODAL, "", $arr1 = $arr2)

As you can see, = will always return False even if they are totally identical (and <> will always return True).  You need to compare individual elements of the array.

Also the operator == should only be used when comparing strings (look help file for it) as this is for case-sensitive equality.

I believe your problems come from badly using comparaison operators (untested though).

 

Link to comment
Share on other sites

1 hour ago, Nine said:

First of all, do not compare arrays like you do (result of MouseGetPos).

#include <Constants.au3>

Local $arr1 = [1,2,3]
Local $arr2 = $arr1

MsgBox ($MB_SYSTEMMODAL, "", $arr1 = $arr2)

As you can see, = will always return False even if they are totally identical (and <> will always return True).  You need to compare individual elements of the array.

Also the operator == should only be used when comparing strings (look help file for it) as this is for case-sensitive equality.

I believe your problems come from badly using comparaison operators (untested though).

Hey, thanks for the insight on how array comparison works! I've edited both versions of the script in the original post to fix these embarrassing errors, and unfortunately none of them work properly now! :)

But at least now I have a better understanding what's going on: the tooltip doesn't disappear if F1 is being pressed when previous mouse position is equal to the current mouse position. I think it's more pronounced on the first version of the script because it's somewhat more performant.

I'll keep looking into it! Thanks again!

Link to comment
Share on other sites

Fixed it!

While trying to figure out what's happening in the main loop I actually found a somewhat elegant solution to my problem.

DllCall("user32.dll", "bool", "SetProcessDPIAware")

HotKeySet("{F1}", "DebugMode")
HotKeySet("{ESC}", "Terminate")

Global $debugMode = False
Global $mousePositionOld = [Null, Null]
Global $toolTipMessage = ""

While True
    ;
    If $debugMode == True Then
        Local $mousePosition = MouseGetPos()
        If $mousePosition[0] <> $mousePositionOld[0] Or $mousePosition[1] <> $mousePositionOld[1] Then
            DebugToolTip($mousePosition[0], $mousePosition[1])
            $mousePositionOld = $mousePosition
        ; These lines fix the issue when the tooltip doesn't disappear if the mouse cursor is stationary when you press F1.
        ; I don't know why, I just tried to test what's happening when the mouse is moving and when it's not
        Else
            Sleep(10)
        ; ----------
        EndIf
    Else
        Sleep(100)
    EndIf
WEnd

Func DebugToolTip($mousePosition0, $mousePosition1)
    Local $windowPosition = WinGetPos("[ACTIVE]")
    $toolTipMessage = WinGetTitle("[ACTIVE]") & @LF & $mousePosition0 - $windowPosition[0] & ", " & $mousePosition1 - $windowPosition[1] & @LF & PixelGetColor($mousePosition0, $mousePosition1)
    ToolTip($toolTipMessage, $mousePosition0 + 10, $mousePosition1 + 10, "", 0, 4)
EndFunc

Func DebugMode()
    $debugMode = Not $debugMode
    If $debugMode == False Then
        ClipPut($toolTipMessage)
        $mousePositionOld[0] = Null
        $mousePositionOld[1] = Null
        ; This line fixes the issue when the tooltip sometimes doesn't disappear when F1 was pressed while the mouse cursor was moving.
        ; Not really sure what's going on, but it could be that the DebugMode function fired up from a hotkey removes the tooltip and then the main loop tunrs it back on (?). So theoretically I change the tooltip text variable from a hotkey to empty string so the main loop uses that insted of a string formed in the DebugToolTip function (?). This is the most coherent explaination I could come up with...
        $toolTipMessage = ""
        ; ----------
        ToolTip("")
    EndIf
EndFunc

Func Terminate()
    Exit
EndFunc

It does work very well, and the fixes are pretty simple and don't introduce any additional checks or calculations. Unfortunately I'm not entirely sure why this nonsense fixed anything.

I wrote a bunch comments inside the code body about the changes I made and what I think is going on.

Edited by endtro
Link to comment
Share on other sites

Just imagine you are pressing F1 right in between of $toolTipMessage = WinGetTitle("[ACTIVE]").... and ToolTip($toolTipMessage,.... when $debugMode is True (of course).  It very feasible since you are using long duration functions (WinGetTitle and PixelGetColor) when setting the message.

If you do not erase the message, it will still fire the tooltip but the boolean is now False so you do not set ToolTip("") until you pressed F1 again.

It works by setting the $tooTipMessage to Null because ToolTip ("", 100, 100, "", 0, 4) still erases the ToolTip.

Hope my explanations are clear.

ps.  Just remove your == it is terribly ugly, and replace with 

; If $debugMode == True Then  ; should become
If $debugMode Then

; If $debugMode == False Then ; should become
If Not $debugMode Then

:)

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

×
×
  • Create New...