ToolTips: set border colour (custom font/colour ToolTips) (borders around windows/controls)

Get help with using AutoHotkey and its commands and hotkeys
User avatar
jeeswg
Posts: 5273
Joined: 19 Dec 2016, 01:58
Location: UK

ToolTips: set border colour (custom font/colour ToolTips) (borders around windows/controls)

12 Sep 2017, 07:04

There's a rumour that the Progress command will be removed from AutoHotkey v2. I often use the Progress command to create a large font ToolTip, and so I'm trying to recreate these large 'Progress ToolTips' by creating a ToolTip directly.

Anyhow, pretty much everything is working, however, I'd like, if possible, to be able to set the border colour, or simply remove borders. At present, it appears that whatever you set the text colour to, the border uses that colour.

E.g. in ToolTipEx_sample.ahk, the text/border colours were the same in both example ToolTips:
ToolTipEx - custom fonts and colors in ToolTips - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=4350

Any general comments on the script, or on creating ToolTips, are welcome.

Code: Select all

;GUIs via DllCall: ToolTips

#Persistent
#SingleInstance force

DetectHiddenWindows, On
vSizeTI := A_PtrSize=8?72:48
;vText := "   hello world   `r`nhello world`r`nhello world"
vText := "hello world`r`nhello world`r`nhello world"
vText2 := vText
;vText2 := SubStr(vText, 2)
VarSetCapacity(TOOLINFO, vSizeTI, 0)
NumPut(vSizeTI, &TOOLINFO, 0, "UInt") ;cbSize
NumPut(0x20, &TOOLINFO, 4, "UInt") ;uFlags ;TTF_TRACK := 0x20
NumPut(&vText, &TOOLINFO, A_PtrSize=8?48:36, "Ptr") ;lpszText

;create window
;TTS_NOPREFIX := 0x2 ;TTS_ALWAYSTIP := 0x1
;WS_EX_TOPMOST := 0x8
hTT := DllCall("user32\CreateWindowEx", UInt,0x8, Str,"tooltips_class32", Ptr,0, UInt,0x3, Int,0, Int,0, Int,0, Int,0, Ptr,A_ScriptHwnd, Ptr,0, Ptr,0, Ptr,0)

;set text/background colours, and distance between text/margins
;vColBk := 0x00FFFF ;BGR
;vColTx := 0xFF0000 ;BGR
vColBk := 0xF0F0F0 ;BGR
vColTx := 0x000000 ;BGR
DllCall("uxtheme\SetWindowTheme", Ptr,hTT, Ptr,0, Str,"")
VarSetCapacity(RECT, 16, 0)
;vRect := "4,4,4,1"
;vRect := "20,20,20,20"
vRect := "8,4,180,1"
Loop, Parse, vRect, % ","
	NumPut(A_LoopField, &RECT, A_Index*4-4, "Int")
SendMessage, 0x41A, 0, % &RECT,, % "ahk_id " hTT ;TTM_SETMARGIN := 0x41A
SendMessage, 0x413, % vColBk, 0,, % "ahk_id " hTT ;TTM_SETTIPBKCOLOR := 0x413
SendMessage, 0x414, % vColTx, 0,, % "ahk_id " hTT ;TTM_SETTIPTEXTCOLOR := 0x414

;to allow multiline ToolTips
SendMessage, 0x418, 0, 200,, % "ahk_id " hTT ;TTM_SETMAXTIPWIDTH := 0x418

;set font
vFontName := "MS Shell Dlg", vFontSize := 18
vFontWeight := 400, vFontHeight := -Round(vFontSize*A_ScreenDPI/72)
hFont := DllCall("gdi32\CreateFont", Int,vFontHeight, Int,0, Int,0, Int,0, Int,vFontWeight, UInt,0, UInt,0 ,UInt,0, UInt,0, UInt,0, UInt,0, UInt,0, UInt,0, Str,vFontName, Ptr)
SendMessage, 0x30, % hFont, 0,, % "ahk_id " hTT ;WM_SETFONT := 0x30

