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