Page 1 of 3

ToolTipFont / ToolTipColor - options for the ToolTip command

Posted: 05 Oct 2014, 00:47
by lexikos
ToolTipFont(Options, Name)
Sets the font options and name for subsequent calls to the ToolTip command.
Parameters are the same as for Gui Font.
Pass "Default" for Options to restore the font setting to default.

ToolTipColor(Background, Text)
Sets the background and text colours for subsequent calls to the ToolTip command.
Parameters are the same as for Gui Color.
Pass "Default" for either parameter to restore it to its default. If both are default, the system visual style is used.

Code: Select all

; ToolTipOpt v1.004
; Changes:
;  v1.001 - Pass "Default" to restore a setting to default
;  v1.002 - ANSI compatibility
;  v1.003 - Added workarounds for ToolTip's parameter being overwritten
;           by code within the message hook.
;  v1.004 - Fixed text colour.
 
ToolTipFont(Options := "", Name := "", hwnd := "") {
    static hfont := 0
    if (hwnd = "")
        hfont := Options="Default" ? 0 : _TTG("Font", Options, Name), _TTHook()
    else
        DllCall("SendMessage", "ptr", hwnd, "uint", 0x30, "ptr", hfont, "ptr", 0)
}
 
ToolTipColor(Background := "", Text := "", hwnd := "") {
    static bc := "", tc := ""
    if (hwnd = "") {
        if (Background != "")
            bc := Background="Default" ? "" : _TTG("Color", Background)
        if (Text != "")
            tc := Text="Default" ? "" : _TTG("Color", Text)
        _TTHook()
    }
    else {
        VarSetCapacity(empty, 2, 0)
        DllCall("UxTheme.dll\SetWindowTheme", "ptr", hwnd, "ptr", 0
            , "ptr", (bc != "" && tc != "") ? &empty : 0)
        if (bc != "")
            DllCall("SendMessage", "ptr", hwnd, "uint", 1043, "ptr", bc, "ptr", 0)
        if (tc != "")
            DllCall("SendMessage", "ptr", hwnd, "uint", 1044, "ptr", tc, "ptr", 0)
    }
}
 
_TTHook() {
    static hook := 0
    if !hook
        hook := DllCall("SetWindowsHookExW", "int", 4
            , "ptr", RegisterCallback("_TTWndProc"), "ptr", 0
            , "uint", DllCall("GetCurrentThreadId"), "ptr")
}
 
_TTWndProc(nCode, _wp, _lp) {
    Critical 999
   ;lParam  := NumGet(_lp+0*A_PtrSize)
   ;wParam  := NumGet(_lp+1*A_PtrSize)
    uMsg    := NumGet(_lp+2*A_PtrSize, "uint")
    hwnd    := NumGet(_lp+3*A_PtrSize)
    if (nCode >= 0 && (uMsg = 1081 || uMsg = 1036)) {
        _hack_ = ahk_id %hwnd%
        WinGetClass wclass, %_hack_%
        if (wclass = "tooltips_class32") {
            ToolTipColor(,, hwnd)
            ToolTipFont(,, hwnd)
        }
    }
    return DllCall("CallNextHookEx", "ptr", 0, "int", nCode, "ptr", _wp, "ptr", _lp, "ptr")
}
 
_TTG(Cmd, Arg1, Arg2 := "") {
    static htext := 0, hgui := 0
    if !htext {
        Gui _TTG: Add, Text, +hwndhtext
        Gui _TTG: +hwndhgui +0x40000000
    }
    Gui _TTG: %Cmd%, %Arg1%, %Arg2%
    if (Cmd = "Font") {
        GuiControl _TTG: Font, %htext%
        SendMessage 0x31, 0, 0,, ahk_id %htext%
        return ErrorLevel
    }
    if (Cmd = "Color") {
        hdc := DllCall("GetDC", "ptr", htext, "ptr")
        SendMessage 0x138, hdc, htext,, ahk_id %hgui%
        clr := DllCall("GetBkColor", "ptr", hdc, "uint")
        DllCall("ReleaseDC", "ptr", htext, "ptr", hdc)
        return clr
    }
}
Example

