45. How do I change the background colour of an edit field on a dialog?
The following code will change the colour of a
single edit field, with the ID value IDC_EDIT1 to a dark gray. We do this by
returning an appropriately coloured brush from the WM_CTLCOLOR handler, and at
the same time setting the background colour of any contained text to also be
dark gray.
 |
|
So, let's start by defining our colour. This
is done as a constant COLORREF value (note the double R in that type name)
:
const COLORREF crefDarkGray = (RGB(128,128,128));
|
 |
|
In the class header, we define some
variables for creating and holding our brush :
LOGBRUSH m_DGBrushStruct;
HBRUSH m_DGBrush;
|
 |
|
In the InitDialog handler, we create the
brush :
m_DGBrushStruct.lbStyle = BS_SOLID;
m_DGBrushStruct.lbColor = crefDarkGray;
m_DGBrushStruct.lbHatch = 0;
m_DGBrush = ::CreateBrushIndirect (&m_DGBrushStruct);
|
 |
|
Finally, we create a handler for the
WM_CTLCOLOR message, and put some code in it to set our colours up as
required :
HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd*
pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
switch (nCtlColor)
{
case CTLCOLOR_EDIT:
if (pWnd->GetDlgCtrlID () == IDC_EDIT1)
{
pDC->SetBkColor (crefDarkGray);
return m_DGBrush;
}
break;
default:
break;
}
return hbr;
}
There's a couple of interesting things
about that code. Note the use of GetDlgCtrlID ? We can't compare the pWnd
returned against a pWnd for the edit control, because OnCtlColor returns a
temporary pointer, and comparisons against MFC temporary pointers won't
work. Secondly, as I stated above, it only changes the background colour
for the one specific edit control. If you want to change all edit
controls, simply remove the IF statement. Note
that you delete brush handles using the DeleteObject API, not CloseHandle. |
 |
|
As an intellectual exercise, what if we want
a disabled edit control to paint in the normal colour for an enabled
window ? This breaks normal UI usage of course, so I'm not suggesting you
do it, but it presents an interesting problem. Here the technique is
similar, but we have to know a small wrinkle : disabled edit boxes are
treated like statics. Look at the following code, which is extracted from
another OnCtlColor handler :
HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd*
pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
switch (nCtlColor)
{
case CTLCOLOR_STATIC:
if (pWnd->GetDlgCtrlID () == IDC_EDIT1)
{
hbr = GetSysColorBrush (COLOR_WINDOW);
pDC->SetBkColor (GetSysColor(COLOR_WINDOW));
return (hbr);
}
break;
That code will paint the edit box and the
background of any contained text in the normal colour for a window
background, but the text remains gray so as to give feedback to the user
that the edit field is indeed disabled. Plus it will react correctly if
the windows colours are changed at runtime.
Satisfied Jerry ? <g>.
|