[2024/06/06] ColorButton.ahk | Customize Gui Button Background/ Text/ Border Colors.

Post your working scripts, libraries and tools.
User avatar
NPerovic
Posts: 40
Joined: 31 Dec 2022, 01:25
Contact:

[2024/06/06] ColorButton.ahk | Customize Gui Button Background/ Text/ Border Colors.

01 May 2024, 13:37

This is an extended method for changing a button's background, text and border color.

Image


Updates: 2024/06/06
New Features:
  • Customise the button text colour.
  • Customise the button border colour.
  • Customise the button border display timing (always show, show on focus, never show).
  • Once the button background colour is set, you can use properties to alter various settings.
Added Properties
  • BackColor: Set/Get the Button Background Color (RGB).
  • TextColor: Set/Get the Button Text Color (RGB).
  • BorderColor: Button Border Color (RGB). (To set the border color, you must have used SetColor(), SetBackColor(), or BackColor to set the background color at least once beforehand.)
  • RoundedCorner: Rounded Corner Preference for the Button. (To set the rounded corner preference, you must have used SetColor(), SetBackColor(), or BackColor to set the background color at least once beforehand.)
  • ShowBorder: Border Preference.
    - 1: Highlight when focused.
    - 0: No border displayed.
    - -1: Border always visible.
For TextColor/ BorderColor/ RoundedCorner/ ShowBorder, you must have used SetColor(), SetBackColor(), or BackColor to set the background colour at least once beforehand.

Learn more: https://github.com/nperovic/ColorButton.ahk/releases/tag/v1.3.0



Updates: 2024/05/06
  • Update structure for 32-bit AutoHotkey v2.0.X. (No changes for the structure for v2.1-alpha.x)
  • Fixed the corner issues for win 10 users.
Note: Those structure classes for v2.0.X works the same way as v2.1-alpha.x.



Features
  • Easily change a button's color.
  • Automatically set the text colour to white or black depends on the background colour.
  • Compatible with AutoHotkey v2.1-alpha.9 or later. Update: v2.0 is also supported now.
  • Learn more about the ahk v2.1-alpha: Click here

Rounded Button
Image

No Rounded Corners
Image


How To Use
  1. Download the ColorButton.ahk file.
  2. Include the ColorButton.ahk file in your script.
  3. Implement the background color by using the SetBackColor method on your button object.

SetColor

Code: Select all

GuiCtrl.SetColor(bgColor, txColor?, showBorder := 1, borderColor := 0xFFFFFF, roundedCorner?)

Parameters
bgColor
Type: Integer
Button's background color. (RGB)
txColor
Type: Integer (Optional)
Button text color (RGB). If omitted, the text colour will be automatically set to white or black depending on the background colour.
showBorder
Type: Boolean (Optional)
Border display preference.
1: Highlight when focused.
0: No border displayed.
-1: Border always visible.
borderColor
Type: Integer (Optional)
Button border color (RGB). Default is 0xFFFFFF.
roundedCorner
Type: Integer (Optional)
Rounded corner preference for the button.
For Windows 11: Enabled (value: 9).
For Windows 10: Disabled.

Examples


Get Code

GitHub: ColorButton.ahk



keywords: gui, gui button, win32 gui, button color, gui button color, change color, button background color, v2 gui, gdi, customdraw, roundrect, WM_NOTIFY, v2.1, alpha
Last edited by NPerovic on 06 Jun 2024, 10:41, edited 3 times in total.
✨ Dark Theme for Everything
✨ Other Scripts

just me
Posts: 9557
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: ColorButton.ahk | An extended method that lets you customize gui button background colors.

02 May 2024, 02:01

Moin,

running the code embedded in your v2.0 script with v2.0.13 on Win 10

Code: Select all

myGui := Gui()
myGui.SetFont("cWhite s24", "Segoe UI")
myGui.BackColor := 0x2c2c2c
btn := myGui.AddButton(, "SUPREME")
btn.SetBackColor(0xaa2031)
btn2 := myGui.AddButton(, "SUPREME")
btn2.SetBackColor(0xffd155)
myGui.Show("w300 h300")
i get:
Zwischenablage01.png
Zwischenablage01.png (10.11 KiB) Viewed 1876 times
ozzii
Posts: 485
Joined: 30 Oct 2013, 06:04

Re: ColorButton.ahk | An extended method that lets you customize gui button background colors.

