2 sets of functions for text overlays on a HUD

Post your working scripts, libraries and tools for AHK v1.1 and older
freiheit
Posts: 7
Joined: 16 Oct 2020, 23:37

2 sets of functions for text overlays on a HUD

Post by freiheit » 17 Jun 2021, 21:25

A few days ago I posted in the support forum for help with positioning multiple controls in an Autohotkey GUI. Another user was kind enough to revise my code.

Purpose of code: To display a HUD style semi-transparent overlay on the screen with one or more rows of text. In my use case it displays the current time followed by the date. One function creates the semi-transparent overlay gui, another function adds a single text control (use as many times as the number of rows of test you wish to display), a 3rd function goes through all the controls in the gui to make them of uniform width (so that all the text will be centered), and the 4th function displays the final overlay.

Never satisfied with my initial solutions, I have been further updating the code to for the option of building 2 identical GUIs over top of one another so that the text (on the uppermost GUI) may be fully opaque while the background (lower GUI) is still semi-transparent. This uses the same 4 functions but with a '2' added to the ends of the function names indicating 2 GUIs. DO NOT mix the single-GUI and dual-GUI functions as each set makes assumptions about how many GUIs it is dealing with.

Am posting the full code here in the hopes that it may be useful to somebody, somewhere, sometime.

Here is the code to call the functions and setup what text will be displayed. To use the "2 guis" fully opaque text version add a 2 to the end of each function name, such as Overlay_CreateGUI2(), Overlay_CreateRow2(), etc.

Code: Select all

RWin::  ; Right Windows key
	; Setup overlay window
	WinID := Overlay_CreateGUI()

	; Setup row to display current time
	FormatTime, nowtime, , h:mm tt
	CtrlID := Overlay_CreateRow(72, nowTime)

	; Setup row to display current date
	FormatTime, nowdate, , MMM dd, yyyy
	CtrlID := Overlay_CreateRow(40, nowDate)

	; Make GUI control widths equal so all text can be centered
	Overlay_UniformCtrlWidths()

	; Show overlay window
	Overlay_ShowGUI(666)
Return
Here are the 8 functions (4 each for single GUI with text transparency and for dual GUI with fully opaque text).

Code: Select all

; First are the single-GUI functions.

Overlay_CreateGUI(LRM:=16, TBM:=4) {  ; LRM: left & right margin, TBM: top & bottom margin
	BGC = 333333

	Gui, 1: +AlwaysOnTop +ToolWindow -Caption +E0x20 ; Click through GUI always on top.
	Gui, 1: Color, %BGC%
	Gui, 1: Margin, %LRM%, %TBM%
	Gui, 1: +LastFound
	WinSet, Transparent, 180

	OverlayWin := WinExist()
	Return OverlayWin
}


Overlay_CreateRow(fontSize, textToShow) {
	TextFont := "Trebuchet MS Bold"
	; set some text colors to be chosen randomly, just for fun
	FGColorsList := ["AA8888", "88AA88", "8888AA", "AAAA88", "AA88AA", "88AAAA"]
	Random, randint, 1, % FGColorsList.MaxIndex()
	FGC := FGColorsList[randint]

	Gui, 1: Font, S%fontSize%, %TextFont%
	Gui, 1: Add, Text, xm y+0 center, %textToShow%
	Gui, 1: Add, Text, xp-3 yp-3 center c%FGC% BackgroundTrans, %textToShow%

	GuiControlGet, thisCtrl, hwnd, %textToShow%
	Return thisCtrl
}


; Set width of all gui controls to widest control
Overlay_UniformCtrlWidths() {
	CtrlWidth := 0  ; set variable to hold widest control found so far
	Gui, 1: +LastFound
	WinGet, cList, ControlListHwnd  ; get list of controls for the gui

	; Loop through once to find the widest button
	Loop, Parse, cList, "`n"
	{
		GuiControlGet, thisCtrl, Pos, %A_LoopField%
		If (thisCtrlW > CtrlWidth) {
			CtrlWidth := thisCtrlW + 5
		}
	}

	; Loop through second time to set all buttons to same width
	Loop, Parse, cList, "`n"
	{
		GuiControl, Move, %A_LoopField%, w%CtrlWidth%
	}
}


