There is no simple method to change the background colour of check boxes. The reason is that MFC check boxes are system controls which do not provide options to change the background colour for the arrow area and that area is not transparent.
The only option to do this is deriving a
CButton
class that uses owner drawing. There you can draw an unchecked box using system functions. For checked boxes fill then the background and draw the arrow manually.
This can be done for classic check boxes using
CDC::DrawFrameControl
, filling the background with
CDC::FillSolidRect
(use
InflateRect(-2, -2)
with the check box size) and drawing the arrow.
But applications do not use the classic style nowadays. Then you have to use
DrawThemeBackground
, fill the background using
CDC::GradientFill
, and draw the arrow shaded too. But that will not look exactly like the system drawn check boxes.
int nBkClr = pDC->GetBkColor();
#if 1
pDC->DrawFrameControl(rcBox, DFC_BUTTON, DFCS_BUTTONCHECK);
#else
DrawThemeBackground(m_hTheme,
lpDrawItemStruct->hDC,
BP_CHECKBOX, nThemedState,
&rcBox, NULL);
#endif
CRect rcBk(rcBox);
rcBk.InflateRect(-2, -2);
#if 1
pDC->FillSolidRect(&rcBk, clrBk);
#else
static GRADIENT_TRIANGLE TriG[2] = { { 0, 1, 3 }, { 0, 3, 2} };
#define GetR(rgb) ((int)((rgb) & 0xFF)) // extract R/G/B values fro COLORREF
#define GetG(rgb) ((int)(((rgb) >> 8) & 0xFF))
#define GetB(rgb) ((int)(((rgb) >> 16) & 0xFF))
#define Darken(a) ((a) - ((a) >> 1)) // make R/G/B part darker
#define Brighten(a) ((a) + ((0xFF - (a)) >> 1)) // make R/G/B part brighter
#define Col16(c) ((COLOR16)((c) << 8)) // convert R/G/B part to COLOR16 value
#define Bright16(a) (Col16(Brighten(a)))
TRIVERTEX TriV[4] = {
{rc.left, rc.top, Col16(GetR(clr)), Col16(GetG(clr)), Col16(GetB(clr)), 0},
{rc.right, rc.top, Bright16(GetR(clr)), Bright16(GetG(clr)), Bright16(GetB(clr)), 0},
{rc.left, rc.bottom, Bright16(GetR(clr)), Bright16(GetG(clr)), Bright16(GetB(clr)), 0},
{rc.right, rc.bottom, 0xff00, 0xff00, 0xff00, 0}
};
pDC->GradientFill(TriV, 4, TriG, 2, GRADIENT_FILL_TRIANGLE);
#endif
CRect rcArr(rcBox.left + 3,
rcBox.top + 5,
rcBox.left + 4,
rcBox.top + 8);
for (int i = 0; i < 7; i++)
{
pDC->FillSolidRect(&rcArr, clrArr);
rcArr.OffsetRect(1, (i < 2) ? 1 : -1);
}
pDC->SetBkColor(nBkClr);