[Function] FFToolTip: Flicker-Free ToolTip

Post your working scripts, libraries and tools for AHK v1.1 and older
iPhilip
Posts: 853
Joined: 02 Oct 2013, 12:21

[Function] FFToolTip: Flicker-Free ToolTip

Post by iPhilip » 08 Mar 2019, 17:43

*** UPDATED VERSIONS ***

Hi Folks,

If you ever use a tooltip in a timer to show text next to the cursor, you will likely have noticed flickering of the tooltip window. The function below FFToolTip() addresses that problem. It functions much like the ToolTip command but without the flickering.

I am providing two versions below. One for AHK v1.1 and a second one for AHK v2.0. Both work for single-monitor and multiple-monitor configurations. Neither requires any additional function. If the DPI settings of multiple monitors don't match, use the workaround described in the documentation.

For reference, @lexikos provided a review of a few functions that address the same problem as well as a simple fix for AHK v2 here. In addition, @NPerovic posted ToolTipEx that does the same and more.

Here is the function for AHK v1.1:

Code: Select all

; ===============================================================================================================================
; FFToolTip(Text := "", X := "", Y := "", WhichToolTip := 1)
; Function:       Creates a tooltip window on any screen in a single or multiple-monitor environment. Unlike the built-in ToolTip
;                 function, calling this function repeatedly will not cause the tooltip window to flicker. Otherwise, it behaves
;                 much the same way, except around the bottom-right corner of each monitor. If neither coordinate is specified,
;                 the tooltip window will not cover any part of the taskbar.
; 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 destroyed.
;                 - 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:  If the tooltip is being shown for the first time or is being updated, the function returns the handle of the
;                 tooltip window. If the Text parameter is blank or omitted, the function returns zero.
; Global vars:    None
; Dependencies:   None
; Requirements:   AHK v1.1
; Tested with:    AHK v1.1.37.02 (A32/U32/U64)
; Tested on:      Win 10 Pro (x64)
; Written by:     iPhilip
; Forum link:     https://www.autohotkey.com/boards/viewtopic.php?f=6&t=62607
; ===============================================================================================================================

