CtlColorStatic - individual colors for 'static' controls

Post your working scripts, libraries and tools
just me
Posts: 8699
Joined: 02 Oct 2013, 08:51
Location: Germany

CtlColorStatic - individual colors for 'static' controls

21 Jul 2014, 05:00

This is just an excerpt from CtlColors limited to be used with static (Text) controls and a few others and using a different approach for the background brush. It is aimed to keep things as simple, short. and fast as possible.
MSDN wrote: WM_CTLCOLORSTATIC (0x0138)

A static control, or an edit control that is read-only or disabled, sends the WM_CTLCOLORSTATIC message to its parent window when the control is about to be drawn. By responding to this message, the parent window can use the specified device context handle to set the text foreground and background colors of the static control.
...
You can set the text background color of a disabled edit control, but you cannot set the text foreground color. The system always uses COLOR_GRAYTEXT.
As you might notice when playing around with the function, check boxes and radio buttons are also sending this message (although not documented by Microsoft). So it can be used to set the background color for this controls, too. In this case, if ou specify a text color it will be used to draw the focus rect rather than the caption.
Usage
Notes
CtlColorStatic.ahk
Sample Script
User avatar
lmstearn
Posts: 565
Joined: 11 Aug 2016, 02:32
Google: +lmstearn
GitHub: lmstearn
Contact:

Re: CtlColorStatic - individual colors for 'static' controls

19 Mar 2021, 07:34

Thanks for posting. :)
Just a note reflecting perhaps on some inconsistencies in the setup over here (W10 20H2), that although all of the GDI functions work fine in the script, one actually returns a fail. Take SetBkColor, and its return in running the following code where the msgbox doesn't pop up:

Code: Select all

#NoEnv
SetBatchLines, -1
Keys := {C: "CapsLock", S: "ScrollLock", N: "NumLock"}
StateColor := {0: 0x5481E6, 1: 0x98CB4A} ; 0 = Off, 1 = On
Controls := {C: {}, S: {}, N: {}}
For Ctrl, Key In Keys
   Controls[Ctrl].State := GetKeyState(Key, "T")

gui, -caption +toolwindow +alwaysontop +lastfound
gui, color, 8b0fc6
gui, font, s10 w600, Arial Bold
Gui, Margin, 0, 0
winset, transcolor, 8b0fc6

gui, add, text, x0 y0 w60 h16 0x201 gClicked vC hwndHWND, C
gui, add, text, x0 y16 w60 h4 0x04 ; 0x04 = SS_BLACKRECT
Controls.C.Hwnd := HWND

; ======================================================================================================================
; Function:       CtlColorStatic
; Requires:       AHK 1.1
; Tested with:    AHK 1.1.15.02
; Tested on:      Win 8.1 (x64)
; Change history:
;     1.0.00.00/2014-07-19/just me     -  Initial release.
; ======================================================================================================================
CtlColorStatic(W, L := "", M := "") { ; W : wParam, L : lParam, M : uMsg
   Static Controls := {}, Init := OnMessage(0x0138, "CtlColorStatic"), CLR_INVALID := 16777215 ; 0xFFFFFFFF ; WM_CTLCOLORSTATIC = 0x0138
   If DllCall("User32.dll\IsWindow", "Ptr", W, "UInt") { ; W is the HWND of an existing control, it is a setup call ----
      Controls.Remove(W, "")
      If (L <> "") && ((B := ((L & 0xFF0000) >> 16) | (L & 0x00FF00) | ((L & 0x0000FF) << 16)) <> "")
         Controls[W] := {B: B, T: M <> "" ? ((M & 0xFF0000) >> 16) | (M & 0x00FF00) | ((M & 0x0000FF) << 16) : ""}
      Return DllCall("User32.dll\RedrawWindow", "Ptr", W, "Ptr", 0, "Ptr", 0, "UInt", 0x0405, "UInt")
   }
   If Controls.HasKey(L) { ; Presumably called by message handler ------------------------------------------------------
      If (Controls[L].T <> "")
         DllCall("Gdi32.dll\SetTextColor", "Ptr", W, "UInt", Controls[L].T)
      if (DllCall("Gdi32.dll\SetBkColor", "Ptr", W, "UInt", Controls[L].B) != CLR_INVALID)
	  msgbox No error

      DllCall("Gdi32.dll\SetDCBrushColor", "Ptr", W, "UInt", Controls[L].B)
      Return DllCall("Gdi32.dll\GetStockObject", "UInt", 18, "UPtr") ; DC_BRUSH = 18
   }
}
gui, add, text, x63 y0 w60 h16 0x201 gClicked vS hwndHWND, S
gui, add, text, x63 y16 w60 h4 0x04 ; 0x04 = SS_BLACKRECT
Controls.S.Hwnd := HWND

gui, add, text, x126 y0 w60 h16 0x201 gClicked vN hwndHWND, N
gui, add, text, x126 y16 w60 h4 0x04 ; 0x04 = SS_BLACKRECT
Controls.N.Hwnd := HWND

gui, show

For Each, Ctrl In Controls
   CtlColorStatic(Ctrl.Hwnd, StateColor[Ctrl.State], 0xFFFFFF)

return

guiclose:
guiescape:
exitapp

Clicked:
   If (A_GuiEvent <> "DoubleClick") && (Ctrl := Controls[A_GuiControl])
      CtlColorStatic(Ctrl.Hwnd, StateColor[Ctrl.State := !Ctrl.State], 0xFFFFFF)
return

GetStates:
   For Ctrl, Key In Keys
      Controls[Ctrl].State := GetKeyState(Key, "T")
Return

SetTextColor, SetBkMode
, and even GetBkColor all return success codes, so appears to be another GDI mystery.
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH
just me
Posts: 8699
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: CtlColorStatic - individual colors for 'static' controls

20 Mar 2021, 05:19

Code: Select all

CLR_INVALID = 0xFFFFFFFF
16777215    = 0x00FFFFFF (white)
User avatar
lmstearn
Posts: 565
Joined: 11 Aug 2016, 02:32
Google: +lmstearn
GitHub: lmstearn
Contact:

Re: CtlColorStatic - individual colors for 'static' controls

20 Mar 2021, 08:08

Sry :)
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH

Return to “Scripts and Functions”

Who is online

Users browsing this forum: No registered users and 27 guests