Colored Groupbox

Post your working scripts, libraries and tools for AHK v1.1 and older
doubledave22
Posts: 343
Joined: 08 Jun 2019, 17:36

Colored Groupbox

Post by doubledave22 » 03 May 2022, 15:10

Requires Gdip_all: viewtopic.php?t=6517

Had a use for a custom colored groupbox and couldn't find anything. Tried to make this a 1:1 replacement for the built in groupbox for GUIs.

Examples found in script below:
Customize thickness, line color, and text padding. The rest should be pretty self explanatory. Hope someone finds this useful

This could probably be done much better so definitely open to suggestions

Code: Select all

#NoEnv
#SingleInstance force
#include Gdip_All.ahk
OnExit CleanUp


If !pToken := Gdip_Startup()
{
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}

gui, color, 333333

gui, font, s12 cWhite
Custom_GroupBox(1					; GUI Name
				, "Groupbox Title1"	; Title text (can be empty "") for a simple box
				, "m+25"			; X examples: "m+25", "s+15", "p", "25"
				, "m+25"			; Y examples: "m+25", "s+15", "p", "25"
				, 200				; Groupbox Width
				, 150				; Groupbox Height
				, "FFFF00"			; Groupbox line color
				, 1					; Thickness
				, 5					; Text padding
				, "Center"			; Position (default is "Center") but Left and Right also supported
				, "Section")		; optional section here

gui, add, text, yp+25 xp+10 wp-20 center, Here is some inner text

gui, font, s15 cYellow

Custom_GroupBox(1					; GUI Name
				, "Title2"			; Title text (can be empty "") for a simple box
				, "+25"				; X examples: "m+25", "s+15", "p", "25"
				, "s"				; Y examples: "m+25", "s+15", "p", "25"
				, 200				; Groupbox Width
				, 150				; Groupbox Height
				, "FF00FF"			; Groupbox line color
				, 3					; Thickness
				, 5					; Text padding
				, "Right")			; Position (default is "Center") but Left and Right also supported

gui, add, text, yp+25 xp+10 wp-20 center, Here is some inner text

gui, font, s8 cRed

Custom_GroupBox(1					; GUI Name
				, "Groupbox Title3"	; Title text (can be empty "") for a simple box
				, "s"				; X examples: "m+25", "s+15", "p", "25"
				, "s+175"			; Y examples: "m+25", "s+15", "p", "25"
				, 200				; Groupbox Width
				, 150				; Groupbox Height
				, "0000FF"			; Groupbox line color
				, 10				; Thickness
				, 10				; Text padding
				, "Left")			; Position (default is "Center") but Left and Right also supported

gui, add, text, yp+25 xp+10 wp-20 center, Here is some inner text

gui, show, w500 h500
return