FFToolTip(Text := "", X := "", Y := "", WhichToolTip := 1) {
   static TTS := []
   static DeltaX := 16  ; Horizontal gap between the mouse and the left edge of the tooltip window
   static DeltaY := 16  ; Vertical gap between the mouse and the top edge of the tooltip window
   static DeltaZ := 3   ; Vertical gap between the mouse and the bottom edge of the tooltip window when in the bottom-right corner of the screen
   static Flags  := 0x10040  ; TPM_WORKAREA = 0x10000 | TPM_VERTICAL = 0x0040
   static POS := VarSetCapacity(POS, 16)
   static EXC := VarSetCapacity(EXC, 16)
   static OUT := VarSetCapacity(OUT, 16)
   static PID := DllCall("GetCurrentProcessId", "UInt")
   
   local
   if (Text = "") {  ; Destroy the tooltip
      ToolTip, , , , WhichToolTip
      TTS.Delete(WhichToolTip)
      hwnd := 0
   } else if !TTS.HasKey(WhichToolTip) {  ; First call
      ToolTip, %Text%, X, Y, WhichToolTip
      hwnd := WinExist("ahk_class tooltips_class32 ahk_pid " PID)
      WinGetPos, X, Y, W, H, ahk_id %hwnd%
      TTS[WhichToolTip] := {X:X, Y:Y, W:W, H:H, hwnd:hwnd, Text:Text}
   } else if !(Text == TTS[WhichToolTip].Text) {  ; The tooltip text changed.
      ToolTip, %Text%, X, Y, WhichToolTip
      hwnd := TTS[WhichToolTip].hwnd
      WinGetPos, X, Y, W, H, ahk_id %hwnd%
      TTS[WhichToolTip] := {X:X, Y:Y, W:W, H:H, hwnd:hwnd, Text:Text}
   } else {  ; The tooltip is being repositioned.
      IsEmptyX := X = ""
      IsEmptyY := Y = ""
      if (IsEmptyX || IsEmptyY) {
         DllCall("GetCursorPos", "Ptr", &POS, "Int")
         MouseX := NumGet(POS, 0, "Int")
         MouseY := NumGet(POS, 4, "Int")
      }
      ;
      ; Convert input coordinates to screen coordinates.
      ;
      if (A_CoordModeToolTip = "Window") {
         WinGetPos, WinX, WinY, , , A
         X := IsEmptyX ? MouseX : X + WinX
         Y := IsEmptyY ? MouseY : Y + WinY
      } else if (A_CoordModeToolTip = "Client") {
         NumPut(IsEmptyX ? 0 : X, POS, 0, "Int")
         NumPut(IsEmptyY ? 0 : Y, POS, 4, "Int")
         DllCall("ClientToScreen", "Ptr", WinExist("A"), "Ptr", &POS, "Int")
         X := IsEmptyX ? MouseX : NumGet(POS, 0, "Int")
         Y := IsEmptyY ? MouseY : NumGet(POS, 4, "Int")
      } else {  ; A_CoordModeToolTip = "Screen"
         X := IsEmptyX ? MouseX : X
         Y := IsEmptyY ? MouseY : Y
      }
      W := TTS[WhichToolTip].W
      H := TTS[WhichToolTip].H
      ;
      ; If neither coordinate is specified, force the tooltip window to be within the working area of the monitors.
      ;
      if IsEmptyX && IsEmptyY
      && DllCall("SetRect", "Ptr", &POS, "Int", X + DeltaX, "Int", Y + DeltaY, "Int", W, "Int", H, "Int")
      && DllCall("SetRect", "Ptr", &EXC, "Int", X - DeltaZ, "Int", Y - DeltaZ, "Int", X + DeltaX, "Int", Y + DeltaY, "Int")
      && DllCall("CalculatePopupWindowPosition", "Ptr", &POS, "Ptr", &POS + 8, "UInt", Flags, "Ptr", &EXC, "Ptr", &OUT, "Int")
         X := NumGet(OUT, 0, "Int"), Y := NumGet(OUT, 4, "Int")
      ;
      ; If necessary, store the coordinates and move the tooltip window.
      ;
      hwnd := TTS[WhichToolTip].hwnd
      if (X != TTS[WhichToolTip].X || Y != TTS[WhichToolTip].Y) {
         TTS[WhichToolTip].X := X, TTS[WhichToolTip].Y := Y
         DllCall("MoveWindow", "Ptr", hwnd, "Int", X, "Int", Y, "Int", W, "Int", H, "Int", false, "Int")
      }
   }
   return hwnd
}
Here is a self-contained example for AHK v1.1:

Code: Select all

#Requires AutoHotkey v1.1.33
#NoEnv

ToolTipText := "
(
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.
)"

MsgBox,
(
First, let's show a tooltip as it tracks with mouse movement
using the built-in method.`n
Notice the flickering of the tooltip window.`n
Click OK to start.
)
SetTimer, Timer1, 10
MsgBox
SetTimer, Timer1, Off
ToolTip
MsgBox,
(
Now, let's show a tooltip as it tracks with mouse movement
using the FFToolTip function.`n
Notice the absence of any flickering and the behavior of the
tooltip window near the taskbar.`n
Click OK to continue.
)
SetTimer, Timer2, 10
MsgBox Click OK to exit.
SetTimer Timer2, Off
FFToolTip()
return

Timer1:
ToolTip, %ToolTipText%
Return

Timer2:
FFToolTip(ToolTipText)
Return