Code: Select all

ToolTip Standard tooltip
Sleep 1000
ToolTipFont("s20", "Comic Sans MS")
ToolTip ToolTip with custom font
Sleep 1000
ToolTipColor("Black", "White")
ToolTip ToolTip with custom font and color
Sleep 1000
ExitApp
About
While testing just me's ToolTipEx and writing my own GUI-based version, I realized that it's not necessary to reimplement the command just to stylize a tooltip. This script uses a message hook to modify the tooltip when AutoHotkey sends it an update message (TTM_UPDATETIPTEXT). It uses the following tricks:
  • Use a CallWndProc hook to intercept messages sent to tooltip windows owned by by the script. It would be better to subclass the tooltips_class32 window class (within the current process), but that requires creating a tooltips_class32 window for use with GetClassLong/SetClassLong.

    Caution: Hooking messages which can interrupt AutoHotkey's commands may cause the command's parameters to be overwritten. The hook callback must avoid certain operations that use the "deref buffer", such as concatenation (except when the result is directly assigned to a variable) or functions returning strings, including WinExist (which returns a hexadecimal string).
  • Use a hidden GUI to parse font options/names and colour values/names.
  • Apply the WS_CHILD style to a GUI so that DetectHiddenWindows isn't needed.
Notes:
  • It's possible to embed a GUI into a tooltip window.
  • It's possible to resize a tooltip window from within the message hook, but you must WinSet Region to clear the tooltip's shape first.

Re: ToolTipFont / ToolTipColor - options for the ToolTip com

Posted: 05 Oct 2014, 13:17
by Skrell
can this be used to hook all windows displayed tooltips and change their appearance? Or is this ONLY for modifying autohotkey generated tooltips?

Re: ToolTipFont / ToolTipColor - options for the ToolTip com

Posted: 05 Oct 2014, 13:17
by joedf
Very nice :)

Re: ToolTipFont / ToolTipColor - options for the ToolTip com

Posted: 05 Oct 2014, 16:31
by tmplinshi
nice 8-)

Re: ToolTipFont / ToolTipColor - options for the ToolTip com

Posted: 06 Oct 2014, 00:44
by just me
nice (nice trick also: SendMessage 0x138, hdc, htext,, ahk_id %hgui%),
but how to switch back to the default font and colors?

Re: ToolTipFont / ToolTipColor - options for the ToolTip com

Posted: 06 Oct 2014, 01:10
by lexikos
Skrell wrote:can this be used to hook all windows displayed tooltips and change their appearance? Or is this ONLY for modifying autohotkey generated tooltips?
Refer to my first post. I'll let you infer your own answers.
just me wrote:but how to switch back to the default font and colors?
Reload ;)

It's just a matter of clearing the static variables and either creating a new window or resetting the window theme. I've updated the script so that it does this if you pass "Default" for the parameter(s).

Re: ToolTipFont / ToolTipColor - options for the ToolTip com

Posted: 06 Oct 2014, 12:37
by Relayer
For some reason I get the plain old TT while running the example. I'm using AutoHotkey v1.1.14.04

Relayer

Re: ToolTipFont / ToolTipColor - options for the ToolTip com

Posted: 06 Oct 2014, 12:41
by guest3456
Relayer wrote:For some reason I get the plain old TT while running the example. I'm using AutoHotkey v1.1.14.04

Relayer
Maybe its for AHK v2, since the default function parameter values are assigned with :=. Try replacing those with =

Re: ToolTipFont / ToolTipColor - options for the ToolTip com

Posted: 08 Oct 2014, 01:33
by lexikos
No, it is not compatible with v2. It was also not ANSI compatible, but it is now (v1.002). It already worked with v1.1.14.04 Unicode.

By the way, there have been numerous bug fixes and a few new features added since v1.1.14.04...