SendMessage, % A_IsUnicode?0x432:0x404, 0, % &TOOLINFO,, % "ahk_id " hTT ;TTM_ADDTOOLW := 0x432
vWinX := 300, vWinY := 300
SendMessage, 0x412, 0, % (vWinX&0xFFFF)|(vWinY<<16),, % "ahk_id " hTT ;TTM_TRACKPOSITION := 0x412
SendMessage, 0x411, 1, % &TOOLINFO,, % "ahk_id " hTT ;TTM_TRACKACTIVATE := 0x411

;didn't work to set border style
;WinSet, Style, +0x40000, % "ahk_id " hTT
;WinSet, Style, +0x400000, % "ahk_id " hTT
;WinSet, Style, +0x800000, % "ahk_id " hTT

;unknown ExStyle
;WinSet, ExStyle, -0x80000, % "ahk_id " hTT

;didn't work to resize ToolTip
;WinMove, % "ahk_id " hTT,, 300, 300, 302, 41

Progress, zh0 b1 c0 fs18 x300 y440, % vText2
Sleep, 5000
DllCall("DestroyWindow", Ptr,hTT)
Progress, Off
return
Last edited by jeeswg on 07 Mar 2018, 10:46, edited 4 times in total.
User avatar
jeeswg
Posts: 5273
Joined: 19 Dec 2016, 01:58
Location: UK

Re: ToolTips: set border colour

12 Sep 2017, 10:45

There's another rumour that the SplashImage command will be removed from AutoHotkey v2. I often use the SplashImage command four times to create borders around a control, and so I'm trying to recreate these 'SplashImage Borders' by creating a GUI with a hole in it directly.

It's not relevant to ToolTips directly, although it is related to GUIs and borders. Anyhow, I wanted the two pieces of code to be kept together.

Code: Select all

;based on example at the very bottom of:
;WinSet
;https://autohotkey.com/docs/commands/WinSet.htm
q:: ;draw borders around the active window/control
vWinClass := "CustomClass"
vFunc := "MyBordersWndProc"
pWndProc := RegisterCallback(vFunc, "F")
vPIs64 := (A_PtrSize=8)
vSize := vPIs64?80:48
VarSetCapacity(WNDCLASSEX, vSize, 0)
NumPut(vSize, &WNDCLASSEX, 0, "UInt") ;cbSize
NumPut(pWndProc, &WNDCLASSEX, 8, "Ptr") ;lpfnWndProc
;vColBGR := 0x00FFFF ;yellow
vColBGR := 0x0000FF ;red
hBrush := DllCall("CreateSolidBrush", UInt,vColBGR, Ptr)
NumPut(hBrush, &WNDCLASSEX, vPIs64?48:32, "Ptr") ;hbrBackground
NumPut(&vWinClass, &WNDCLASSEX, vPIs64?64:40, "Ptr") ;lpszClassName
DllCall("RegisterClassEx", Ptr,&WNDCLASSEX, UShort)

WinGet, hWnd, ID, A
ControlGetFocus, vCtlClassNN, % "ahk_id " hWnd
ControlGet, hWnd, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
WinGetPos, vWinX, vWinY, vWinW, vWinH, % "ahk_id " hWnd
vBdrWidth := 5
vWinX -= vBdrWidth, vWinY -= vBdrWidth
vWinW += vBdrWidth*2, vWinH += vBdrWidth*2

DetectHiddenWindows, On
;WS_POPUP := 0x80000000
;WS_EX_TOOLWINDOW := 0x80 ;WS_EX_TOPMOST := 0x8
vWinText := "", vWinStyle := 0x80000000, vWinExStyle := 0x88
;vWinX := 100, vWinY := 100, vWinW := 300, vWinH := 300
hWnd := DllCall("CreateWindowEx", UInt,vWinExStyle, Str,vWinClass, Str,vWinText, UInt,vWinStyle, Int,vWinX, Int,vWinY, Int,vWinW, Int,vWinH, Ptr,0, Ptr,0, Ptr,0, Ptr,0, Ptr)
;vBdrL := 10, vBdrR := 10, vBdrT := 10, vBdrB := 10
vBdrL := vBdrR := vBdrT := vBdrB := vBdrWidth
oArray := [vWinW, vWinH, vBdrL, vWinW-vBdrR, vBdrT, vWinH-vBdrB]
vRegion := Format("0-0 {1:}-0 {1:}-{2:} 0-{2:} 0-0" " {3:}-{5:} {4:}-{5:} {4:}-{6:} {3:}-{6:} {3:}-{5:}", oArray*)
WinSet, Region, % vRegion, % "ahk_id " hWnd
WinShow, % "ahk_id " hWnd

