44 * @author Nikola Perovic
55 * @link https://github.com/nperovic/ColorButton.ahk
66 * @date 2024/04/28
7- * @version 1.0.0
7+ * @version 1.0.1
88 ***********************************************************************/
99
1010#Requires AutoHotkey v2.1-alpha.9
@@ -14,22 +14,20 @@ class RECT {
1414 left: i32, top: i32, right: i32, bottom: i32
1515}
1616
17- class NMHDR
18- {
19- hwndFrom: uptr
20- idFrom : uptr
21- code : i32
22- }
23-
24- class NMCUSTOMDRAWINFO
25- {
26- hdr : NMHDR
17+ class NMCUSTOMDRAWINFO {
18+ hdr : NMCUSTOMDRAWINFO.NMHDR
2719 dwDrawStage: u32
2820 hdc : uptr
2921 rc : RECT
3022 dwItemSpec : uptr
31- uItemState : u32
23+ uItemState : i32
3224 lItemlParam: iptr
25+
26+ class NMHDR {
27+ hwndFrom: uptr
28+ idFrom : uptr
29+ code : i32
30+ }
3331}
3432
3533/**
@@ -44,21 +42,20 @@ class _BtnColor extends Gui.Button {
4442
4543 /**
4644 * @param {Gui.Button} myBtn
47- * @param {integer} color
45+ * @param {integer} bkColor
4846 */
49- static SetBackColor(myBtn, color )
47+ static SetBackColor(myBtn, bkColor )
5048 {
51- static DC_BRUSH := 18
52- static DC_PEN := 19
49+ static IS_WIN11 := (VerCompare(A_OSVersion , " 10.0.22200" ) >= 0 )
5350 static WM_CTLCOLORBTN := 0x0135
5451 static NM_CUSTOMDRAW := - 12
5552 static WM_DESTROY := 0x0002
5653 static WS_EX_COMPOSITED := 0x02000000
5754 static WS_CLIPCHILDREN := 0x02000000
5855 static WS_CLIPSIBLINGS := 0x04000000
5956
60- clr := (IsNumber(color ) ? color : Number((! InStr (color , " 0x" ) ? " 0x" : "" ) color ))
61- hoverColor := BrightenColor(clr)
57+ clr := (IsNumber(bkColor ) ? bkColor : Number((! InStr (bkColor , " 0x" ) ? " 0x" : "" ) bkColor ))
58+ hoverColor := BrightenColor(clr, 10 )
6259 hbrush := CreateSolidBrush(ColorHex(myBtn.Gui .BackColor))
6360
6461 myBtn.Gui .Opt(" +E" WS_EX_COMPOSITED " +" WS_CLIPCHILDREN)
@@ -78,35 +75,32 @@ class _BtnColor extends Gui.Button {
7875
7976 myBtn.OnNotify(NM_CUSTOMDRAW, (gCtrl, lParam) {
8077 static CDDS_PREPAINT := 1
81- static BM_GETSTATE := 0x00F2
82- static BST_PUSHED := 0x0004
83- static BST_HOT := 0x0200
84- static BST_FOCUS := 0x0008
85-
78+ static CDIS_HOT := 0x0040
79+ static DC_BRUSH := 18
80+ static DC_PEN := 19
81+
8682 Critical (- 1 )
87-
88- /** @type {tagNMHDR } */
89- LPNMHDR := StructFromPtr(NMHDR , lParam)
83+
84+ /** @type {NMCUSTOMDRAWINFO } */
85+ lpnmCD := StructFromPtr(NMCUSTOMDRAWINFO , lParam)
9086
91- if !(LPNMHDR. code == NM_CUSTOMDRAW && LPNMHDR. hwndFrom == gCtrl.hwnd)
87+ if (lpnmCD.hdr. code != NM_CUSTOMDRAW || lpnmCD.hdr. hwndFrom != gCtrl.hwnd || lpnmCD.dwDrawStage != CDDS_PREPAINT )
9288 return
9389
94- /** @type {tagNMCUSTOMDRAWINFO} */
95- lpnmCD := StructFromPtr(NMCUSTOMDRAWINFO, lParam)
96-
97- if (lpnmCD.dwDrawStage = CDDS_PREPAINT) {
98-
99- btnState := SendMessage(BM_GETSTATE,,, gCtrl.hwnd)
100- brushColor := (btnState & BST_HOT && !(btnState & BST_PUSHED) ? hoverColor : clr)
101-
102- SetDCBrushColor(lpnmCD.hdc, RgbToBgr(brushColor))
103- SetDCPenColor(lpnmCD.hdc, RgbToBgr(brushColor))
104- SelectObject(lpnmCD.hdc, GetStockObject(DC_BRUSH))
105- SelectObject(lpnmCD.hdc, GetStockObject(DC_PEN))
106- SetBkMode(lpnmCD.hdc, 0)
107- RoundRect(lpnmCD.hdc, lpnmCD.rc.left + 3, lpnmCD.rc.top + 3, lpnmCD.rc.right - 3, lpnmCD.rc.bottom - 3, 6, 6)
108- return true
109- }
90+ brushColor := RgbToBgr(GetKeyState("LButton", "P") || !(lpnmCD.uItemState & CDIS_HOT) ? clr : hoverColor )
91+
92+ SetBkMode(lpnmCD.hdc, 0)
93+ SetDCBrushColor(lpnmCD.hdc, brushColor)
94+ SelectObject(lpnmCD.hdc, bru := GetStockObject(DC_BRUSH))
95+ SetDCPenColor(lpnmCD.hdc, brushColor)
96+ 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)
102+
103+ return true
110104 })
111105
112106 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}")))
@@ -123,6 +117,8 @@ class _BtnColor extends Gui.Button {
123117
124118 DeleteObject(hObject) => DllCall('Gdi32\DeleteObject', 'ptr', hObject, 'int')
125119
120+ FillRect(hDC, lprc, hbr) => DllCall("User32\FillRect", "ptr", hDC, "ptr", lprc, "ptr", hbr, "int")
121+
126122 IsColorDark(clr) =>
127123 ( (clr >> 16 & 0xFF) / 255 * 0.2126
128124 + (clr >> 8 & 0xFF) / 255 * 0.7152
0 commit comments