Optional parameters have supported := since v1.1.09.

Re: ToolTipFont / ToolTipColor - options for the ToolTip com

Posted: 09 Oct 2014, 08:32
by Relayer
Thank you lexikos!

You have my utmost respect. What you've done with AutoHotKey has been truly amazing and has enabled me to be so much more productive and have way more fun than I could have without your work. I can only hope you maintain your energy to stick with it.

Relayer

Re: ToolTipFont / ToolTipColor - options for the ToolTip com

Posted: 16 Oct 2014, 22:29
by freiheitner
Seriously cool. I've been searching for a fairly simple way to do this since default tooltips on Windows 7 are pretty un-attention-grabbing. Thanks for this!

Re: ToolTipFont / ToolTipColor - options for the ToolTip command

Posted: 21 Oct 2015, 05:35
by slur
I don't know this is just me or not

but this code gives me funny results

Code: Select all

ToolTipFont("s12")

test := "Hello"

tooltip, %test%, 40, 0, 1
tooltip, % test . A_Space, 40, 40, 2
tooltip, % 1 + 0, 40, 80, 3
tooltip, %A_Space%, 40, 120, 4
tooltip, % InStr(test, "o"), 40, 160, 5
tooltip, % test ? "yes" : "no", 40, 200, 6
sleep, 5000
Exitapp

#Include <ToolTipOpt>
except the first one, which says Hello as expected,
others give me ahk_class tooltips_class32 ahk_id __random_id_here__

WindowsXP SP3 AHK1.1.22.07 U32

Re: ToolTipFont / ToolTipColor - options for the ToolTip command

Posted: 21 Oct 2015, 11:13
by boiler
This is very useful. Thanks for providing it.

Re: ToolTipFont / ToolTipColor - options for the ToolTip command

Posted: 24 Oct 2015, 08:25
by GS SAHU
idea!

i things tooltip showing in callouts( as cloud,oval, rectangular, rounded rectangualar callouts) with a cartoon image like saying tooltip text.text speak in sound also a other option in tooltip.

like: :offtopic:

it is possible?

Re: ToolTipFont / ToolTipColor - options for the ToolTip command

Posted: 24 Oct 2015, 12:37
by joedf
Try gDip ?

Re: ToolTipFont / ToolTipColor - options for the ToolTip command

Posted: 08 Dec 2015, 11:48
by Avi
I notice that when a custom font tooltip is active (visible), hotkeys get suspended. For example, in the following code pressing Win+O will not close the script when ToolTipFont is set. But when you comment that line, the hotkey works.

Code: Select all

; ToolTipOpt v1.002
; Changes:
;  v1.001 - Pass "Default" to restore a setting to default
;  v1.002 - ANSI compatibility
;  https://autohotkey.com/boards/viewtopic.php?t=4777

ToolTipFont("s20", "Comic Sans MS") ;<------
Tooltip massive tooltip custom font
Hotkey, #o, labelx, On
var := 0
while !var
	sleep 20
ExitApp
return

labelx:
	var := 1
	return


ToolTipFont(Options := "", Name := "", hwnd := "") {
	static hfont := 0
	if (hwnd = "")
		hfont := Options="Default" ? 0 : _TTG("Font", Options, Name), _TTHook()
	else
		SendMessage 0x30, hfont, 0,, ahk_id %hwnd%
}
 
ToolTipColor(Background := "", Text := "", hwnd := "") {
	static bc := "", tc := ""
	if (hwnd = "") {
		if (Background != "")
			bc := Background="Default" ? "" : _TTG("Color", Background)
		if (Text != "")
			tc := Text="Default" ? "" : _TTG("Color", Text)
		_TTHook()
	}
	else {
		VarSetCapacity(empty, 2, 0)
		DllCall("UxTheme.dll\SetWindowTheme", "ptr", hwnd, "ptr", 0, "ptr", bc tc != "" ? &empty : 0)
		if (bc != "")
			SendMessage 1043, %bc%,,, ahk_id %hwnd%
		if (tc != "")
			SendMessage 1044, %tc%,,, ahk_id %hwnd%
	}
}
 
