0

I've been trying to theme a button in a Windows API application using C++. I want to make the button label red at all times. Currently I get only a red label until I move the window, after that I get a button with a red label as wanted. Sorry I'm not very experienced with the native Windows API (previously win32 API)

The code I've tried follows. I create the button

GetClientRect(hWnd, &rect);
hButton = CreateWindowExW(
    0L, 
    L"BUTTON",
    L"Hello, World!!!", 
    WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_FLAT,
    rect.right / 2 - 100,
    rect.bottom / 2 - 25,
    200, 
    50, 
    hWnd, 
    NULL, 
    ((LPCREATESTRUCT)lParam)->hInstance,
    NULL);

Then to theme it I use the following code in the WM_PAINT procedure of the Window Proc

 case WM_PAINT:
    {
        // Use DrawThemeBackground

        RECT rc;
        PAINTSTRUCT ps;
        GetClientRect(hButton, &rc);

        HDC hdc = GetDC(hWnd);

        HTHEME theme = OpenThemeData(hWnd, L"button");

        if (theme)
        {
            // Setup a DrawThemeTextEx Options struct
            DTTOPTS opts = { 0 };
            opts.dwSize = sizeof(opts);
            opts.crText = RGB(255, 0, 0);
            opts.dwFlags = DTT_TEXTCOLOR | DTT_COMPOSITED;

            WCHAR caption[255];
            GetWindowText(hButton, caption, 255);

            DrawThemeTextEx(theme, hdc, BP_PUSHBUTTON, CBS_UNCHECKEDNORMAL,
                caption, -1, DT_CENTER | DT_VCENTER | DT_SINGLELINE,
                &rc, &opts);
            CloseThemeData(theme);

        }
        else
        {
            // Draw the control without using visual styles.
        }

        ReleaseDC(hWnd, hdc);

        break;
    }

I wanted to ask if I'm doing something wrong or missing on something. I'd really appreciate.

Chuck
  • 192
  • 2
  • 11
  • 1
    Do you need to call BeginPaint/EndPaint somewhere in that sequence within the WM_PAINT handler? – selbie Apr 23 '23 at 20:20
  • I've tried that but then I don't get any theming. – Chuck Apr 23 '23 at 20:22
  • 2
    You seem to be trying to render the button control from the parent window's `WM_PAINT` handler. That doesn't make much sense. – IInspectable Apr 23 '23 at 20:26
  • Can I ask where to render themed controls? It almost works this way. – Chuck Apr 23 '23 at 20:33
  • 2
    Either create an [owner-drawn control](https://learn.microsoft.com/en-us/windows/win32/controls/user-controls-intro#creating-owner-drawn-controls), or [subclass the control](https://learn.microsoft.com/en-us/windows/win32/controls/user-controls-intro#subclassing-the-window-class-of-an-existing-control), in case you need more control over its visual appearance. – IInspectable Apr 23 '23 at 21:00
  • 3
    [Custom draw](https://learn.microsoft.com/en-us/windows/win32/controls/custom-draw) is the easiest way to change the button's label color. – Jonathan Potter Apr 23 '23 at 21:01
  • I just wanted to learn how to paint and theme the button without having to subclass the control. – Chuck Apr 24 '23 at 09:05
  • If you do Owner-Drawn Controls, you can make it looks like you want. The subclass procedure can alter selected behaviors of the control by processing those messages that affect the selected behaviors. As far as I'm concerned, you need to subclass the control. – Jeaninez - MSFT May 05 '23 at 08:46

0 Answers0