Reputation: 9662
How Do I Set the Background Color of buttons including a Checkbox button?
I struggled to find the answer to this today - thinking it should be simple to answer this, but the information I stumbled on was less than helpful, so at the risk of duplicating stuff that's out there but I couldn't find, I'll make this quick'n'dirty how-to...
Upvotes: 0
Views: 2527
Reputation: 9662
All 'Button' class windows send WM_CTLCOLORSTATIC
to their parent window, which can then call ::SetBkColor((HDC)wParam, rgbBkColor)
, and return a brush for that color.
If this is all using system colors, then the brush handle doesn't need to be managed, you can simply ask for the ::GetSysColor(sysIndex)
, and return the ::GetSysColorBrush(sysIndex)
for the returned brush.
If you're using a custom color, then you'll need to create your own brush and manage the handle for that.
I needed this code for a Message Box replacement, which has the upper part using a white background, and the lower part using a gray background, per the Windows standard message box. So my static control (icon) needed to be white, while my other buttons (including a "Don't ask again" checkbox) needed to have a gray background (checkboxes normally have a white background).
So, I handle WM_ERASEBKGND to paint the two portions of the background correctly, and then I handle WM_CLTLCOLORSTATIC to ensure that all buttons are properly "transparent" for the background that they appear on. In my case, the I used a "Static" control for the icon, which draws its background in gray, and a couple of push-buttons plus a checkbox button - which a checkbox button always paints its background in white, so both required a fix.
My example is using MFC, but hopefully you can translate that trivially enough for your purposes:
// add to the message map:
ON_MESSAGE(WM_CTLCOLORSTATIC, OnCtlColorStatic)
// create the implementation:
LRESULT CRTFMessageBox::OnCtlColorStatic(WPARAM wParam, LPARAM lParam)
{
// buttons and static controls (icon) send WM_CTLCOLORSTATIC, so we can force them to use the correct background color here...
const HDC hdc = (HDC)wParam;
const int idc = ::GetDlgCtrlID((HWND)lParam);
// choose a system color or brush based on if this is icon (static) or another control (a button)
const int idx = idc == IDC_STATIC ? COLOR_WINDOW : COLOR_3DFACE;
// select system color
::SetBkColor(hdc, GetSysColor(idx));
// return system brush (which we don't need to delete!)
return (LRESULT)GetSysColorBrush(idx);
}
Upvotes: 3