; ===============================================================================================================================
; FFToolTip(Text := "", X := "", Y := "", WhichToolTip := 1)
; Function:       Creates a tooltip window on any screen in a single or multiple-monitor environment. Unlike the built-in ToolTip
;                 function, calling this function repeatedly will not cause the tooltip window to flicker. Otherwise, it behaves
;                 much the same way, except around the bottom-right corner of each monitor. If neither coordinate is specified,
;                 the tooltip window will not cover any part of the taskbar.
; 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 destroyed.
;                 - 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:  If the tooltip is being shown for the first time or is being updated, the function returns the handle of the
;                 tooltip window. If the Text parameter is blank or omitted, the function returns zero.
; Global vars:    None
; Dependencies:   None
; Requirements:   AHK v1.1
; Tested with:    AHK v1.1.37.02 (A32/U32/U64)
; Tested on:      Win 10 Pro (x64)
; Written by:     iPhilip
; Forum link:     https://www.autohotkey.com/boards/viewtopic.php?f=6&t=62607
; ===============================================================================================================================

FFToolTip(Text := "", X := "", Y := "", WhichToolTip := 1) {
   static TTS := []
   static DeltaX := 16  ; Horizontal gap between the mouse and the left edge of the tooltip window
   static DeltaY := 16  ; Vertical gap between the mouse and the top edge of the tooltip window
   static DeltaZ := 3   ; Vertical gap between the mouse and the bottom edge of the tooltip window when in the bottom-right corner of the screen
   static Flags  := 0x10040  ; TPM_WORKAREA = 0x10000 | TPM_VERTICAL = 0x0040
   static POS := VarSetCapacity(POS, 16)
   static EXC := VarSetCapacity(EXC, 16)
   static OUT := VarSetCapacity(OUT, 16)
   static PID := DllCall("GetCurrentProcessId", "UInt")
   
   local
   if (Text = "") {  ; Destroy the tooltip
      ToolTip, , , , WhichToolTip
      TTS.Delete(WhichToolTip)
      hwnd := 0
   } else if !TTS.HasKey(WhichToolTip) {  ; First call
      ToolTip, %Text%, X, Y, WhichToolTip
      hwnd := WinExist("ahk_class tooltips_class32 ahk_pid " PID)
      WinGetPos, X, Y, W, H, ahk_id %hwnd%
      TTS[WhichToolTip] := {X:X, Y:Y, W:W, H:H, hwnd:hwnd, Text:Text}
   } else if !(Text == TTS[WhichToolTip].Text) {  ; The tooltip text changed.
      ToolTip, %Text%, X, Y, WhichToolTip
      hwnd := TTS[WhichToolTip].hwnd
      WinGetPos, X, Y, W, H, ahk_id %hwnd%
      TTS[WhichToolTip] := {X:X, Y:Y, W:W, H:H, hwnd:hwnd, Text:Text}
   } else {  ; The tooltip is being repositioned.
      IsEmptyX := X = ""
      IsEmptyY := Y = ""
      if (IsEmptyX || IsEmptyY) {
         DllCall("GetCursorPos", "Ptr", &POS, "Int")
         MouseX := NumGet(POS, 0, "Int")
         MouseY := NumGet(POS, 4, "Int")
      }
      ;
      ; Convert input coordinates to screen coordinates.
      ;
      if (A_CoordModeToolTip = "Window") {
         WinGetPos, WinX, WinY, , , A
         X := IsEmptyX ? MouseX : X + WinX
         Y := IsEmptyY ? MouseY : Y + WinY
      } else if (A_CoordModeToolTip = "Client") {
         NumPut(IsEmptyX ? 0 : X, POS, 0, "Int")
         NumPut(IsEmptyY ? 0 : Y, POS, 4, "Int")
         DllCall("ClientToScreen", "Ptr", WinExist("A"), "Ptr", &POS, "Int")
         X := IsEmptyX ? MouseX : NumGet(POS, 0, "Int")
         Y := IsEmptyY ? MouseY : NumGet(POS, 4, "Int")
      } else {  ; A_CoordModeToolTip = "Screen"
         X := IsEmptyX ? MouseX : X
         Y := IsEmptyY ? MouseY : Y
      }
      W := TTS[WhichToolTip].W
      H := TTS[WhichToolTip].H
      ;
      ; If neither coordinate is specified, force the tooltip window to be within the working area of the monitors.
      ;
      if IsEmptyX && IsEmptyY
      && DllCall("SetRect", "Ptr", &POS, "Int", X + DeltaX, "Int", Y + DeltaY, "Int", W, "Int", H, "Int")
      && DllCall("SetRect", "Ptr", &EXC, "Int", X - DeltaZ, "Int", Y - DeltaZ, "Int", X + DeltaX, "Int", Y + DeltaY, "Int")
      && DllCall("CalculatePopupWindowPosition", "Ptr", &POS, "Ptr", &POS + 8, "UInt", Flags, "Ptr", &EXC, "Ptr", &OUT, "Int")
         X := NumGet(OUT, 0, "Int"), Y := NumGet(OUT, 4, "Int")
      ;
      ; If necessary, store the coordinates and move the tooltip window.
      ;
      hwnd := TTS[WhichToolTip].hwnd
      if (X != TTS[WhichToolTip].X || Y != TTS[WhichToolTip].Y) {
         TTS[WhichToolTip].X := X, TTS[WhichToolTip].Y := Y
         DllCall("MoveWindow", "Ptr", hwnd, "Int", X, "Int", Y, "Int", W, "Int", H, "Int", false, "Int")
      }
   }
   return hwnd
}
Here is the function for AHK v2:

Code: Select all

; ===============================================================================================================================
; FFToolTip(Text?, X?, Y?, WhichToolTip := 1)
; Function:       Creates a tooltip window on any screen in a single or multiple-monitor environment. Unlike the built-in ToolTip
;                 function, calling this function repeatedly will not cause the tooltip window to flicker. Otherwise, it behaves
;                 much the same way, except around the bottom-right corner of each monitor. If neither coordinate is specified,
;                 the tooltip window will not cover any part of the taskbar.
; 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 destroyed.
;                 - 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:  If the tooltip is being shown for the first time or is being updated, the function returns the handle of the
;                 tooltip window. If the Text parameter is blank or omitted, the function returns zero.
; Global vars:    None
; Dependencies:   None
; Requirements:   AHK v2.0
; Tested with:    AHK v2.0.16 (U32/U64)
; Tested on:      Win 10 Pro (x64)
; Written by:     iPhilip
; Forum link:     https://www.autohotkey.com/boards/viewtopic.php?f=6&t=62607
; ===============================================================================================================================

FFToolTip(Text?, X?, Y?, WhichToolTip := 1) {
   static TTS := []
   static DeltaX := 16  ; Horizontal gap between the mouse and the left edge of the tooltip window
   static DeltaY := 16  ; Vertical gap between the mouse and the top edge of the tooltip window
   static DeltaZ := 3   ; Vertical gap between the mouse and the bottom edge of the tooltip window when in the bottom-right corner of the screen
   static Flags  := 0x10040  ; TPM_WORKAREA = 0x10000 | TPM_VERTICAL = 0x0040
   static POS := Buffer(16)
   static EXC := Buffer(16)
   static OUT := Buffer(16)
   
   if !TTS.Length
      TTS.Length := 20
   if !IsSet(Text) || Text = '' {  ; Destroy the tooltip.
      hwnd := ToolTip( , , , WhichToolTip)
      TTS.Delete(WhichToolTip)
   } else if !TTS.Has(WhichToolTip) || Text !== TTS[WhichToolTip].Text {  ; First call or tooltip text changed.
      hwnd := ToolTip(Text, X?, Y?, WhichToolTip)
      WinGetPos(&X, &Y, &W, &H, hwnd)
      TTS[WhichToolTip] := {X:X, Y:Y, W:W, H:H, hwnd:hwnd, Text:Text}
   } else {  ; The tooltip is being repositioned.
      IsSetX := IsSet(X)
      IsSetY := IsSet(Y)
      if !IsSetX || !IsSetY {
         DllCall('GetCursorPos', 'Ptr', POS, 'Int')
         MouseX := NumGet(POS, 0, 'Int')
         MouseY := NumGet(POS, 4, 'Int')
      }
      ;
      ; Convert input coordinates to screen coordinates.
      ;
      if A_CoordModeToolTip = 'Window' {
         WinGetPos &WinX, &WinY, , , 'A'
         X := IsSetX ? X + WinX : MouseX
         Y := IsSetY ? Y + WinY : MouseY
      } else if A_CoordModeToolTip = 'Client' {
         NumPut 'Int', X ?? 0, 'Int', Y ?? 0, POS
         DllCall('ClientToScreen', 'Ptr', WinExist('A'), 'Ptr', POS, 'Int')
         X := IsSetX ? NumGet(POS, 0, 'Int') : MouseX
         Y := IsSetY ? NumGet(POS, 4, 'Int') : MouseY
      } else {  ; A_CoordModeToolTip = 'Screen'
         X := X ?? MouseX
         Y := Y ?? MouseY
      }
      W := TTS[WhichToolTip].W
      H := TTS[WhichToolTip].H
      ;
      ; If neither coordinate is specified, force the tooltip window to be within the working area of the monitors.
      ;
      if !IsSetX && !IsSetY
      && DllCall('SetRect', 'Ptr', POS, 'Int', X + DeltaX, 'Int', Y + DeltaY, 'Int', W, 'Int', H, 'Int')
      && DllCall('SetRect', 'Ptr', EXC, 'Int', X - DeltaZ, 'Int', Y - DeltaZ, 'Int', X + DeltaX, 'Int', Y + DeltaY, 'Int')
      && DllCall('CalculatePopupWindowPosition', 'Ptr', POS, 'Ptr', POS.Ptr + 8, 'UInt', Flags, 'Ptr', EXC, 'Ptr', OUT, 'Int')
         X := NumGet(OUT, 0, 'Int'), Y := NumGet(OUT, 4, 'Int')
      ;
      ; If necessary, store the coordinates and move the tooltip window.
      ;
      hwnd := TTS[WhichToolTip].hwnd
      if X != TTS[WhichToolTip].X || Y != TTS[WhichToolTip].Y {
         TTS[WhichToolTip].X := X, TTS[WhichToolTip].Y := Y
         DllCall('MoveWindow', 'Ptr', hwnd, 'Int', X, 'Int', Y, 'Int', W, 'Int', H, 'Int', false, 'Int')
      }
   }
   return hwnd
}
Here is a self-contained example for AHK v2:

Code: Select all

#Requires AutoHotkey v2.0

ToolTipText := '
(
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.
)'

MsgBox '
(
First, let's show a tooltip as it tracks with mouse movement
using the built-in method.`n
Notice the flickering of the tooltip window.`n
Click OK to start.
)'
SetTimer Timer := () => ToolTip(ToolTipText), 10
MsgBox
SetTimer Timer, 0
ToolTip
MsgBox '
(
Now, let's show a tooltip as it tracks with mouse movement
using the FFToolTip function.`n
Notice the absence of any flickering and the behavior of the
tooltip window near the taskbar.`n
Click OK to continue.
)'
SetTimer Timer := () => FFToolTip(ToolTipText), 10
MsgBox 'Click OK to exit.'
SetTimer Timer, 0
FFToolTip()

; ===============================================================================================================================
; FFToolTip(Text?, X?, Y?, WhichToolTip := 1)
; Function:       Creates a tooltip window on any screen in a single or multiple-monitor environment. Unlike the built-in ToolTip
;                 function, calling this function repeatedly will not cause the tooltip window to flicker. Otherwise, it behaves
;                 much the same way, except around the bottom-right corner of each monitor. If neither coordinate is specified,
;                 the tooltip window will not cover any part of the taskbar.
; 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 destroyed.
;                 - 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:  If the tooltip is being shown for the first time or is being updated, the function returns the handle of the
;                 tooltip window. If the Text parameter is blank or omitted, the function returns zero.
; Global vars:    None
; Dependencies:   None
; Requirements:   AHK v2.0
; Tested with:    AHK v2.0.16 (U32/U64)
; Tested on:      Win 10 Pro (x64)
; Written by:     iPhilip
; Forum link:     https://www.autohotkey.com/boards/viewtopic.php?f=6&t=62607
; ===============================================================================================================================

