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 post
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 post
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 post
Share on other sites
Posted (edited)

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 post
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 post
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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By MrCreatoR
      This UDF allows to set an events handler for Mouse device.
       
      The beginning...
      I searched for a way to disable the Mouse Primary click, and be able to call some function when the click event is received...
      Big thanks to amel27 for this one, i only organized the whole stuff to UDF style.
       
      Example:
      #include <GUIConstantsEx.au3> #include "MouseOnEvent.au3" HotKeySet("{ESC}", "_Quit") _Example_Intro() _Example_Limit_Window() Func _Example_Intro() MsgBox(64, "Attention!", "Let's set event function for mouse wheel *scrolling* up and down", 5) ;Set event function for mouse wheel *scrolling* up/down and primary button *down* action (call our function when the events recieved) _MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT, "_MouseWheel_Events") _MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT, "_MouseWheel_Events") _MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "_MousePrimaryDown_Event") Sleep(3000) ;UnSet the events _MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT) _MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT) _MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT) ToolTip("") MsgBox(64, "Attention!", "Now let's disable Secondary mouse button up action, and call our event function.", 5) _MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT, "_MouseSecondaryUp_Event", 0, 1) Sleep(5000) _MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT) ToolTip("") EndFunc Func _Example_Limit_Window() Local $hGUI = GUICreate("MouseOnEvent UDF Example - Restrict events on specific window") GUICtrlCreateLabel("Try to click on that specific GUI window", 40, 40, 300, 30) GUICtrlSetFont(-1, 12, 800) GUICtrlCreateLabel("Press <ESC> to exit", 10, 10) GUISetState() _MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "_MousePrimaryDown_Event", $hGUI) ;A little(?) bugie when you mix different events :( ;_MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT, "_MouseSecondaryUp_Event", $hGUI) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $GUI_EVENT_PRIMARYDOWN MsgBox(0, "", "Should not be shown ;)") EndSwitch WEnd _MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT) ;_MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT) EndFunc Func _MouseWheel_Events($iEvent) Switch $iEvent Case $MOUSE_WHEELSCROLLDOWN_EVENT ToolTip("Wheel Mouse Button (scrolling) DOWN Blocked") Case $MOUSE_WHEELSCROLLUP_EVENT ToolTip("Wheel Mouse Button (scrolling) UP Blocked") EndSwitch Return $MOE_BLOCKDEFPROC ;Block EndFunc Func _MousePrimaryDown_Event() ToolTip("Primary Mouse Button Down Blocked") Return $MOE_BLOCKDEFPROC ;Block EndFunc Func _MouseSecondaryUp_Event() ToolTip("Secondary Mouse Button Up Blocked") EndFunc Func _Quit() Exit EndFunc  
      Available Events Constants:
       
      ------------------------------------------
      CHANGELOG:
      Download:
      Attached:     MouseOnEvent_2.4.zip
      Old version:
      MouseOnEvent.zip - v2.3
      MouseOnEvent_2.1.zip
      MouseOnEvent_2.0.zip
      MouseOnEvent_UDF_1.9.zip
      MouseSetOnEvent_UDF_1.8.zip
      MouseSetOnEvent_UDF_1.7.zip
      MouseSetOnEvent_UDF_1.6.zip
      MouseSetOnEvent_UDF_1.5.zip
      MouseSetOnEvent_UDF_1.4.zip
      MouseSetOnEvent_UDF_1.3.zip
      Previous downloads: 146 + 200 + 804
      MouseOnEvent.zip
      MouseOnEvent.zip
    • By CarlD
      Update: Download the latest version here.
      As my first stab at GUI scripting, I'm trying to write a simple graphical interface for Grep for Windows. I have a basic GUI, but I'm stuck on one point and nothing I've tried so far works. The sticking point is that while the Tab key works to move focus from one input control to the next, clicking the mouse on any but the first input does nothing. This seems like a basic feature of GUI functionality that should work out of the box (like Tab), but clearly I'm missing something. I tried (among many other things) Melba23's technique in the post below, but this doesn't do what I'm after -- getting the left click to set the insertion point for user input. Would greatly appreciate a pointer or two. 😉
      Here's my code so far:
      ; Grep for Windows -- GUI [CLD] #include <AutoItConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> Opt("WinTitleMatchMode", -2) #cs FileInstall("X:\nix\search1.ico", @TempDir & "\search1.ico") FileInstall("X:\nix\grep.exe", @TempDir & "\grep.exe") FileInstall("X:\nix\sed.exe", @TempDir & "\sed.exe") FileInstall("X:\nix\libiconv2.dll", @TempDir & "\libiconv2.dll") FileInstall("X:\nix\libintl3.dll", @TempDir & "\libintl3.dll") FileInstall("X:\nix\pcre3.dll", @TempDir & "\pcre3.dll") FileInstall("X:\nix\regex2.dll", @TempDir & "\regex2.dll") #ce ; $sDefFs = @ScriptDir & "\.txt" $sOut = "" $iX = 20 $iY = 20 $hgGGrep = GUICreate("Grep for Windows: Simple TeXT search", 600, 600) GUISetState(@SW_SHOW, $hgGGrep) ; Obtain value of control: GUICtrlRead() ; left, top, width, height ; $iX, $iY, $iX + n, $iY + m ; $hgIco = GUICtrlCreateIcon(@ScriptDir & "\search1.ico", $iX, $iY, 10) $hgGL0 = GUICtrlCreateLabel("Enter a string or regular expression" & @CRLF & "(space between words means ""OR"")", $iX + 50, $iY, 250, 30) $hgSch = GUICtrlCreateInput("", $iX + 50, $iY + 40, 325, 20, $GUI_SS_DEFAULT_INPUT, -1) $hgXyZ = GUICtrlCreateCheckbox("cAsE-sEnSiTiVe", $iX + 50, $iY + 65, -1, -1) $hgExe = GUICtrlCreateButton("Search", 400, $iY + 40, -1, -1) $hgFL1 = GUICtrlCreateLabel("Filespec", $iX + 50, $iY + 100, 250, 20) $hgFs1 = GUICtrlCreateInput("d:\path\*.txt", $iX + 110, $iY + 100, 250, 20, $GUI_SS_DEFAULT_INPUT, -1) $hgFL2 = GUICtrlCreateLabel("Filespec", $iX + 50, $iY + 120, 250, 20) $hgFs2 = GUICtrlCreateInput("", $iX + 110, $iY + 120, 250, 20, $GUI_SS_DEFAULT_INPUT, -1) $hgFL3 = GUICtrlCreateLabel("Filespec", $iX + 50, $iY + 140, 250, 20) $hgFs3 = GUICtrlCreateInput("", $iX + 110, $iY + 140, 250, 20, $GUI_SS_DEFAULT_INPUT,-1) $hgOut = GUICtrlCreateEdit($sOut, 25, 190, 550, 400, $ES_LEFT, -1) GUICtrlSetState($hgSch, $GUI_FOCUS) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd ; #cs _WinAPI_SetFocus(ControlGetHandle("Grep for Windows", "", $hgSch)) _WinAPI_SetFocus(ControlGetHandle("Grep for Windows", "", $hgFs1)) _WinAPI_SetFocus(ControlGetHandle("Grep for Windows", "", $hgFs2)) _WinAPI_SetFocus(ControlGetHandle("Grep for Windows", "", $hgFs3)) #ce Thanks in advance.
    • By WoodGrain
      Hi guys,
       
      I've written a script that will move my mouse to a location on the screen whenever my remote access software becomes active, the problem I have is that as soon as the remote access software becomes active it appears to capture the mouse and keyboard so nothing happens when I use MouseMove().
       
      Is there any way around this?
       
      Thanks!
    • By badcoder123
      Hey, all.  
      I've been looking for a way to change cursor colour but not the cursor itself. I've been looking for a couple hours now and can't find anything.  I also don't even know where to start, if anyone has any tips or examples please comment them.
      Thanks
    • By ohaya
      Hi,
      I am still really new with AutoIT.  We are using it to automate logging into web sites and I have encountered problems with focus.  The target web page is configured to put the cursor into the first text field (username) when the page is loaded, and when I run the AutoIT script, which does the log in seems like it is just not starting where I expect it to be.  
      I have been kind of using ToolTip() to kind of help with debugging, but now I am wondering if the calls to ToolTip() are causing the focus to be messed up.  
      For example, at least visually, when the ToolTip() is called, I can see the cursor disappear from the web page text field and they when I do anything that is supposed to send keystrokes, they are going off somwhere else ("never-neverland").
      But when I remove some of the ToolTip() calls, it works correctly.
      So the questions I have are:
      1) Do the ToolTip() calls interfere with/change where the focus on the target page are?
      2) In general, what are the "rules" for where ToolTip can be used "safely" (== doesn't interfere with focus)?
      Thanks,
      Jim
       
×
×
  • Create New...