Change all instances of MouseX + 16 to MouseX + 75mstrauss2021 wrote: ↑24 Jun 2021, 12:12Still using this script and loving it.
Got everything working the way I want, however...
I have the tooltip always following the mouse which is good, but now I realize the tooltip is kind of getting in the way.
I've read the comments in the script and tried altering X variable but no change.
How can I add 75 to the X position of the tooltip and which line needs to be changed?
[Function] FFToolTip: Flicker-Free ToolTip
Re: [Function] FFToolTip: Flicker-Free ToolTip
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)
-
- Posts: 30
- Joined: 13 Feb 2021, 10:34
Re: [Function] FFToolTip: Flicker-Free ToolTip
Beautiful, thank you
-
- Posts: 1
- Joined: 22 Oct 2021, 13:06
Re: [Function] FFToolTip: Flicker-Free ToolTip
Thanks for writing this excellent code iPhilip. I've been using it for years. Unfortunately, updates made to AHK v2 (somewhere between AHK 2.0-a100-52515e2 and the current AHK 2.0-beta.2) caused the v2 versions in the original post to not work. I managed to modify the code for my own use so that it works with the current version of the AHK v2 beta and I feel I spent way too much time on it to not upload my results for others. I don't have enough of a grasp of DllCalls and Buffer objects to believe my modifications are optimal and/or fully efficient, but at least it works.
Basically, here's the code that iPhilip had labeled as "AHK v2 versions: Here is the function for single-monitor configurations:" with my modifications:
And here's a summary of the lines I changed:
Again, thanks iPhilip for the excellent code. I'm glad I was able to tweak it so I could continue using it with the current AHK v2.
Basically, here's the code that iPhilip had labeled as "AHK v2 versions: Here is the function for single-monitor configurations:" with my modifications:
Code: Select all
; ===============================================================================================================================
; FFToolTip(Text:="", X:="", Y:="", WhichToolTip:=1)
; Function: Creates a tooltip window anywhere on the screen. Unlike the built-in ToolTip function, calling this function
; repeatedly will not cause the tooltip window to flicker. Otherwise, it behaves the same way. Use this function
; without the first three parameters, i.e. FFToolTip(), in order to hide the tooltip.
; Parameters: Text - The text to display in the tooltip. To create a multi-line tooltip, use the linefeed character (`n) in
; between each line, e.g. Line1`nLine2. If blank or omitted, the existing tooltip will be hidden.
; X - The x position of the tooltip. This position is relative to the active window, the active window's client
; area, or the entire screen depending on the coordinate mode (see the CoordMode function). In the default
; mode, the coordinates that are relative to the active window.
; Y - The y position of the tooltip. See the above X parameter for more information. If both the X and Y
; coordinates are omitted, the tooltip will be shown near the mouse cursor.
; WhichToolTip - A number between 1 and 20 to indicate which tooltip window to operate upon. If unspecified, the
; default is 1.
; Return values: None
; Global vars: None
; Dependencies: None
; Tested with: AHK 2.0-beta.2
; Tested on: Win 7 (x64)
; Written by: iPhilip
; ===============================================================================================================================
; MSDN Links:
; https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getcursorpos - GetCursorPos function
; https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-clienttoscreen - ClientToScreen function
; https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-movewindow - MoveWindow function
; ===============================================================================================================================
FFToolTip(Text:="", X:="", Y:="", WhichToolTip:=1) {
static ID := [], Xo:=0, Yo:=0, W:=0, H:=0, SavedText:=""
, PID := DllCall("GetCurrentProcessId")
, Point := Buffer(8)
if (Text = "") { ; Hide the tooltip
ToolTip , , , WhichToolTip
ID.Delete(WhichToolTip)
} else if not ID.Has(WhichToolTip) { ; First call
ToolTip Text, X, Y, WhichToolTip
ID.Length := Max(ID.Length, WhichToolTip)
ID[WhichToolTip] := WinExist("ahk_class tooltips_class32 ahk_pid " PID)
WinGetPos , , &W, &H, "ahk_id " ID[WhichToolTip]
SavedText := Text
} else if (Text != SavedText) { ; The tooltip text changed
ToolTip Text, X, Y, WhichToolTip
WinGetPos , , &W, &H, "ahk_id " ID[WhichToolTip]
SavedText := Text
} else { ; The tooltip is being repositioned
if (Flag := X = "" || Y = "") {
DllCall("GetCursorPos", "Ptr", Point.Ptr, "Int")
MouseX := NumGet(Point, 0, "Int")
MouseY := NumGet(Point, 4, "Int")
}
;
; Convert input coordinates to screen coordinates
;
if (A_CoordModeToolTip = "Window") {
WinGetPos &WinX, &WinY, , , "A"
X := X = "" ? MouseX + 16 : X + WinX
Y := Y = "" ? MouseY + 16 : Y + WinY
} else if (A_CoordModeToolTip = "Client") {
DllCall("ClientToScreen", "Ptr", WinExist("A"), "Ptr", Point.Ptr, "Int")
X := X = "" ? MouseX + 16 : NumGet(Point, 0, "Int")
Y := Y = "" ? MouseY + 16 : NumGet(Point, 4, "Int")
} else { ; A_CoordModeToolTip = "Screen"
X := X = "" ? MouseX + 16 : X
Y := Y = "" ? MouseY + 16 : Y
}
;
; Deal with the bottom and right edges of the screen
;
if Flag {
X := X + W >= A_ScreenWidth ? A_ScreenWidth - W - 1 : X
Y := Y + H >= A_ScreenHeight ? A_ScreenHeight - H - 1 : Y
if (MouseX >= X && MouseX <= X + W && MouseY >= Y && MouseY <= Y + H)
X := MouseX - W - 3, Y := MouseY - H - 3
}
;
; If necessary, store the coordinates and move the tooltip window
;
if (X != Xo || Y != Yo) {
Xo := X, Yo := Y
DllCall("MoveWindow", "Ptr", ID[WhichToolTip], "Int", X, "Int", Y, "Int", W, "Int", H, "Int", false, "Int")
}
}
}
Code: Select all
static ID := [], Xo, Yo, W, H, SavedText -> static ID := [], Xo:=0, Yo:=0, W:=0, H:=0, SavedText:=""
, _ := VarSetCapacity(Point, 8) -> , Point := Buffer(8) ; VarSetCapacity is deprecated now and instead Buffer objects must be used
} else if not ID[WhichToolTip] { ; First call -> } else if not ID.Has(WhichToolTip) { ; First call ; arrays were changed so that to check for the existence of an element, we now must use the Has function
[nothing] -> ID.Length := Max(ID.Length, WhichToolTip) ; this line is needed before "ID[WhichToolTip] := ...", since arrays were changed to require that their length be increased before a new element can be added and its value set
DllCall("GetCursorPos", "Ptr", &Point, "Int") -> DllCall("GetCursorPos", "Ptr", Point.Ptr, "Int") ; since Point is now a buffer object, it needs to be referenced differently
NumPut(X, Point, 0, "Int"), NumPut(Y, Point, 4, "Int") -> ; deleted, the line was breaking the code and strangely didn't seem to affect the end result
DllCall("ClientToScreen", "Ptr", WinExist("A"), "Ptr", &Point, "Int") -> DllCall("ClientToScreen", "Ptr", WinExist("A"), "Ptr", Point.Ptr, "Int") ; since Point is now a buffer object, it needs to be referenced differently
; I also peppered the code with &'s before variable names wherever not doing so was generating errors.
Re: [Function] FFToolTip: Flicker-Free ToolTip
Buffer objects can (and should) be passed directly to Ptr parameters of DllCalls. There are optimizations in place for this.
Re: [Function] FFToolTip: Flicker-Free ToolTip
Great script. Works perfectly on Win 7.
Re: [Function] FFToolTip: Flicker-Free ToolTip
I'm learning how to implement Functions in scripts. Can you show me how to put it in:
Code: Select all
#Persistent
SetTimer, WatchCursor, 500
Return
WatchCursor:
MouseGetPos, , , id, control
WinGetTitle, title, ahk_id %id%
WinGetClass, class, ahk_id %id%
ControlGetFocus, ActiveWin, A
ToolTip, Unique ID: ahk_id %id%`nTitle
: %title%`nClass
: ahk_class %class%`nControl
: %control%`nActive Control
: %ActiveWin%`n`nCTRL+WIN+T to Toggle On
and Off
or `nCTRL+F12 to Copy to Clipboard
FFToolTip()
Return
^#T::
SetTimer, WatchCursor, % (Toggle:=!Toggle)
? "Off" : "On"
If Toggle
ToolTip
Return
^F12::ClipBoard := "Unique ID: ahk_id " . id
. "`r" . "Title: " . title
. "`r" . "Class: ahk_class" . class
. "`r" . "Control: "
. "Active Control: " . ActiveWin
. control . "`r"
Re: [Function] FFToolTip: Flicker-Free ToolTip
Sure. Does the code below help?
Code: Select all
#Persistent
SetTimer, WatchCursor, 500
Return
WatchCursor:
MouseGetPos, , , id, control
WinGetTitle, title, ahk_id %id%
WinGetClass, class, ahk_id %id%
ControlGetFocus, ActiveWin, A
FFToolTip("Unique ID: ahk_id " id "`n"
. "Title: " title "`n"
. "Class: ahk_class " class "`n"
. "Control: " control "`n"
. "Active Control: " ActiveWin "`n`n"
. "CTRL+WIN+T to Toggle On and Off or`n"
. "CTRL+F12 to Copy to Clipboard")
Return
^#T::
SetTimer, WatchCursor, % (Toggle:=!Toggle)
? "Off" : "On"
If Toggle
FFToolTip()
Return
^F12::ClipBoard := "Unique ID: ahk_id " . id
. "`r" . "Title: " . title
. "`r" . "Class: ahk_class" . class
. "`r" . "Control: "
. "Active Control: " . ActiveWin
. control . "`r"
; ===============================================================================================================================
; FFToolTip(Text:="", X:="", Y:="", WhichToolTip:=1)
; Function: Creates a tooltip window anywhere on the screen. Unlike the built-in ToolTip command, calling this function
; repeatedly will not cause the tooltip window to flicker. Otherwise, it behaves the same way. Use this function
; without the first three parameters, i.e. FFToolTip(), in order to hide the tooltip.
; Parameters: Text - The text to display in the tooltip. To create a multi-line tooltip, use the linefeed character (`n) in
; between each line, e.g. Line1`nLine2. If blank or omitted, the existing tooltip will be hidden.
; X - The x position of the tooltip. This position is relative to the active window, the active window's client
; area, or the entire screen depending on the coordinate mode (see the CoordMode command). In the default
; mode, the coordinates that are relative to the active window.
; Y - The y position of the tooltip. See the above X parameter for more information. If both the X and Y
; coordinates are omitted, the tooltip will be shown near the mouse cursor.
; WhichToolTip - A number between 1 and 20 to indicate which tooltip window to operate upon. If unspecified, the
; default is 1.
; Return values: None
; Global vars: None
; Dependencies: None
; Tested with: AHK 1.1.30.01 (A32/U32/U64)
; Tested on: Win 7 (x64)
; Written by: iPhilip
; ===============================================================================================================================
; MSDN Links:
; https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getcursorpos - GetCursorPos function
; https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-clienttoscreen - ClientToScreen function
; https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-movewindow - MoveWindow function
; ===============================================================================================================================
FFToolTip(Text:="", X:="", Y:="", WhichToolTip:=1) {
static ID := [], Xo, Yo, W, H, SavedText
, PID := DllCall("GetCurrentProcessId")
, _ := VarSetCapacity(Point, 8)
if (Text = "") { ; Hide the tooltip
ToolTip, , , , WhichToolTip
ID.Delete(WhichToolTip)
} else if not ID[WhichToolTip] { ; First call
ToolTip, %Text%, X, Y, WhichToolTip
ID[WhichToolTip] := WinExist("ahk_class tooltips_class32 ahk_pid " PID)
WinGetPos, , , W, H, % "ahk_id " ID[WhichToolTip]
SavedText := Text
} else if (Text != SavedText) { ; The tooltip text changed
ToolTip, %Text%, X, Y, WhichToolTip
WinGetPos, , , W, H, % "ahk_id " ID[WhichToolTip]
SavedText := Text
} else { ; The tooltip is being repositioned
if (Flag := X = "" || Y = "") {
DllCall("GetCursorPos", "Ptr", &Point, "Int")
MouseX := NumGet(Point, 0, "Int")
MouseY := NumGet(Point, 4, "Int")
}
;
; Convert input coordinates to screen coordinates
;
if (A_CoordModeToolTip = "Window") {
WinGetPos, WinX, WinY, , , A
X := X = "" ? MouseX + 16 : X + WinX
Y := Y = "" ? MouseY + 16 : Y + WinY
} else if (A_CoordModeToolTip = "Client") {
NumPut(X, Point, 0, "Int"), NumPut(Y, Point, 4, "Int")
DllCall("ClientToScreen", "Ptr", WinExist("A"), "Ptr", &Point, "Int")
X := X = "" ? MouseX + 16 : NumGet(Point, 0, "Int")
Y := Y = "" ? MouseY + 16 : NumGet(Point, 4, "Int")
} else { ; A_CoordModeToolTip = "Screen"
X := X = "" ? MouseX + 16 : X
Y := Y = "" ? MouseY + 16 : Y
}
;
; Deal with the bottom and right edges of the screen
;
if Flag {
X := X + W >= A_ScreenWidth ? A_ScreenWidth - W - 1 : X
Y := Y + H >= A_ScreenHeight ? A_ScreenHeight - H - 1 : Y
if (MouseX >= X && MouseX <= X + W && MouseY >= Y && MouseY <= Y + H)
X := MouseX - W - 3, Y := MouseY - H - 3
}
;
; If necessary, store the coordinates and move the tooltip window
;
if (X != Xo || Y != Yo) {
Xo := X, Yo := Y
DllCall("MoveWindow", "Ptr", ID[WhichToolTip], "Int", X, "Int", Y, "Int", W, "Int", H, "Int", false, "Int")
}
}
}
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)
Re: [Function] FFToolTip: Flicker-Free ToolTip
@iPhilip Perfect, thanks.
Re: [Function] FFToolTip: Flicker-Free ToolTip
You are welcome.
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)
Re: [Function] FFToolTip: Flicker-Free ToolTip
You might consider replacing all of the positioning logic with a single call to CalculatePopupWindowPosition, assuming you don't need to support Windows XP or older. It transparently supports multiple monitors, even if they have different DPI settings (which causes this script some trouble). I've demonstrated how to do it for v2 here. For v1, there's WinMoveZ by SKAN.
Re: [Function] FFToolTip: Flicker-Free ToolTip
Thank you, @lexikos. I will look into it.lexikos wrote: ↑30 Apr 2022, 18:22You might consider replacing all of the positioning logic with a single call to CalculatePopupWindowPosition, assuming you don't need to support Windows XP or older. It transparently supports multiple monitors, even if they have different DPI settings (which causes this script some trouble). I've demonstrated how to do it for v2 here. For v1, there's WinMoveZ by SKAN.
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)
Re: [Function] FFToolTip: Flicker-Free ToolTip
omg thanks very much for this!
finally no more flickering tooltips
finally no more flickering tooltips