3
3
* @file ColorButton.ahk
4
4
* @author Nikola Perovic
5
5
* @link https://github.com/nperovic/ColorButton.ahk
6
- * @date 2024/04/28
7
- * @version 1.0.1
6
+ * @date 2024/04/29
7
+ * @version 1.1.0
8
8
***********************************************************************/
9
9
10
10
#Requires AutoHotkey v2.1-alpha.9
@@ -37,14 +37,19 @@ class NMCUSTOMDRAWINFO {
37
37
* btn := myGui.AddButton(, "SUPREME")
38
38
* btn.SetBackColor(0xaa2031)
39
39
*/
40
- class _BtnColor extends Gui .Button {
40
+ class _BtnColor extends Gui .Button
41
+ {
41
42
static __New() => super.Prototype.SetBackColor := ObjBindMethod(this, " SetBackColor" )
42
43
43
44
/**
44
- * @param {Gui.Button} myBtn
45
- * @param {integer} bkColor
45
+ * @param {Gui.Button} myBtn omitted.
46
+ * @param {integer} btnBgColor Button's background color.
47
+ * @param {integer} [colorBehindBtn] The color of the button's surrounding area. If omitted, if will be the same as `myGui.BackColor`.
48
+ * @param {integer} [roundedCorner] Specifies the rounded corner preference for the button. If omitted, :
49
+ * > For Windows 11: Enabled. (value: 9)
50
+ * > For Windows 10: Disabled.
46
51
*/
47
- static SetBackColor(myBtn, bkColor )
52
+ static SetBackColor(myBtn, btnBgColor, colorBehindBtn?, roundedCorner? )
48
53
{
49
54
static IS_WIN11 := (VerCompare(A_OSVersion , " 10.0.22200" ) >= 0 )
50
55
static WM_CTLCOLORBTN := 0x0135
@@ -54,57 +59,64 @@ class _BtnColor extends Gui.Button {
54
59
static WS_CLIPCHILDREN := 0x02000000
55
60
static WS_CLIPSIBLINGS := 0x04000000
56
61
57
- clr := (IsNumber(bkColor ) ? bkColor : Number((! InStr (bkColor , " 0x" ) ? " 0x" : "" ) bkColor ))
62
+ clr := (IsNumber(btnBgColor ) ? btnBgColor : Number((! InStr (btnBgColor , " 0x" ) ? " 0x" : "" ) btnBgColor ))
58
63
hoverColor := BrightenColor(clr, 10 )
59
- hbrush := CreateSolidBrush(ColorHex(myBtn.Gui .BackColor))
64
+ btnBkColr := ColorHex(colorBehindBtn ?? myBtn.Gui .BackColor)
65
+ hbrush := CreateSolidBrush(btnBkColr)
60
66
61
- myBtn.Gui .Opt(" +E" WS_EX_COMPOSITED " + " WS_CLIPCHILDREN )
67
+ myBtn.Gui .Opt(" +E" WS_EX_COMPOSITED )
62
68
myBtn.Gui .OnEvent(" Close" , (* ) => (DeleteObject(hbrush), unset))
63
69
64
70
myBtn.Opt(" +" WS_CLIPSIBLINGS)
65
71
SetWindowTheme(myBtn.hwnd, IsColorDark(clr) ? " DarkMode_Explorer" : " Explorer" )
66
72
myBtn.Redraw()
67
73
68
74
myBtn.Gui .OnMessage (WM_CTLCOLORBTN, (GuiObj, wParam, * ) {
69
- Critical (- 1 )
70
- SelectObject(wParam, hbrush)
71
75
SetBkMode(wParam, 0 )
72
- SetBkColor(wParam, ColorHex(GuiObj.BackColor))
76
+ SelectObject(wParam, hbrush)
77
+ SetBkColor(wParam, btnBkColr)
73
78
return hbrush
74
- })
79
+ }, - 1 )
75
80
76
81
myBtn.OnNotify(NM_CUSTOMDRAW, (gCtrl, lParam) {
77
82
static CDDS_PREPAINT := 1
83
+ static CDDS_PREERASE := 0x3
78
84
static CDIS_HOT := 0x0040
79
85
static DC_BRUSH := 18
80
86
static DC_PEN := 19
81
87
82
- Critical (- 1 )
83
-
84
88
/** @type {NMCUSTOMDRAWINFO} */
85
89
lpnmCD := StructFromPtr(NMCUSTOMDRAWINFO, lParam)
86
90
87
- if (lpnmCD.hdr.code != NM_CUSTOMDRAW || lpnmCD.hdr.hwndFrom != gCtrl.hwnd || lpnmCD.dwDrawStage != CDDS_PREPAINT)
91
+ if (lpnmCD.hdr.code != NM_CUSTOMDRAW || lpnmCD.hdr.hwndFrom != gCtrl.hwnd || ( lpnmCD.dwDrawStage != CDDS_PREPAINT) )
88
92
return
89
93
94
+ Critical()
95
+
90
96
brushColor := RgbToBgr(GetKeyState("LButton", "P") || !(lpnmCD.uItemState & CDIS_HOT) ? clr : hoverColor )
91
97
98
+ if (IS_WIN11 || IsSet(roundedCorner)) {
99
+ rcRgn := CreateRoundRectRgn(lpnmCD.rc.left, lpnmCD.rc.top, lpnmCD.rc.right, lpnmCD.rc.bottom, roundedCorner ?? 9, roundedCorner ?? 9)
100
+ SetWindowRgn(lpnmCD.hdr.hwndFrom, rcRgn, 0)
101
+ }
102
+
92
103
SetBkMode(lpnmCD.hdc, 0)
93
104
SetDCBrushColor(lpnmCD.hdc, brushColor)
94
- SelectObject(lpnmCD.hdc, bru := GetStockObject(DC_BRUSH))
95
105
SetDCPenColor(lpnmCD.hdc, brushColor)
106
+ SelectObject(lpnmCD.hdc, bru := GetStockObject(DC_BRUSH))
96
107
SelectObject(lpnmCD.hdc, GetStockObject(DC_PEN))
97
-
98
- if IS_WIN11
99
- RoundRect(lpnmCD.hdc, lpnmCD.rc.left, lpnmCD.rc.top, lpnmCD.rc.right, lpnmCD.rc.bottom, 8, 8)
100
- else
101
- FillRect(lpnmCD.hdc, lpnmCD.rc, bru)
108
+ FillRect(lpnmCD.hdc, lpnmCD.rc, bru)
109
+
110
+ if IsSet(rcRgn)
111
+ DeleteObject(rcRgn)
102
112
103
113
return true
104
114
})
105
115
106
116
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}")))
107
117
118
+ CreateRoundRectRgn(nLeftRect, nTopRect, nRightRect, nBottomRect, nWidthEllipse, nHeightEllipse) => DllCall('Gdi32\CreateRoundRectRgn', 'int', nLeftRect, 'int', nTopRect, 'int', nRightRect, 'int', nBottomRect, 'int', nWidthEllipse, 'int', nHeightEllipse, 'ptr')
119
+
108
120
CreateSolidBrush(crColor) => DllCall('Gdi32\CreateSolidBrush', 'uint', crColor, 'ptr')
109
121
110
122
ColorHex(clr) => Number((!InStr(clr, "0x") ? "0x" : "") clr)
@@ -115,6 +127,8 @@ class _BtnColor extends Gui.Button {
115
127
116
128
SetDCBrushColor(hdc, crColor) => DllCall('Gdi32\SetDCBrushColor', 'ptr', hdc, 'uint', crColor, 'uint')
117
129
130
+ SetWindowRgn(hWnd, hRgn, bRedraw) => DllCall("User32\SetWindowRgn", "ptr", hWnd, "ptr", hRgn, "int", bRedraw, "int")
131
+
118
132
DeleteObject(hObject) => DllCall('Gdi32\DeleteObject', 'ptr', hObject, 'int')
119
133
120
134
FillRect(hDC, lprc, hbr) => DllCall("User32\FillRect", "ptr", hDC, "ptr", lprc, "ptr", hbr, "int")
0 commit comments