May 302008

Windows provides us with a message called WM_CTRLCOLORDLG which helps us in changing background color of a dialog. If we are handling this message then we need to return brush which is used for drawing background color. This means we can provide custom brushes. Don’t forget that we’ve got maintain such custom brushes since these are used even after the call returns. So be careful when destroying these objects.

A quick way to get a brush is get a system cached one by called GetSysColorBrush. Such brushes are not required to be freed. Use system colors such as COLOR_WINDOW, COLOR_3DFACE etc for creating such brushes.

Here is an e.g. on how to do this…

LRESULT CSomeDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
    switch( message )
       // Note that since we are using a system cache brush it's not required to
       // delete this object, but for custom brushes we've got to free them.
       return (LRESULT)GetSysColorBrush( COLOR_HOTLIGHT );
    return CDialog::WindowProc(message, wParam, lParam);

Note that all other ctlcolor messages are send to the owner window of a control except for WM_CTLCOLORDLG which instead is send to the dialog itself. So WM_CTLCOLOREDIT will be send to the parent window of the edit control.

Now as a homework for you try changing background of an edit control. As a hint just change WM_CTLCOLORDLG to WM_CTLCOLOREDIT. Call SetBkColor using dc handle stored in wParam to change background color. Same way for foreground color. Note that for readonly edit controls we get WM_CTLCOLORSTATIC message.

Another option in MFC is to add a message handler for WM_CTLCOLOR (ON_WM_CTLCOLOR), nCtlCode will the type of ctl code given for e.g. CTLCOLOR_DLG for a dialog, CTLCOLOR_EDIT for an edit control.

Have fun changing background colors but keep in mind needs of users too.