tags:

views:

551

answers:

3

I am stuck with WIN32 and C++ ( no .NET or anything managed )

+1  A: 

I think WM_CTLCOLORSTATIC notification might be what you're after.

Alex Deem
A: 

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.

tyranid
this is not working for a group box. It is however working for a label (static control)The documentation saysA 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. So not sure if a group box qualifies.Whats interesting is though that if I set a breakpoint it does go off so I guess the message is being sent for said control ( group box ) for some reason though the color is not changing
Rahul
Really iy isn't working? Works fine for my little test app I have running. It can be abit weird, if the brush isn't correct it wont do anything for example.
tyranid
could Vista make any diff
Rahul
Well my machine is Windows 7 so I doubt it. What I reacon is happening is static fields have some weird ID settings, pretty much everything is set to -1, you can end up then setting the color for something totally unrelated. Try right clicking the dialog box entry in the resource editor and choosing Resource Symbols. Add a new distinct entry to the list (say IDC_MYGROUPBOX) with the suggested ID, go to the dialog editor and change the ID in the properties to that new IDm then use that in the code instead to do the color and see if it makes a difference.
tyranid
+1  A: 

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.

Chris Becke
so for a group box which WM_CTLCORxxx am I looking for All I see in my winuser.h areWM_CTLCOLORMSGBOX WM_CTLCOLOREDIT WM_CTLCOLORLISTBOX WM_CTLCOLORBTN WM_CTLCOLORDLG WM_CTLCOLORSCROLLBAR WM_CTLCOLORSTATIC
Rahul
Your problem is - they dont seem to have added a new CTLCOLOR message. Which means your options are :- owner-draw the group box - a pita. Or use a text-less group box, with a regular static text above it. Or watch the window with Spy++ to see if there is a new as-yet-undocumented message it might be sending.
Chris Becke
so when you can do this by setting the fore colour in .NET , your guess is that under the covers this results in an owner drawn group box?
Rahul
Spy++ would be the best way to check that.
Chris Becke