Sleep, 3000
DllCall("DestroyWindow", Ptr,hWnd)
return

MyBordersWndProc(hWnd, uMsg, wParam, lParam)
{
	return DllCall("DefWindowProc", Ptr,hWnd, UInt,uMsg, UPtr,wParam, Ptr,lParam, Ptr)
}
Last edited by jeeswg on 07 Mar 2018, 09:50, edited 1 time in total.
User avatar
jeeswg
Posts: 5273
Joined: 19 Dec 2016, 01:58
Location: UK

Re: ToolTips: set border colour

13 Sep 2017, 10:37

Well, for the sake of the border colour, but actually, probably to result in a more versatile i.e. easy to modify script, 'Progress ToolTips' by creating a GUI from scratch using DllCall:

Code: Select all

q:: ;'Progress ToolTip'
vWinClass := "CustomClass"
vFunc := "MyToolTipExWndProc"
pWndProc := RegisterCallback(vFunc, "F")
vPIs64 := (A_PtrSize=8)
vSize := vPIs64?80:48
VarSetCapacity(WNDCLASSEX, vSize, 0)
NumPut(vSize, &WNDCLASSEX, 0, "UInt") ;cbSize
NumPut(pWndProc, &WNDCLASSEX, 8, "Ptr") ;lpfnWndProc
hCursor := DllCall("LoadCursor", Ptr,0, Ptr,32512, Ptr) ;IDC_ARROW := 32512
;vColBGR := 0x00FFFF ;yellow
;vColBGR := 0x0000FF ;red
hBrush := 16
;hBrush := DllCall("CreateSolidBrush", UInt,vColBGR, Ptr)
NumPut(hCursor, &WNDCLASSEX, vPIs64?40:28, "Ptr") ;hCursor
NumPut(hBrush, &WNDCLASSEX, vPIs64?48:32, "Ptr") ;hbrBackground
NumPut(&vWinClass, &WNDCLASSEX, vPIs64?64:40, "Ptr") ;lpszClassName
DllCall("RegisterClassEx", Ptr,&WNDCLASSEX, UShort)

;create window
DetectHiddenWindows, On
;WS_POPUP := 0x80000000
;WS_DISABLED := 0x8000000
;WS_CLIPSIBLINGS := 0x4000000
;WS_BORDER := 0x800000
;Progress windows use WS_DISABLED and WS_CLIPSIBLINGS, are these necessary?

;WS_EX_TOOLWINDOW := 0x80 ;WS_EX_TOPMOST := 0x8
vWinText := "", vWinStyle := 0x8C800000, vWinExStyle := 0x88
;vWinX := 100, vWinY := 100, vWinW := 300, vWinH := 300
vWinX := 300, vWinY := 300, vWinW := 302, vWinH := 99
hGui := DllCall("CreateWindowEx", UInt,vWinExStyle, Str,vWinClass, Str,vWinText, UInt,vWinStyle, Int,vWinX, Int,vWinY, Int,vWinW, Int,vWinH, Ptr,A_ScriptHwnd, Ptr,0, Ptr,0, Ptr,0, Ptr)

;create Static control
vWinClass := "Static", vWinText := "hello world`r`nhello world`r`nhello world"
;WS_CHILD := 0x40000000 ;WS_VISIBLE := 0x10000000
;SS_EDITCONTROL := 0x2000 ;SS_NOPREFIX := 0x80
vWinStyle := 0x50002080, vWinExStyle := 0
;vWinX := 0, vWinY := 0, vWinW := 300, vWinH := 300
vWinX := 11, vWinY := 6, vWinW := 280, vWinH := 92
hStc := DllCall("CreateWindowEx", UInt,vWinExStyle, Str,vWinClass, Str,vWinText, UInt,vWinStyle, Int,vWinX, Int,vWinY, Int,vWinW, Int,vWinH, Ptr,hGui, Ptr,0, Ptr,0, Ptr,0, Ptr)