_TTHook() {
	static hook := 0
	if !hook
		hook := DllCall("SetWindowsHookExW", "int", 4
			, "ptr", RegisterCallback("_TTWndProc", "F"), "ptr", 0
			, "uint", DllCall("GetCurrentThreadId"), "ptr")
}
 
_TTWndProc(nCode, _wp, _lp) {
	Critical 999
   ;lParam  := NumGet(_lp+0*A_PtrSize)
   ;wParam  := NumGet(_lp+1*A_PtrSize)
	uMsg    := NumGet(_lp+2*A_PtrSize)
	hwnd    := NumGet(_lp+3*A_PtrSize)
	if (nCode >= 0 && (uMsg = 1081 || uMsg = 1036) && WinExist("ahk_class tooltips_class32 ahk_id " hwnd)) {
		ToolTipColor(,, hwnd)
		ToolTipFont(,, hwnd)
	}
	return DllCall("CallNextHookEx", "ptr", 0, "int", nCode, "ptr", _wp, "ptr", _lp, "ptr")
}
 
_TTG(Cmd, Arg1, Arg2 := "") {
	static htext := 0, hgui := 0
	if !htext {
		Gui _TTG: Add, Text, +hwndhtext
		Gui _TTG: +hwndhgui +0x40000000
	}
	Gui _TTG: %Cmd%, %Arg1%, %Arg2%
	if (Cmd = "Font") {
		GuiControl _TTG: Font, %htext%
		SendMessage 0x31, 0, 0,, ahk_id %htext%
		return ErrorLevel
	}
	if (Cmd = "Color") {
		hdc := DllCall("GetDC", "ptr", htext, "ptr")
		SendMessage 0x138, hdc, htext,, ahk_id %hgui%
		clr := DllCall("GetBkColor", "ptr", hdc, "uint")
		DllCall("ReleaseDC", "ptr", htext, "ptr", hdc)
		return clr
	}
}
I tried commenting Critical 999 in _TTWndProc and that did work to some extent but it had other weird bugs (in some other script).

Using AHK 1.1.22.07 U32 on Win 8.1 x64

EDIT - I tried the same thing with justme's TooltipEx and that worked.

Re: ToolTipFont / ToolTipColor - options for the ToolTip command

Posted: 09 Dec 2015, 02:01
by lexikos
Try one of:
1. Remove , "F", otherwise Critical 999 will affect whatever thread was active when the hook was called.
2. Use Critical Off before returning from _TTWndProc. (Instead of "Off", you may use the value A_IsCritical had before Critical 999 was called.)

Re: ToolTipFont / ToolTipColor - options for the ToolTip command

Posted: 06 Jul 2016, 03:53
by lexikos
I've updated the script with workarounds for slur's issue (also reported recently by Lampshade).

Re: ToolTipFont / ToolTipColor - options for the ToolTip command

Posted: 06 Jul 2016, 07:42
by arcticir
Hi,We can limit the width of it?

Re: ToolTipFont / ToolTipColor - options for the ToolTip command

Posted: 06 Jul 2016, 09:05
by rommmcek
@arcticir: Good question!
Btw, wouldn't be nice to have an option for getting dimensions of ToolTip? OS is obviously aware of them for ToolTipFont behaves exactly the same as native ToolTip, especially in right bottom corner of the screen.
Now I use ToolTipColor as:

Code: Select all

TooTipColor("WhatEverExceptDefault", "BackgroundColor")
Text Color doesn't work.
Edit: That was a lightning fast fix! So text color problems are history!

But I noticed another "limitation" (it was happening in 1.003 too - in earlier versions dunno, 'couse I didn't use them): In quick consecutive changes of the ToolTip once being modified by ToolTipFont sometimes happens (not very often), broken display of the ToolTip, see pic.