FFToolTip(Text?, X?, Y?, WhichToolTip := 1) {
   static TTS := []
   static DeltaX := 16  ; Horizontal gap between the mouse and the left edge of the tooltip window
   static DeltaY := 16  ; Vertical gap between the mouse and the top edge of the tooltip window
   static DeltaZ := 3   ; Vertical gap between the mouse and the bottom edge of the tooltip window when in the bottom-right corner of the screen
   static Flags  := 0x10040  ; TPM_WORKAREA = 0x10000 | TPM_VERTICAL = 0x0040
   static POS := Buffer(16)
   static EXC := Buffer(16)
   static OUT := Buffer(16)
   
   if !TTS.Length
      TTS.Length := 20
   if !IsSet(Text) || Text = '' {  ; Destroy the tooltip.
      hwnd := ToolTip( , , , WhichToolTip)
      TTS.Delete(WhichToolTip)
   } else if !TTS.Has(WhichToolTip) || Text !== TTS[WhichToolTip].Text {  ; First call or tooltip text changed.
      hwnd := ToolTip(Text, X?, Y?, WhichToolTip)
      WinGetPos(&X, &Y, &W, &H, hwnd)
      TTS[WhichToolTip] := {X:X, Y:Y, W:W, H:H, hwnd:hwnd, Text:Text}
   } else {  ; The tooltip is being repositioned.
      IsSetX := IsSet(X)
      IsSetY := IsSet(Y)
      if !IsSetX || !IsSetY {
         DllCall('GetCursorPos', 'Ptr', POS, 'Int')
         MouseX := NumGet(POS, 0, 'Int')
         MouseY := NumGet(POS, 4, 'Int')
      }
      ;
      ; Convert input coordinates to screen coordinates.
      ;
      if A_CoordModeToolTip = 'Window' {
         WinGetPos &WinX, &WinY, , , 'A'
         X := IsSetX ? X + WinX : MouseX
         Y := IsSetY ? Y + WinY : MouseY
      } else if A_CoordModeToolTip = 'Client' {
         NumPut 'Int', X ?? 0, 'Int', Y ?? 0, POS
         DllCall('ClientToScreen', 'Ptr', WinExist('A'), 'Ptr', POS, 'Int')
         X := IsSetX ? NumGet(POS, 0, 'Int') : MouseX
         Y := IsSetY ? NumGet(POS, 4, 'Int') : MouseY
      } else {  ; A_CoordModeToolTip = 'Screen'
         X := X ?? MouseX
         Y := Y ?? MouseY
      }
      W := TTS[WhichToolTip].W
      H := TTS[WhichToolTip].H
      ;
      ; If neither coordinate is specified, force the tooltip window to be within the working area of the monitors.
      ;
      if !IsSetX && !IsSetY
      && DllCall('SetRect', 'Ptr', POS, 'Int', X + DeltaX, 'Int', Y + DeltaY, 'Int', W, 'Int', H, 'Int')
      && DllCall('SetRect', 'Ptr', EXC, 'Int', X - DeltaZ, 'Int', Y - DeltaZ, 'Int', X + DeltaX, 'Int', Y + DeltaY, 'Int')
      && DllCall('CalculatePopupWindowPosition', 'Ptr', POS, 'Ptr', POS.Ptr + 8, 'UInt', Flags, 'Ptr', EXC, 'Ptr', OUT, 'Int')
         X := NumGet(OUT, 0, 'Int'), Y := NumGet(OUT, 4, 'Int')
      ;
      ; If necessary, store the coordinates and move the tooltip window.
      ;
      hwnd := TTS[WhichToolTip].hwnd
      if X != TTS[WhichToolTip].X || Y != TTS[WhichToolTip].Y {
         TTS[WhichToolTip].X := X, TTS[WhichToolTip].Y := Y
         DllCall('MoveWindow', 'Ptr', hwnd, 'Int', X, 'Int', Y, 'Int', W, 'Int', H, 'Int', false, 'Int')
      }
   }
   return hwnd
}
I hope you find it useful.

- iPhilip

Previous post