02 May 2024, 03:51

Same like 'just me'
On Win 10 latest version/updates
But like this it's OK ;)
btn.SetBackColor(0xaa2031,, 0)
User avatar
NPerovic
Posts: 40
Joined: 31 Dec 2022, 01:25
Contact:

Re: ColorButton.ahk | An extended method that lets you customize gui button background colors.

03 May 2024, 13:58

just me wrote:
02 May 2024, 02:01
Moin,

running the code embedded in your v2.0 script with v2.0.13 on Win 10

Code: Select all

myGui := Gui()
myGui.SetFont("cWhite s24", "Segoe UI")
myGui.BackColor := 0x2c2c2c
btn := myGui.AddButton(, "SUPREME")
btn.SetBackColor(0xaa2031)
btn2 := myGui.AddButton(, "SUPREME")
btn2.SetBackColor(0xffd155)
myGui.Show("w300 h300")
i get:
Zwischenablage01.png

Thank you very much for the feedback:)

Could you please try this to see if it resolves the issue? I currently don't have access to a Windows 10 device to test it myself. Your assistance with testing would be immensely appreciated!


Code: Select all

class _BtnColor extends Gui.Button
{
    static __New() => super.Prototype.SetBackColor := ObjBindMethod(this, "SetBackColor")

    /**
     * @param {Gui.Button} myBtn omitted.
     * @param {integer} btnBgColor Button's background color. (RGB)
     * @param {integer} [colorBehindBtn] The color of the button's surrounding area. If omitted, if will be the same as `myGui.BackColor`. **(Usually let it be transparent looks better.)**
     * @param {integer} [roundedCorner] Specifies the rounded corner preference for the button. If omitted,        : 
     * > For Windows 11: Enabled. (value: 9)  
     * > For Windows 10: Disabled.   
     */
    static SetBackColor(myBtn, btnBgColor, colorBehindBtn?, roundedCorner?)
    {
        static BS_FLAT          := 0x8000
        static BS_BITMAP        := 0x0080
        static IS_WIN11         := (VerCompare(A_OSVersion, "10.0.22200") >= 0)
        static WM_CTLCOLORBTN   := 0x0135
        static NM_CUSTOMDRAW    := -12
        static WM_DESTROY       := 0x0002
        static WS_EX_COMPOSITED := 0x02000000
        static WS_CLIPSIBLINGS  := 0x04000000

        rcRgn       := unset
        clr         := IsNumber(btnBgColor) ? btnBgColor : ColorHex(btnBgColor)
        isDark      := IsColorDark(clr)
        hoverColor  := RgbToBgr(BrightenColor(clr, isDark ? 15 : -15))
        pushedColor := RgbToBgr(BrightenColor(clr, isDark ? -10 : 10))
        clr         := RgbToBgr(clr)
        btnBkColr   := (colorBehindBtn ?? !IS_WIN11) && RgbToBgr(ColorHex(myBtn.Gui.BackColor))
        hbrush      := (colorBehindBtn ?? !IS_WIN11) ? CreateSolidBrush(btnBkColr) : GetStockObject(5)

        myBtn.Gui.Opt("+" WS_CLIPSIBLINGS)
        myBtn.Gui.OnMessage(WM_CTLCOLORBTN, ON_WM_CTLCOLORBTN)

        if btnBkColr
            myBtn.Gui.OnEvent("Close", (*) => DeleteObject(hbrush))

        myBtn.Opt("+" (WS_CLIPSIBLINGS | BS_FLAT | BS_BITMAP)) ; 
        myBtn.OnNotify(NM_CUSTOMDRAW, (gCtrl, lParam) => ON_NM_CUSTOMDRAW(gCtrl, lParam))
        SetWindowTheme(myBtn.hwnd, isDark ? "DarkMode_Explorer" : "Explorer")

        ON_WM_CTLCOLORBTN(GuiObj, wParam, lParam, Msg)
        {
            Critical(-1)

            if (lParam != myBtn.hwnd) 
                return

            if (colorBehindBtn ?? !IS_WIN11) {
                SelectObject(wParam, hbrush)
                SetBkMode(wParam, 0)
                SetBkColor(wParam, btnBkColr)
            }

            return hbrush 
        }

        first := 1

        ON_NM_CUSTOMDRAW(gCtrl, lParam)
        {
            static CDDS_PREPAINT        := 0x1
            static CDDS_PREERASE        := 0x3
            static CDIS_HOT             := 0x40
            static CDRF_NOTIFYPOSTPAINT := 0x10
            static CDRF_SKIPPOSTPAINT   := 0x100
            static CDRF_SKIPDEFAULT     := 0x4
            static CDRF_NOTIFYPOSTERASE := 0x40
            static CDRF_DODEFAULT       := 0x0
            static DC_BRUSH             := GetStockObject(18)
            static DC_PEN               := GetStockObject(19)
            
            Critical(-1)

            lpnmCD := StructFromPtr(NMCUSTOMDRAWINFO, lParam)

            if (lpnmCD.hdr.code != NM_CUSTOMDRAW ||lpnmCD.hdr.hwndFrom != gCtrl.hwnd)
                return CDRF_DODEFAULT
            
            switch lpnmCD.dwDrawStage {
            case CDDS_PREERASE:
            {
                if (roundedCorner ?? IS_WIN11) {
                    rcRgn := CreateRoundRectRgn(lpnmCD.rc.left, lpnmCD.rc.top, lpnmCD.rc.right, lpnmCD.rc.bottom, roundedCorner ?? 9, roundedCorner ?? 9)
                    SetWindowRgn(gCtrl.hwnd, rcRgn, 1)
                }
                SetBkMode(lpnmCD.hdc, 0)
                return CDRF_NOTIFYPOSTERASE 
            }
            case CDDS_PREPAINT: 
            {
                isPressed  := GetKeyState("LButton", "P")
                brushColor := (!(lpnmCD.uItemState & CDIS_HOT) || first ? clr : isPressed ? pushedColor : hoverColor)

                SelectObject(lpnmCD.hdc, DC_BRUSH)
                SetDCBrushColor(lpnmCD.hdc, brushColor)
                SelectObject(lpnmCD.hdc, DC_PEN)
                SetDCPenColor(lpnmCD.hdc, !first && gCtrl.Focused && !isPressed ? 0xFFFFFF : brushColor)

                rounded := !!(rcRgn ?? 0)

                if (!first && gCtrl.Focused && !isPressed) {
                    if !rounded {
                        lpnmCD.rc.left   += 1
                        lpnmCD.rc.top    += 1
                        lpnmCD.rc.right  -= 1
                        lpnmCD.rc.bottom -= 1
                    }
                    DrawFocusRect(lpnmCD.hdc, lpnmCD.rc)
                }

                if rounded {
                    RoundRect(lpnmCD.hdc, lpnmCD.rc.left, lpnmCD.rc.top, lpnmCD.rc.right - rounded, lpnmCD.rc.bottom - rounded, roundedCorner ?? 9, roundedCorner ?? 9)
                    DeleteObject(rcRgn)
                    rcRgn := ""                    
                }
                else {
                    FillRect(lpnmCD.hdc, lpnmCD.rc, DC_BRUSH)
                }

                if first
                    first := 0

                SetWindowPos(mybtn.hwnd, 0,,,,, 0x4043)

                return CDRF_NOTIFYPOSTPAINT
            }}
            
            return CDRF_DODEFAULT
        }

        static RgbToBgr(color) => (IsInteger(color) ? ((Color >> 16) & 0xFF) | (Color & 0x00FF00) | ((Color & 0xFF) << 16) : NUMBER(RegExReplace(STRING(color), "Si)c?(?:0x)?(?<R>\w{2})(?<G>\w{2})(?<B>\w{2})", "0x${B}${G}${R}")))

        static CreateRoundRectRgn(nLeftRect, nTopRect, nRightRect, nBottomRect, nWidthEllipse, nHeightEllipse) => DllCall('Gdi32\CreateRoundRectRgn', 'int', nLeftRect, 'int', nTopRect, 'int', nRightRect, 'int', nBottomRect, 'int', nWidthEllipse, 'int', nHeightEllipse, 'ptr')

        static CreateSolidBrush(crColor) => DllCall('Gdi32\CreateSolidBrush', 'uint', crColor, 'ptr')

        static ColorHex(clr) => Number((!InStr(clr, "0x") ? "0x" : "") clr)

        static DrawFocusRect(hDC, lprc) => DllCall("User32\DrawFocusRect", "ptr", hDC, "ptr", lprc, "int")

        static GetStockObject(fnObject) => DllCall('Gdi32\GetStockObject', 'int', fnObject, 'ptr')

        static SetWindowPos(hWnd, hWndInsertAfter, X := 0, Y := 0, cx := 0, cy := 0, uFlags := 0x40) => DllCall("User32\SetWindowPos", "ptr", hWnd, "ptr", hWndInsertAfter, "int", X, "int", Y, "int", cx, "int", cy, "uint", uFlags, "int")

        static SetDCPenColor(hdc, crColor) => DllCall('Gdi32\SetDCPenColor', 'ptr', hdc, 'uint', crColor, 'uint')

        static SetDCBrushColor(hdc, crColor) => DllCall('Gdi32\SetDCBrushColor', 'ptr', hdc, 'uint', crColor, 'uint')

        static SetWindowRgn(hWnd, hRgn, bRedraw) => DllCall("User32\SetWindowRgn", "ptr", hWnd, "ptr", hRgn, "int", bRedraw, "int")

        static DeleteObject(hObject) {
            DllCall('Gdi32\DeleteObject', 'ptr', hObject, 'int')
        }

        static FillRect(hDC, lprc, hbr) => DllCall("User32\FillRect", "ptr", hDC, "ptr", lprc, "ptr", hbr, "int")

        static IsColorDark(clr) => 
            ( (clr >> 16 & 0xFF) / 255 * 0.2126 
            + (clr >>  8 & 0xFF) / 255 * 0.7152 
            + (clr       & 0xFF) / 255 * 0.0722 < 0.5 )

        static RGB(R := 255, G := 255, B := 255) => ((R << 16) | (G << 8) | B)
        
        static BrightenColor(clr, perc := 5) => ((p := perc / 100 + 1), RGB(Round(Min(255, (clr >> 16 & 0xFF) * p)), Round(Min(255, (clr >> 8 & 0xFF) * p)), Round(Min(255, (clr & 0xFF) * p))))

        static RoundRect(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect, nWidth, nHeight) => DllCall('Gdi32\RoundRect', 'ptr', hdc, 'int', nLeftRect, 'int', nTopRect, 'int', nRightRect, 'int', nBottomRect, 'int', nWidth, 'int', nHeight, 'int')
        
        static SetTextColor(hdc, color) => DllCall("SetTextColor", "Ptr", hdc, "UInt", color)
        
        static SetWindowTheme(hwnd, appName, subIdList?) => DllCall("uxtheme\SetWindowTheme", "ptr", hwnd, "ptr", StrPtr(appName), "ptr", subIdList ?? 0)
        
        static SelectObject(hdc, hgdiobj) => DllCall('Gdi32\SelectObject', 'ptr', hdc, 'ptr', hgdiobj, 'ptr')
                
        static SetBkColor(hdc, crColor) => DllCall('Gdi32\SetBkColor', 'ptr', hdc, 'uint', crColor, 'uint')
        
        static SetBkMode(hdc, iBkMode) => DllCall('Gdi32\SetBkMode', 'ptr', hdc, 'int', iBkMode, 'int')
    }
}
✨ Dark Theme for Everything
✨ Other Scripts