Custom_GroupBox(GUIName, vText, gX, gY, gW, gH, Line_Color, Thickness, Padding := 5, Position := "Center", Options := "", DPI_Adjust := 1)
{
	; start with the text control and add additional padding
	gui, %GUIName%: add, text, % Position " backgroundtrans hwndvHwnd x" gX " y" gY " w" gW - (Padding * 4) - (Thickness * 2) " h" gH, % vText

	; grab the visible text dimensions (this isn't quite right if using newlines)
	Text_width_height(vhWnd, tW, tH)

	; adjust for high dpi, set DPI_Adjust to 0 if your GUI is using -dpiscale
	if (DPI_Adjust)
	{
		tW /= (a_screendpi/96)
		tH /= (a_screendpi/96)
	}

	; center the text vertically with the top lines
	Added_Y := ceil((tH/2) - (Thickness/2))

	; reposition X to account for inputs such as "+20" or "s+20"
	guicontrolget, vPos, %GUIName%:pos, % vHwnd
	
	; add addition X offsets
	guicontrol, %GUIName%: move, % vHwnd, % "x" vPosX + (Padding * 2) + Thickness
	
	; grab new position
	guicontrolget, vPos, %GUIName%:pos, % vHwnd
	
	; get top Y coordinate before moving the text up
	Top_Y := vPosY + Added_Y
	
	; left edge
	Colored_Square(GUIName, 1, 1, Line_Color, "w" Thickness " h" gH - Added_Y " x" vPosX - Thickness - (Padding * 2) " yp" + Added_Y)
	
	; right edge
	Colored_Square(GUIName, 1, 1, Line_Color, "w" Thickness " hp xp" + gW - Thickness " yp")
	
	; bottom edge
	Colored_Square(GUIName, 1, 1, Line_Color, "w" gW - (Thickness*2) " h" Thickness " x" vPosX - (Padding * 2) " y" vPosY + vPosH - Thickness)
	
	; fill out groupbox if no text is made
	if (vText = "")
		return Colored_Square(GUIName, 1, 1, Line_Color, "wp h" Thickness " xp y" vPosY)
	
	;=========================== Find Top Line Dimensions ========================
	if (Position = "Center")
	{
		inner_width := gW - (Thickness * 2)
		Top_Line_Width_L := Top_Line_Width_R := Ceil(((inner_width - tW)/2) - Padding)
	}
	
	else if (Position = "Right")
	{
		Top_Line_Width_L := Ceil(gW - tW - (Padding * 3) - (Thickness * 2))
		Top_Line_Width_R := Padding - Thickness
	}
	
	else if (Position = "Left" or Position = "")
	{
		Top_Line_Width_L := Padding - Thickness
		Top_Line_Width_R := Ceil(gW - tW - (Padding * 3) - (Thickness * 2))
	}
	;=========================== Find Top Line Dimensions ========================
	
	; make sure widths dont go negative
	if (Top_Line_Width_L < Padding)
		Top_Line_Width_L := Padding
	
	if (Top_Line_Width_R < Padding)
		Top_Line_Width_R := Padding
	
	; Draw top lines
	Colored_Square(GUIName, 1, 1, Line_Color, "w" Top_Line_Width_L " h" Thickness " x" vPosX - (Padding * 2) " y" Top_Y)
	Colored_Square(GUIName, 1, 1, Line_Color, "w" Top_Line_Width_R " h" Thickness " x" vPosX - (Padding * 2) - (Thickness * 2) + gW - Top_Line_Width_R " y" Top_Y)
	
	; add dummy control for positioning purposes (this fills out the whole groupbox + height of the text)
	gui, %GUIName%: add, text, % Options " hidden x" vPosX - Thickness - (Padding * 2) " y" vPosY " w" gW " h" gH
}

Text_width_height(hWnd, ByRef w, ByRef h) 
{
	ControlGetText, String,, ahk_id %HwND%
	hDC			:= DllCall("GetDC", "UPtr", 0, "UPtr")
	HFONT		:= DllCall("User32.dll\SendMessage", "Ptr", hWnd, "Int", 0x31, "Ptr", 0, "Ptr", 0) ; WM_GETFONT := 0x31
	HFONT_OLD	:= DllCall("SelectObject", "UPtr", hDC, "UPtr", HFONT, "UPtr")
	
	VarSetCapacity(FontSize, 8)
    DllCall("GetTextExtentPoint32", "UPtr", hDC, "Str", String, "Int", StrLen(String), "UPtr", &FontSize)
	w:=NumGet(FontSize, 0, "UInt"), h:=NumGet(FontSize, 4, "UInt")
	
	; clean up
	DllCall("SelectObject", "UPtr", hDC, "UPtr", HFONT_OLD, "UPtr")
    DllCall("ReleaseDC", "UPtr", 0, "UPtr", hDC)
}

Colored_Square(GUIName, sWidth, sHeight, sColor, Position)
{ ; creates a square on any gui of sWidth vx sHeight of sColor with positional options and optional groupbox
	
	pBitmap := Gdip_CreateBitmap(sWidth,sHeight)                                                                  
	pGraphics:= Gdip_GraphicsFromImage(pBitmap)                 
	Gdip_GraphicsClear(pGraphics, "0xff" sColor)    
	hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap)

	Gui, %GUIName%: Add, Picture,% "backgroundtrans " Position " 0xE", HBITMAP:%hBitmap%
	
	; clean up
	Gdip_DeleteGraphics(pGraphics)
	DeleteObject(hBitmap)
	Gdip_DisposeImage(pBitmap)
}


CleanUp:
Gdip_Shutdown(pToken)
ExitApp
return

Esc::ExitApp

GroupboxColors.png
GroupboxColors.png (12.89 KiB) Viewed 680 times

Return to “Scripts and Functions (v1)”