I am stuck with WIN32 ( no .NET or anything managed )
WM_CTLCOLORSTATIC was the correct way to control the color of the group box title.
However, it no longer works: If your application uses a manifest to include the version 6 comctl library, the Groupbox control no longer sends the WM_CTLCOLORSTATIC
to its parent to get a brush. If your dialog controls look ugly, square and grey - like the windows 95 controls, then you don't have xp styles enabled and you can control the color of group boxes. But thats a terrible sacrifice to make! :P
Next, most of the standard controls send WM_CTLCOLORxxx
messages to their parent (the dialog) to control their painting. The only way to identify the controls is to look up their control IDs - which is why assigning controls a identifier that indicates that that control needs a specific color or font is a good idea. i.e. Don't use IDC_STATIC
for controls that need red text. Set them to IDC_DRAWRED
or some made up id.
Dont use GetDlgItem(hwndDlg,IDC_ID) == hwndCtl
to test if the WM_CTLCOLOR
message is for the correct control: GetDlgItem will simply return the handle of the first control on the dialog with the specific Id, which means only one control will be painted.
case WM_CTLCOLORSTATIC:
if(GetWindowLong( (HWND)lParam, GWL_ID) == IDC_RED)
return MakeControlRed( (HDC)wParam );
You always* need to return a HBRUSH from a WM_CTLCOLORxxx message - even if you really just want to 'tamper' with the HDC being passed in. If you don't return a valid brush from your dialog proc then the dialogs window procedure will think you didn't handle the message at all and pass it on to DefWindowProc - which will reset any changes to the HDC you made. Instead of creating brushes, the system has a cache of brushes on standby to draw standard ui elements: GetSysColorBrush
Of course, you DON'T always need to return an HBRUSH. IF you have the xp theme style enabled in your app, you are sometimes allowed to return null :- because xp theme dialogs have differently colored backgrounds (especially on tab controls) returning a syscolor brush would result in ugly grey boxes on a lighter background :- in those specific cases the dialog manager will allow you to return null and NOT reset your changes in the DC.
Well you set the font using the normal way of setting control fonts. Send a WM_SETFONT message in your window initialisation using a HFONT you created with CreateFont. e.g.
SendDlgItemMessage(hDlg, IDC_STATIC, WM_SETFONT, (WPARAM)hFont, TRUE);
Then as pointed out you need to use the WM_CTLCOLORSTATIC notification to set the actual color.
case WM_CTLCOLORSTATIC: if(GetDlgItem(hDlg, IDC_STATIC) == (HWND)lParam) { HDC hDC = (HDC)wParam;
SetBkColor(hDC, GetSysColor(COLOR_BTNFACE)); SetTextColor(hDC, RGB(0, 0xFF, 0)); SetBkMode(hDC, TRANSPARENT);
return (INT_PTR)CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
} break;
Although you really should only create the solid brush once and delete it when the dialog goes away because you will end up with a leak.
I think WM_CTLCOLORSTATIC notification might be what you're after.