just me
Posts: 9557
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: ColorButton.ahk | An extended method that lets you customize gui button background colors.

04 May 2024, 01:49

Hi @NPerovic, I tested. Result on Win 10:
Zwischenablage01.png
Zwischenablage01.png (10.13 KiB) Viewed 1576 times
Thanks for sharing this script. It never occurred to me that buttons support custom draw.
just me
Posts: 9557
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: ColorButton.ahk | An extended method that lets you customize gui button background colors.

04 May 2024, 01:58

BTW:

Code: Select all

class NMCUSTOMDRAWINFO
{
    static Call(ptr)
    {
        return {
            hdr: {
                hwndFrom: NumGet(ptr, 0 ,"uptr"),
                idFrom  : NumGet(ptr, 8 ,"uptr"),
                code    : NumGet(ptr, 16 ,"int")
            },
            dwDrawStage: NumGet(ptr, 24, "uint"),
            hdc        : NumGet(ptr, 32, "uptr"),
            rc         : RECT(
                NumGet(ptr, 40, "uint"),
                NumGet(ptr, 44, "uint"),
                NumGet(ptr, 48, "int"),
                NumGet(ptr, 52, "int")
            ),
            dwItemSpec : NumGet(ptr, 56, "uptr"),
            uItemState : NumGet(ptr, 64, "int"),
            lItemlParam: NumGet(ptr, 72, "iptr")
        }
That's only for AHK64 (A_PtrSize = 8)
User avatar
NPerovic
Posts: 40
Joined: 31 Dec 2022, 01:25
Contact:

Re: ColorButton.ahk | An extended method that lets you customize gui button background colors.

05 May 2024, 19:51

just me wrote:
04 May 2024, 01:58
BTW:

Code: Select all

class NMCUSTOMDRAWINFO
{
    static Call(ptr)
    {
        return {
            hdr: {
                hwndFrom: NumGet(ptr, 0 ,"uptr"),
                idFrom  : NumGet(ptr, 8 ,"uptr"),
                code    : NumGet(ptr, 16 ,"int")
            },
            dwDrawStage: NumGet(ptr, 24, "uint"),
            hdc        : NumGet(ptr, 32, "uptr"),
            rc         : RECT(
                NumGet(ptr, 40, "uint"),
                NumGet(ptr, 44, "uint"),
                NumGet(ptr, 48, "int"),
                NumGet(ptr, 52, "int")
            ),
            dwItemSpec : NumGet(ptr, 56, "uptr"),
            uItemState : NumGet(ptr, 64, "int"),
            lItemlParam: NumGet(ptr, 72, "iptr")
        }
That's only for AHK64 (A_PtrSize = 8)
Right! Thanks for pointing this out. I've updated the code for the structure for v2.0 users.
✨ Dark Theme for Everything
✨ Other Scripts

sashaatx
Posts: 350
Joined: 27 May 2021, 08:27
Contact:

Re: ColorButton.ahk | An extended method that lets you customize gui button background colors.

06 May 2024, 10:44

NPerovic wrote:
05 May 2024, 19:51
just me wrote:
04 May 2024, 01:58
BTW:

Code: Select all

class NMCUSTOMDRAWINFO
{
    static Call(ptr)
    {
        return {
            hdr: {
                hwndFrom: NumGet(ptr, 0 ,"uptr"),
                idFrom  : NumGet(ptr, 8 ,"uptr"),
                code    : NumGet(ptr, 16 ,"int")
            },
            dwDrawStage: NumGet(ptr, 24, "uint"),
            hdc        : NumGet(ptr, 32, "uptr"),
            rc         : RECT(
                NumGet(ptr, 40, "uint"),
                NumGet(ptr, 44, "uint"),
                NumGet(ptr, 48, "int"),
                NumGet(ptr, 52, "int")
            ),
            dwItemSpec : NumGet(ptr, 56, "uptr"),
            uItemState : NumGet(ptr, 64, "int"),
            lItemlParam: NumGet(ptr, 72, "iptr")
        }
That's only for AHK64 (A_PtrSize = 8)
Right! Thanks for pointing this out. I've updated the code for the structure for v2.0 users.
hey big fan of your stuff.

I do a lot of gui work,
https://github.com/samfisherirl/Easy-Auto-GUI-for-AHK-v2 and
https://github.com/samfisherirl/Useful-AHK-v2-Libraries-and-Classes?tab=readme-ov-file#gui-libraries

I worked with GuiResizer for all of my commercial application guis due to various resolutions, and various displays for the same application.

I wrote a class that works with ImageButton.ahk, but Im not a big knower of DLL calls for default win32/C++ stuff.

See bottom gif and here for an example class for resizable image buttons: https://github.com/samfisherirl/GuiResizer-Addons/blob/main/ButtonStyle.ahk

I'd like to incorporate your solution into the GuiResizer, allowing the button size to be changed on the fly. I am not looking for you to write anything, if you could do me the courtesy of pointing me to the aspect of your script that executes the color change where I can tinker and attempt to implement it into a resizable design.

Let me know if you have any questions and thanks in advance.
Attachments
292956102-b30eccaa-faa9-42a7-ae3a-ef345383c1b8.gif
292956102-b30eccaa-faa9-42a7-ae3a-ef345383c1b8.gif (1023.05 KiB) Viewed 1287 times
https://github.com/samfisherirl
? /Easy-Auto-GUI-for-AHK-v2 ? /Useful-AHK-v2-Libraries-and-Classes : /Pulovers-Macro-Creator-for-AHKv2 :
User avatar
kczx3
Posts: 1649
Joined: 06 Oct 2015, 21:39

Re: [2024/05/06] ColorButton.ahk | An extended method that lets you customize gui button background colors.

06 May 2024, 11:01

As far as I can tell, nothing of the code presented in this thread pertains to the size of the button. It merely colors the button as it is sized.
sashaatx
Posts: 350
Joined: 27 May 2021, 08:27
Contact:

Re: [2024/05/06] ColorButton.ahk | An extended method that lets you customize gui button background colors.

06 May 2024, 11:19

kczx3 wrote:
06 May 2024, 11:01
As far as I can tell, nothing of the code presented in this thread pertains to the size of the button. It merely colors the button as it is sized.
sh*t youre right. this worked just fine, resizer and dark mode. Not sure why last time I tried, something conflicted.

Code: Select all

#Requires Autohotkey v2
#SingleInstance force
#Include <GuiReSizer>
#Include <ColorButton>
myCtrls := {}
myGui := Gui(), myGui.Opt("+Resize +MinSize250x150")
myGui.OnEvent("Size", GuiReSizer)
myCtrls.ButtonOK := myGui.Add("Button", "", "&OK").SetBackColor("0x7755ff", , 0)
pushToResizer(myCtrls.ButtonOK, .373, .153, .573, .727)


pushToResizer(ctrl, xp, yp, wp, hp)
{
	ctrl.xp := xp 
	ctrl.yp := yp 
	ctrl.wp := wp 
	ctrl.hp := hp 
}

myGui.Show()
https://github.com/samfisherirl
? /Easy-Auto-GUI-for-AHK-v2 ? /Useful-AHK-v2-Libraries-and-Classes : /Pulovers-Macro-Creator-for-AHKv2 :
sashaatx
Posts: 350
Joined: 27 May 2021, 08:27
Contact:

Re: ColorButton.ahk | An extended method that lets you customize gui button background colors.

07 May 2024, 04:25

NPerovic wrote:
05 May 2024, 19:51
just me wrote:
04 May 2024, 01:58
BTW:

Code: Select all

class NMCUSTOMDRAWINFO
{
    static Call(ptr)
    {
        return {
            hdr: {
                hwndFrom: NumGet(ptr, 0 ,"uptr"),
                idFrom  : NumGet(ptr, 8 ,"uptr"),
                code    : NumGet(ptr, 16 ,"int")
            },
            dwDrawStage: NumGet(ptr, 24, "uint"),
            hdc        : NumGet(ptr, 32, "uptr"),
            rc         : RECT(
                NumGet(ptr, 40, "uint"),
                NumGet(ptr, 44, "uint"),
                NumGet(ptr, 48, "int"),
                NumGet(ptr, 52, "int")
            ),
            dwItemSpec : NumGet(ptr, 56, "uptr"),
            uItemState : NumGet(ptr, 64, "int"),
            lItemlParam: NumGet(ptr, 72, "iptr")
        }
That's only for AHK64 (A_PtrSize = 8)
Right! Thanks for pointing this out. I've updated the code for the structure for v2.0 users.
personal choice, but I try to return ctrls back from methods but this may be bad practice for some reason

Code: Select all

	;line 232 
	        static SelectObject(hdc, hgdiobj) => DllCall('Gdi32\SelectObject', 'ptr', hdc, 'ptr', hgdiobj, 'ptr')
                
        static SetBkColor(hdc, crColor) => DllCall('Gdi32\SetBkColor', 'ptr', hdc, 'uint', crColor, 'uint')
        
        static SetBkMode(hdc, iBkMode) => DllCall('Gdi32\SetBkMode', 'ptr', hdc, 'int', iBkMode, 'int')
        
        return myBtn
    }
}
 
; now
G.btn := G.Add("Button", "", "&OK").SetBgColor(0x000000)
https://github.com/samfisherirl
? /Easy-Auto-GUI-for-AHK-v2 ? /Useful-AHK-v2-Libraries-and-Classes : /Pulovers-Macro-Creator-for-AHKv2 :
User avatar
NPerovic
Posts: 40
Joined: 31 Dec 2022, 01:25
Contact:

Re: ColorButton.ahk | An extended method that lets you customize gui button background colors.

08 May 2024, 15:07

sashaatx wrote:
06 May 2024, 10:44
hey big fan of your stuff.

I do a lot of gui work,
https://github.com/samfisherirl/Easy-Auto-GUI-for-AHK-v2 and
https://github.com/samfisherirl/Useful-AHK-v2-Libraries-and-Classes?tab=readme-ov-file#gui-libraries

I worked with GuiResizer for all of my commercial application guis due to various resolutions, and various displays for the same application.

I wrote a class that works with ImageButton.ahk, but Im not a big knower of DLL calls for default win32/C++ stuff.

See bottom gif and here for an example class for resizable image buttons: https://github.com/samfisherirl/GuiResizer-Addons/blob/main/ButtonStyle.ahk

I'd like to incorporate your solution into the GuiResizer, allowing the button size to be changed on the fly. I am not looking for you to write anything, if you could do me the courtesy of pointing me to the aspect of your script that executes the color change where I can tinker and attempt to implement it into a resizable design.

Let me know if you have any questions and thanks in advance.

Thank you for reaching out and for your kind words! I’m thrilled to hear that you’re a fan of my work. 😊

I often recommend your “Easy Auto GUI for AHK v2” to beginners who are looking to build GUIs with AHK, and it’s great to see such valuable resources being shared within the community.👍

Regarding the button resizing issue, I noticed in your subsequent reply that it seems to be resolved now.

Should you have any further questions or suggestions, please do not hesitate to let me know. 😊
✨ Dark Theme for Everything
✨ Other Scripts

sashaatx
Posts: 350
Joined: 27 May 2021, 08:27
Contact:

Re: [2024/05/06] ColorButton.ahk | An extended method that lets you customize gui button background colors.

02 Jun 2024, 12:05

@NPerovic small error running into on line 277,

when relaunching script already open, and #SingleInstance Force enabled, 'first' has not been assigned a value.

Only lightly tested, Ill edit if it doesnt do as indented or breaks anything. Change !first to !IsSet(first)

Code: Select all

                drawFocused := (showFocusedBorder && !IsSet(first) && gCtrl.Focused && !isPressed)
edit it appears first causes a few throws.

The usecase that is likely different than other gui's is Im using guiresizer. Controls are being set to visible and invisible regularly instead of traditional .hwnd +Parent for changing controls within child guis, and after .Show() controls are being added to the gui object.


Call stack:
C:\Users\dower\OneDrive\Documents\AutoHotkey\Lib\ColorButton.ahk (300) : [ON_NM_CUSTOMDRAW] If first
C:\Users\dower\OneDrive\Documents\AutoHotkey\Lib\ColorButton.ahk (225) : [] Return ON_NM_CUSTOMDRAW(gCtrl, lParam)
> Gui
C:\Users\dower\OneDrive\Documents\AutoHotkey\Lib\ColorButton.ahk (279) : [ON_NM_CUSTOMDRAW] brushColor := (!isHot || first ? clr : isPressed ? pushedColor : hoverColor)
C:\Users\dower\OneDrive\Documents\AutoHotkey\Lib\ColorButton.ahk (225) : [] Return ON_NM_CUSTOMDRAW(gCtrl, lParam)
> Gui
C:\Users\dower\OneDrive\Documents\AutoHotkey\Lib\ColorButton.ahk (300) : [ON_NM_CUSTOMDRAW] If first
C:\Users\dower\OneDrive\Documents\AutoHotkey\Lib\ColorButton.ahk (225) : [] Return ON_NM_CUSTOMDRAW(gCtrl, lParam)
> Gui
C:\Users\dower\OneDrive\Documents\AutoHotkey\Lib\ColorButton.ahk (228) : [_BtnColor.Prototype.BackColor] SetWindowPos(this.hwnd, 0,,,,, 0x43)
G:\My Drive\_TEMeats_ahk\WeightStation\_genderOptions.ahk (70) : [genderOptions.initGenderGui] G.genderWeight.main.gender2 := G.Add("Button", "", "&Gender2").BackColor('0xa0ffd3')
G:\My Drive\_TEMeats_ahk\WeightStation\_genderOptions.ahk (52) : [genderOptions.Call] genderOptions.initGenderGui(&G)
G:\My Drive\_TEMeats_ahk\WeightStation\_WeightStation.ahk (31) : [] genderOptions(&wsGUI, &animalObj)
Attachments
image.png
image.png (441 KiB) Viewed 408 times
https://github.com/samfisherirl
? /Easy-Auto-GUI-for-AHK-v2 ? /Useful-AHK-v2-Libraries-and-Classes : /Pulovers-Macro-Creator-for-AHKv2 :
sashaatx
Posts: 350
Joined: 27 May 2021, 08:27
Contact:

Re: [2024/05/06] ColorButton.ahk | An extended method that lets you customize gui button background colors.

02 Jun 2024, 21:32

here's the solution that worked for me after testing for a few hours, ctrl-f `first` for changes

Code: Select all

            case CDDS_PREPAINT : 
            {
                isPressed   := GetKeyState("LButton", "P")
                isHot       := (lpnmCD.uItemState & CDIS_HOT)
                corner      := (roundedCorner ?? (IS_WIN11 ? 9 : 0))
                drawFocused := (showFocusedBorder && !IsSet(first) && gCtrl.Focused && !isPressed)

                brushColor := (!isHot || first ? clr : isPressed ? pushedColor : hoverColor)
                penColor   := (drawFocused ? 0xFFFFFF : brushColor)

                rc    := lpnmCD.rc
                rcRgn := CreateRoundRectRgn(rc.left, rc.top, rc.right, rc.bottom, corner, corner)
                SetWindowRgn(gCtrl.hwnd, rcRgn, 1)
                DeleteObject(rcRgn)

                SelectObject(lpnmCD.hdc, DC_BRUSH)
                SetDCBrushColor(lpnmCD.hdc, brushColor)

                SelectObject(lpnmCD.hdc, DC_PEN)
                SetDCPenColor(lpnmCD.hdc, penColor)

                SetBkMode(lpnmCD.hdc, 0)

                if drawFocused 
                    FrameRgn(lpnmCD.hdc, rcRgn, DC_PEN, rc.Width, rc.Height)

                RoundRect(lpnmCD.hdc, rc.left, rc.top, rc.right-1, rc.bottom-1, corner, corner)

                if IsSet(first) && first
                    first := 0

                SetWindowPos(this.hwnd, 0, 0, 0, 0, 0, 0x4043)

                return CDRF_NOTIFYPOSTPAINT
            }}
            
            return CDRF_DODEFAULT
        }
https://github.com/samfisherirl
? /Easy-Auto-GUI-for-AHK-v2 ? /Useful-AHK-v2-Libraries-and-Classes : /Pulovers-Macro-Creator-for-AHKv2 :
User avatar
NPerovic
Posts: 40
Joined: 31 Dec 2022, 01:25
Contact:

Re: [2024/05/06] ColorButton.ahk | An extended method that lets you customize gui button background colors.

Today, 10:43

sashaatx wrote:
02 Jun 2024, 21:32
here's the solution that worked for me after testing for a few hours, ctrl-f `first` for changes

Code: Select all

            case CDDS_PREPAINT : 
            {
                isPressed   := GetKeyState("LButton", "P")
                isHot       := (lpnmCD.uItemState & CDIS_HOT)
                corner      := (roundedCorner ?? (IS_WIN11 ? 9 : 0))
                drawFocused := (showFocusedBorder && !IsSet(first) && gCtrl.Focused && !isPressed)

                brushColor := (!isHot || first ? clr : isPressed ? pushedColor : hoverColor)
                penColor   := (drawFocused ? 0xFFFFFF : brushColor)

                rc    := lpnmCD.rc
                rcRgn := CreateRoundRectRgn(rc.left, rc.top, rc.right, rc.bottom, corner, corner)
                SetWindowRgn(gCtrl.hwnd, rcRgn, 1)
                DeleteObject(rcRgn)

                SelectObject(lpnmCD.hdc, DC_BRUSH)
                SetDCBrushColor(lpnmCD.hdc, brushColor)

                SelectObject(lpnmCD.hdc, DC_PEN)
                SetDCPenColor(lpnmCD.hdc, penColor)

                SetBkMode(lpnmCD.hdc, 0)

                if drawFocused 
                    FrameRgn(lpnmCD.hdc, rcRgn, DC_PEN, rc.Width, rc.Height)

                RoundRect(lpnmCD.hdc, rc.left, rc.top, rc.right-1, rc.bottom-1, corner, corner)

                if IsSet(first) && first
                    first := 0

                SetWindowPos(this.hwnd, 0, 0, 0, 0, 0, 0x4043)

                return CDRF_NOTIFYPOSTPAINT
            }}
            
            return CDRF_DODEFAULT
        }
I have updated the code and added some new features. Let me know if there's any issues! :)
✨ Dark Theme for Everything
✨ Other Scripts


Return to “Scripts and Functions (v2)”

Who is online

Users browsing this forum: pastors, william_ahk and 27 guests