; show the final gui with both text controls (set some reasonable default values for size)
Overlay_ShowGUI(showTime:=1000) {
	Gui, 1: Show, NoActivate
	Sleep %showTime%
	Gui, 1: Destroy
}

; From here down are the dual-GUI functions.

Overlay_CreateGUI2(LRM:=16, TBM:=4) {  ; LRM: left & right margin, TBM: top & bottom margin
	BGC = 333333

	Gui, 1: +AlwaysOnTop +ToolWindow -Caption +E0x20 ; Click through GUI always on top.
	Gui, 1: Color, %BGC%
	Gui, 1: Margin, %LRM%, %TBM%
	Gui, 1: +LastFound
	WinSet, Transparent, 180

	Gui, 2: +AlwaysOnTop +ToolWindow -Caption +E0x20 ; Click through GUI always on top.
	Gui, 2: Color, %BGC%
	Gui, 2: Margin, %LRM%, %TBM%
	Gui, 2: +LastFound
	WinSet, Transcolor, %BGC%

	TextLayer := WinExist()
	Return TextLayer
}


Overlay_CreateRow2(fontSize, textToShow) {
	TextFont := "Trebuchet MS Bold"
	; set some text colors to be chosen randomly, just for fun
	FGColorsList := ["AA8888", "88AA88", "8888AA", "AAAA88", "AA88AA", "88AAAA"]
	Random, randint, 1, % FGColorsList.MaxIndex()
	FGC := FGColorsList[randint]

	Gui, 1: Font, S%fontSize%, %TextFont%
	Gui, 1: Add, Text, xm y+0 center cBlack BackgroundTrans, %textToShow%

	Gui, 2: Font, S%fontSize%, %TextFont%
	Gui, 2: Add, Text, xm y+0 center c%FGC% BackgroundTrans, %textToShow%

	GuiControlGet, thisCtrl, hwnd, %textToShow%
	Return thisCtrl
}


; Set width of all gui controls to widest control
Overlay_UniformCtrlWidths2() {
	Loop, 2  ; loop through both GUIs
	{
		CtrlWidth := 0  ; set variable to hold widest control found so far
		Gui, %A_Index%: +LastFound
		WinGet, cList, ControlListHwnd  ; get list of controls for the gui

		; Loop through once to find the widest button
		Loop, Parse, cList, "`n"
		{
			GuiControlGet, thisCtrl, Pos, %A_LoopField%
			If (thisCtrlW > CtrlWidth) {
				CtrlWidth := thisCtrlW + 5
			}
		}

		; Loop through second time to set all buttons to same width
		Loop, Parse, cList, "`n"
		{
			GuiControl, Move, %A_LoopField%, w%CtrlWidth%
		}
	}
}


; show the final gui with both text controls (set some reasonable default values for size)
Overlay_ShowGUI2(showTime:=1000) {
	Gui, 1: Show, NoActivate

	; get coordinates of Gui 1 so Gui 2 can be positioned slightly off to create a drop shadow
	; Gui 1 is the drop shadow while Gui 2 has the opaque, colorful text
	Gui, 1: +LastFound
	WinGetPos, G1X, G1Y, G1W, G1H
	NextX := G1X - 3
	NextY := G1Y - 3
	Gui, 2: Show, x%NextX% y%NextY% NoActivate

	Sleep %showTime%

	Gui, 1: Destroy
	Gui, 2: Destroy
}
User avatar
Delta Pythagorean
Posts: 627
Joined: 13 Feb 2017, 13:44
Location: Somewhere in the US
Contact:

Re: 2 sets of functions for text overlays on a HUD

Post by Delta Pythagorean » 18 Jun 2021, 14:58

How about, instead of creating the GUI everytime you press the hotkey, you instead create the GUI when starting the script, and then show the GUI when pressing the hotkey?

[AHK]......: v2.0.12 | 64-bit
[OS].......: Windows 11 | 23H2 (OS Build: 22621.3296)
[GITHUB]...: github.com/DelPyth
[PAYPAL]...: paypal.me/DelPyth
[DISCORD]..: tophatcat

Post Reply

Return to “Scripts and Functions (v1)”