1

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?

1 Answer 1

1

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); 
Sign up to request clarification or add additional context in comments.

5 Comments

It seems about right, except the text isn't centered vertically to the button. Is there any way to do that?
Also, is there any way to set the font of the drawn text?
@aviad1 (1) Try adding | DT_SINGLELINE in the DrawText() call. (2) Yes - Use SelectFont() - but be sure to save the old font and replace it afterwards, as you have correctly done with the pen and brush.
@aviad1 You may also like to save (and restore) the text color and B/G mode, using GetTextColor() and GetBkMode(). Or, better yet, use SaveDC() and RestoreDC() to do it all for you!
Thanks! This is very helpful

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.