EDIT: 20240609 - The functions now return the handle of the tooltip window or zero if the tooltip was destroyed.
Last edited by iPhilip on 09 Jun 2024, 09:47, edited 3 times in total.
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by Helgef » 10 Mar 2019, 06:37

I tested the single-monitor v2 example, it works great. Good job and thanks for sharing :clap: .

Cheers.

robodesign
Posts: 941
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by robodesign » 10 Mar 2019, 16:50

I tested the multiple monitors one on AHK v1 and windows 10, it displays the Tooltips, but it doesn't move them when I move the mouse, only when the text changes....
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.

iPhilip
Posts: 853
Joined: 02 Oct 2013, 12:21

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by iPhilip » 10 Mar 2019, 18:56

Hi robodesign,

Thank you for the feedback from your tests. Can you post what you used to do your tests? The text doesn't change in the example script that I posted above.

Thank you,

- iPhilip
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

iPhilip
Posts: 853
Joined: 02 Oct 2013, 12:21

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by iPhilip » 10 Mar 2019, 21:37

Helgef wrote:
10 Mar 2019, 06:37
I tested the single-monitor v2 example, it works great. Good job and thanks for sharing :clap: .

Cheers.
Hi Helgef,

Thank you. I appreciate your testing and encouraging words. :)

- iPhilip
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

robodesign
Posts: 941
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by robodesign » 11 Mar 2019, 08:43

Hello!

@Philip.

I have just a simple timer that runs every 200 millimeters.

The timer only calls your function and I pass to it a global variable. When the string changes the tooltip appears at the mouse position.... , if it doesn't change, the tooltip remains in place.

I use the 64-bit version.

Best regards, Marius.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.

guest3456
Posts: 3478
Joined: 09 Oct 2013, 10:31

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by guest3456 » 11 Mar 2019, 09:14

excellent, will be using this


burque505
Posts: 1748
Joined: 22 Jan 2017, 19:37

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by burque505 » 11 Mar 2019, 10:24

@iPhilip, thanks for this. Very nice work and nicely commented. I can only test the single-monitor version(s), but on my Win7 64-bit setup (AHK_L 1.1.30.01) it's fantastic. Quite an improvement.
Regard,
burque505

iPhilip
Posts: 853
Joined: 02 Oct 2013, 12:21

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by iPhilip » 11 Mar 2019, 16:16

robodesign wrote:
11 Mar 2019, 08:43
Hello!

@Philip.

I have just a simple timer that runs every 200 millimeters.
I think you meant milliseconds. :)
robodesign wrote:
11 Mar 2019, 08:43
The timer only calls your function and I pass to it a global variable. When the string changes the tooltip appears at the mouse position.... , if it doesn't change, the tooltip remains in place.

I use the 64-bit version.

Best regards, Marius.
I tested the above multi-monitor example under Windows 7 Pro (64 bit) and Windows 10 Enterprise (64 bit) with AutoHotkey 1.1.30.01 (A32/U32/U64). It worked fine under both systems and all 3 versions of AutoHotkey. If you are willing to post a version of your code, I would be happy to take a look at it. Alternatively, I would be interested in knowing if the above script (unmodified) works for you.

Thank you,

- iPhilip
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

robodesign
Posts: 941
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by robodesign » 11 Mar 2019, 17:59

Hello, I will try it again, unmodified.

I admit I was a bit unorthodox....
I copied and pasted your functions into my KeyPress OSD script.... Where I have a simple timer which displays texts on screen, whatever the OSD is showing it's shown as a tooltip as well. So, something in my script might be messing up with your functions. In particular, with the updating of the tooltip position.

I also use AHK-H.

Best regards, Marius.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.

iPhilip
Posts: 853
Joined: 02 Oct 2013, 12:21

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by iPhilip » 11 Mar 2019, 18:21

robodesign wrote:
11 Mar 2019, 17:59
Hello, I will try it again, unmodified.

I admit I was a bit unorthodox....
I copied and pasted your functions into my KeyPress OSD script.... Where I have a simple timer which displays texts on screen, whatever the OSD is showing it's shown as a tooltip as well. So, something in my script might be messing up with your functions. In particular, with the updating of the tooltip position.