;set font
vFontName := "MS Shell Dlg", vFontSize := 18
vFontWeight := 400, vFontHeight := -Round(vFontSize*A_ScreenDPI/72)
hFont := DllCall("gdi32\CreateFont", Int,vFontHeight, Int,0, Int,0, Int,0, Int,vFontWeight, UInt,0, UInt,0 ,UInt,0, UInt,0, UInt,0, UInt,0, UInt,0, UInt,0, Str,vFontName, Ptr)
SendMessage, 0x30, % hFont, 0,, % "ahk_id " hStc ;WM_SETFONT := 0x30

;vColBk := 0xEFCDAB ;BGR
;vColTx := 0x0000FF ;BGR
vColBk := 0xF0F0F0 ;BGR
vColTx := 0x000000 ;BGR
a := {c:hStc, g:hGui, bc:vColBk, tc:vColTx}
MyStaticWindowProc("Set", a, "", "")
WinSet, Redraw,, % "ahk_id " hStc

Progress, zh0 b1 c0 fs18 x300 y440, % vWinText
WinShow, % "ahk_id " hGui

Sleep, 3000
Progress, Off
DllCall("DestroyWindow", Ptr,hGui)
return

;==================================================

MyToolTipExWndProc(hWnd, uMsg, wParam, lParam)
{
	return DllCall("DefWindowProc", Ptr,hWnd, UInt,uMsg, UPtr,wParam, Ptr,lParam, Ptr)
}

;based on:
;ControlCol() - Set background and text color Gui Controls - Scripts and Functions - AutoHotkey Community
;https://autohotkey.com/board/topic/104539-controlcol-set-background-and-text-color-gui-controls/
MyStaticWindowProc(hWnd, uMsg, wParam, lParam)
{
	static Win := {}
	Critical
	if (uMsg = 0x138) ;WM_CTLCOLORSTATIC := 0x138
	&& Win[hWnd].HasKey(lParam)
	{
		if tc := Win[hWnd, lParam, "tc"]
			DllCall("SetTextColor", Ptr,wParam, UInt,tc)
		if bc := Win[hWnd, lParam, "bc"]
			DllCall("SetBkColor", Ptr,wParam, UInt,bc)
		return Win[hWnd, lParam, "Brush"] ;Return the HBRUSH to notify the OS that we altered the HDC.
	}
	if (hWnd = "Set")
	{
		a := uMsg
		Win[a.g, a.c] := a
		if (Win[a.g, a.c, "tc"] = "") and (Win[a.g, a.c, "bc"] = "")
			Win[a.g].Remove(a.c, "")
		if !Win[a.g, "WindowProcOld"]
			Win[a.g,"WindowProcOld"] := DllCall("SetWindowLong" vSfx, Ptr,a.g, Int,-4, Ptr,RegisterCallback(A_ThisFunc, "", 4), Ptr) ;GWL_WNDPROC := -4
		vSfx := (A_PtrSize=8) ? "Ptr" : ""
		if Win[a.g, a.c, "Brush"]
			DllCall("DeleteObject", Ptr,Brush)
		if (Win[a.g, a.c, "bc"] != "")
			Win[a.g, a.c, "Brush"] := DllCall("CreateSolidBrush", UInt,a.bc, Ptr)
		return
	}
	return DllCall("CallWindowProc", Ptr,Win[hWnd, "WindowProcOld"], Ptr,hWnd, UInt,uMsg, UPtr,wParam, Ptr,lParam)
}

;==================================================
Btw doing this has reminded me of issues to do with setting the colours of controls with the Gui command, it would probably be good if AHK v2 supported this natively. It's a classic thing that people want and ask about, even as newbies.

Return to “Ask For Help”

Who is online

Users browsing this forum: Albireo, gwarble, Herchi, Mipha, Sabestian Caine and 66 guests