I wanted to create some sort of a dark-mode button using Common Controls & Win32 API.
I wanted to use custom drawing to set my button's background & text color.
As for the background, it seems to work fine, but I can't figure out how to set the text color.
Here is what I did (in the window handler function):
LRESULT CALLBACK WindowHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HBRUSH defaultbrush = NULL;
static HBRUSH hotbrush = NULL;
static HBRUSH selectbrush = NULL;
switch (msg)
{
case WM_CREATE:
{
HWND button = CreateWindowA("Button", "Click Me", WS_VISIBLE | WS_CHILD,
10, 10, 80, 30, hwnd, (HMENU)1, NULL, NULL);
if (!button)
{
MessageBoxA(NULL, "Button Creation Failed!", "Error!", MB_ICONEXCLAMATION);
exit(EXIT_FAILURE);
}
break;
}
case WM_NOTIFY:
{
LPNMHDR some_item = (LPNMHDR)lParam;
if (some_item->idFrom == 1 && some_item->code == NM_CUSTOMDRAW)
{
LPNMCUSTOMDRAW item = (LPNMCUSTOMDRAW)some_item;
if (item->uItemState & CDIS_SELECTED)
{
//Select our color when the button is selected
if (selectbrush == NULL)
selectbrush = CreateSolidBrush(0x383838);
//Create pen for button border
HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));
//Select our brush into hDC
HGDIOBJ old_pen = SelectObject(item->hdc, pen);
HGDIOBJ old_brush = SelectObject(item->hdc, selectbrush);
Rectangle(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom);
//Clean up
SelectObject(item->hdc, old_pen);
SelectObject(item->hdc, old_brush);
DeleteObject(pen);
//Here is the problem:
DrawTextA(item->hdc, "Click Me", -1, &item->rc, DT_CENTER | DT_VCENTER);
return CDRF_SKIPDEFAULT;
}
else
{
if (item->uItemState & CDIS_HOT) //Our mouse is over the button
{
//Select our color when the mouse hovers our button
if (hotbrush == NULL)
hotbrush = CreateSolidBrush(0x474747);
HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));
HGDIOBJ old_pen = SelectObject(item->hdc, pen);
HGDIOBJ old_brush = SelectObject(item->hdc, hotbrush);
Rectangle(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom);
SelectObject(item->hdc, old_pen);
SelectObject(item->hdc, old_brush);
DeleteObject(pen);
//Here too:
DrawTextA(item->hdc, "Click Me", -1, &item->rc, DT_CENTER | DT_VCENTER);
return CDRF_SKIPDEFAULT;
}
//Select our color when our button is doing nothing
if (defaultbrush == NULL)
defaultbrush = CreateSolidBrush(0x383838);
HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));
HGDIOBJ old_pen = SelectObject(item->hdc, pen);
HGDIOBJ old_brush = SelectObject(item->hdc, defaultbrush);
Rectangle(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom);
SelectObject(item->hdc, old_pen);
SelectObject(item->hdc, old_brush);
DeleteObject(pen);
//And also here:
DrawTextA(item->hdc, "Click Me", -1, &item->rc, DT_CENTER | DT_VCENTER);
return CDRF_SKIPDEFAULT;
}
}
return CDRF_DODEFAULT;
break;
}
case WM_DESTROY:
DeleteObject(defaultbrush);
DeleteObject(selectbrush);
DeleteObject(hotbrush);
PostQuitMessage(0);
break;
}
return DefWindowProcA(hwnd, msg, wParam, lParam);
}
I tried following a different post I've found on Stack Overflow which is this one: How can I change the background color of a button WinAPI C++ But they only show how to set the background color, not the text color.
Can anyone please help me with that?
You just need to set the text color using the SetTextColor
function, somewhere before your call to DrawText()
:
//...
SetTextColor(item->hdc, RGB(0,255,0)); // For green text, but use any COLORREF value.
DrawTextA(item->hdc, "Click Me", -1, &item->rc, DT_CENTER | DT_VCENTER);
return CDRF_SKIPDEFAULT;
You may also need to set the background mode to TRANSPARENT
, in order to keep the color previously painted:
SetBkMode(item-hdc, TRANSPARENT);