I also use AHK-H.

Best regards, Marius.
FFToolTip was not designed to work with, nor was it tested with AHK-H. I would encourage you to put that information in your signature block.
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

robodesign
Posts: 941
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by robodesign » 13 Mar 2019, 06:24

Hello, again!

I tested your provided examples and they work with AHK_H :-). For your information , I never found a script or something to work with AHK_L, but not with AHK_H. So, do not be afraid of it :-).

The problem is just when I integrate it into my mammoth script, as I previously suggested....

Anyways, congratulations for the great function ;).

Best regards, Marius.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.

iPhilip
Posts: 853
Joined: 02 Oct 2013, 12:21

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by iPhilip » 13 Mar 2019, 12:35

Hi Marius,

Thank you for your comments and the additional testing. I appreciate it. Because of your testing, I put together a portable version of AutoHotkey that will make it easier for me to test my scripts on Windows 10. :)

- iPhilip
P.S.: I will keep in mind your comments about AHK_H.
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

iPhilip
Posts: 853
Joined: 02 Oct 2013, 12:21

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by iPhilip » 13 Mar 2019, 12:40

guest3456 wrote:
11 Mar 2019, 09:14
excellent, will be using this
Thank you, guest3456. :)
burque505 wrote:
11 Mar 2019, 10:24
@iPhilip, thanks for this. Very nice work and nicely commented. I can only test the single-monitor version(s), but on my Win7 64-bit setup (AHK_L 1.1.30.01) it's fantastic. Quite an improvement.
Regard,
burque505
Thank you, burque505. I appreciate it. :)

- iPhilip
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

User avatar
DataLife
Posts: 465
Joined: 29 Sep 2013, 19:52

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by DataLife » 15 Mar 2019, 19:29

This is extremely nice, it should replace the standard tooltip.

thanks very much.
Check out my scripts. (MyIpChanger) (ClipBoard Manager) (SavePictureAs)
All my scripts are tested on Windows 10, AutoHotkey 32 bit Ansi unless otherwise stated.

User avatar
Cerberus
Posts: 172
Joined: 12 Jan 2016, 15:46

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by Cerberus » 17 Mar 2019, 22:00

This looks interesting, I'll try it when next I use tooltips!

P.S. Even after so many years, I continue to be astounded by how courteous and helpful everyone is at the Autohotkey fora.

mstrauss2021
Posts: 49
Joined: 13 Feb 2021, 10:34

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by mstrauss2021 » 28 May 2021, 16:47

Just found this yesterday.
Total life saver. Using on Win 10 at work, however, for some reason when I do a multiline it shows the `n.
so Line1`nLine2 shows as Line1`nLine2
I put a MsgBox in your function to show the value of %Text% and it still shows as 1 line which I wasn't expecting.

The only ting I can think of is that I save my tooltips in an ini file and read them back. I don't know if that has anything to do with it.

burque505
Posts: 1748
Joined: 22 Jan 2017, 19:37

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by burque505 » 28 May 2021, 17:00

@mstrauss2021, I bet you need continuation sections for your tooltips in your .ini file. From the docs for IniWrite:
Value

The string or number that will be written to the right of Key's equal sign (=).

If the text is long, it can be broken up into several shorter lines by means of a continuation section, which might improve readability and maintainability.

mstrauss2021
Posts: 49
Joined: 13 Feb 2021, 10:34

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by mstrauss2021 » 02 Jun 2021, 13:29

Through testing I found that the funtion does something that prevents `n from starting a new line so to correct for it I added:

Reminder := StrReplace(Reminder, "
", "`n") after reading my saved tooltip from ini

and

Reminder := StrReplace(Reminder, "`n", "
") before saving to ini

This allows me to ro read the tooltips in multiline format

mstrauss2021
Posts: 49
Joined: 13 Feb 2021, 10:34

Re: [Function] FFToolTip: Flicker-Free ToolTip

Post by mstrauss2021 » 24 Jun 2021, 12:12

Still 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?

Post Reply

Return to “Scripts and Functions (v1)”