如何更改按钮 WinAPI C++ 的背景颜色

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18745447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:11:04  来源:igfitidea点击:

How can I change the background color of a button WinAPI C++

c++winapibuttoncolorsbackground

提问by retsgorf297

I have searched this many times, but everything I find is MFC. I want it in C++ WinAPI. I know how to change the style of a button control, but I cannot find out how to make a button a different color. So, how can I change the background color of a WinAPI button control using C++? I don't want to do this with a resource file.

我已经搜索了很多次,但我找到的一切都是 MFC。我想要它在 C++ WinAPI 中。我知道如何更改按钮控件的样式,但我不知道如何使按钮具有不同的颜色。那么,如何使用 C++ 更改 WinAPI 按钮控件的背景颜色?我不想用资源文件来做这件事。

Thank you!

谢谢!

回答by FrogTheFrog

Instead of a link I'll just post a copy from my other post using custom-drawing, similar to alwayslearningnewstuffexample:

我将使用自定义绘图从我的其他帖子中发布副本,而不是链接,类似于alwayslearningnewstuff示例:

Nothing is selectedFirst button is selected and was pushedSecond button was pushed and the mouse is over it (notice the increse of brightness - cutom hilight)

未选择任何内容第一个按钮被选中并被按下第二个按钮被按下,鼠标在它上面(注意亮度的增加 - cutom hilight)

First picture shows when nothing is selected, second shows when first button is selected and was pushed and the last one shows when second button was pushed and the mouse is over it (notice the increase of brightness - cutom hilight). In order to do this, you must catch NM_CUSTOMDRAW message and paint button yourself. And this is how you do it. Also added gradient brush function and some comments.

第一张图显示未选择任何内容时,第二张图显示选择并按下第一个按钮时,最后一张显示按下第二个按钮时鼠标悬停在其上方(注意亮度的增加 - cutom hilight)。为此,您必须自己捕获 NM_CUSTOMDRAW 消息并绘制按钮。这就是你如何做到的。还添加了渐变刷功能和一些注释。

#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") 

#include <Windows.h>
#include <Commctrl.h>

#define IDC_EXIT_BUTTON 101
#define IDC_PUSHLIKE_BUTTON 102

HBRUSH CreateGradientBrush(COLORREF top, COLORREF bottom, LPNMCUSTOMDRAW item)
    {
        HBRUSH Brush = NULL;
        HDC hdcmem = CreateCompatibleDC(item->hdc);
        HBITMAP hbitmap = CreateCompatibleBitmap(item->hdc, item->rc.right-item->rc.left, item->rc.bottom-item->rc.top);
        SelectObject(hdcmem, hbitmap);

        int r1 = GetRValue(top), r2 = GetRValue(bottom), g1 = GetGValue(top), g2 = GetGValue(bottom), b1 = GetBValue(top), b2 = GetBValue(bottom);
        for(int i = 0; i < item->rc.bottom-item->rc.top; i++)
        { 
            RECT temp;
            int r,g,b;
            r = int(r1 + double(i * (r2-r1) / item->rc.bottom-item->rc.top));
            g = int(g1 + double(i * (g2-g1) / item->rc.bottom-item->rc.top));
            b = int(b1 + double(i * (b2-b1) / item->rc.bottom-item->rc.top));
            Brush = CreateSolidBrush(RGB(r, g, b));
            temp.left = 0;
            temp.top = i;
            temp.right = item->rc.right-item->rc.left;
            temp.bottom = i + 1; 
            FillRect(hdcmem, &temp, Brush);
            DeleteObject(Brush);
        }
        HBRUSH pattern = CreatePatternBrush(hbitmap);

        DeleteDC(hdcmem);
        DeleteObject(Brush);
        DeleteObject(hbitmap);

        return pattern;
    }

LRESULT CALLBACK MainWindow(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static HBRUSH defaultbrush = NULL;
    static HBRUSH hotbrush = NULL;
    static HBRUSH selectbrush = NULL;
    static HBRUSH push_uncheckedbrush = NULL;
    static HBRUSH push_checkedbrush = NULL;
    static HBRUSH push_hotbrush1 = NULL;
    static HBRUSH push_hotbrush2 = NULL;
    switch (msg)
    {
        case WM_CREATE:
            {
                HWND Exit_Button = CreateWindowEx(NULL, L"BUTTON", L"EXIT", 
                                                        WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 
                                                        50, 50, 100, 100, hwnd, (HMENU)IDC_EXIT_BUTTON, NULL, NULL);
                if(Exit_Button == NULL)
                    {
                        MessageBox(NULL, L"Button Creation Failed!", L"Error!", MB_ICONEXCLAMATION);
                        exit(EXIT_FAILURE);
                    }

                HWND Pushlike_Button = CreateWindowEx(NULL, L"BUTTON", L"PUSH ME!", 
                                                        WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX | BS_PUSHLIKE, 
                                                        200, 50, 100, 100, hwnd, (HMENU)IDC_PUSHLIKE_BUTTON, NULL, NULL);
                if(Pushlike_Button == NULL)
                    {
                        MessageBox(NULL, L"Button Creation Failed!", L"Error!", MB_ICONEXCLAMATION);
                        exit(EXIT_FAILURE);
                    }
            }
        break;
        case WM_COMMAND:
            {
                switch(LOWORD(wParam))
                    {
                        case IDC_EXIT_BUTTON:
                            {
                                SendMessage(hwnd, WM_CLOSE, 0, 0);
                            }
                        break;
                    }
            }
        break;
        case WM_NOTIFY:
        {
            LPNMHDR some_item = (LPNMHDR)lParam;

            if (some_item->idFrom == IDC_EXIT_BUTTON && 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 = CreateGradientBrush(RGB(180, 0, 0), RGB(255, 180, 0), item);

                    //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);

                    //If you want rounded button, then use this, otherwise use FillRect().
                    RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 5, 5);

                    //Clean up
                    SelectObject(item->hdc, old_pen);
                    SelectObject(item->hdc, old_brush);
                    DeleteObject(pen);

                    //Now, I don't want to do anything else myself (draw text) so I use this value for return:
                    return CDRF_DODEFAULT;
                    //Let's say I wanted to draw text and stuff, then I would have to do it before return with
                    //DrawText() or other function and 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 = CreateGradientBrush(RGB(255, 230, 0), RGB(245, 0, 0), item);

                        HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));

                        HGDIOBJ old_pen = SelectObject(item->hdc, pen);
                        HGDIOBJ old_brush = SelectObject(item->hdc, hotbrush);

                        RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 5, 5);

                        SelectObject(item->hdc, old_pen);
                        SelectObject(item->hdc, old_brush);
                        DeleteObject(pen);

                        return CDRF_DODEFAULT;
                    }

                    //Select our color when our button is doing nothing
                    if (defaultbrush == NULL)
                        defaultbrush = CreateGradientBrush(RGB(255, 180, 0), RGB(180, 0, 0), item);

                    HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));

                    HGDIOBJ old_pen = SelectObject(item->hdc, pen);
                    HGDIOBJ old_brush = SelectObject(item->hdc, defaultbrush);

                    RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 5, 5);

                    SelectObject(item->hdc, old_pen);
                    SelectObject(item->hdc, old_brush);
                    DeleteObject(pen);

                    return CDRF_DODEFAULT;
                }
            }
            else if (some_item->idFrom == IDC_PUSHLIKE_BUTTON && some_item->code == NM_CUSTOMDRAW)
            {
                LPNMCUSTOMDRAW item = (LPNMCUSTOMDRAW)some_item;

                if (IsDlgButtonChecked(hwnd, some_item->idFrom))
                {
                    if (item->uItemState & CDIS_HOT)
                    {

                        if (push_hotbrush1 == NULL)
                            push_hotbrush1 = CreateGradientBrush(RGB(0, 0, 245), RGB(0, 230, 255), item);

                        HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));

                        HGDIOBJ old_pen = SelectObject(item->hdc, pen);
                        HGDIOBJ old_brush = SelectObject(item->hdc, push_hotbrush1);

                        RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 10, 10);

                        SelectObject(item->hdc, old_pen);
                        SelectObject(item->hdc, old_brush);
                        DeleteObject(pen);

                        return CDRF_DODEFAULT;
                    }


                    if (push_checkedbrush == NULL)
                        push_checkedbrush = CreateGradientBrush(RGB(0, 0, 180), RGB(0, 222, 200), item);


                    HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));


                    HGDIOBJ old_pen = SelectObject(item->hdc, pen);
                    HGDIOBJ old_brush = SelectObject(item->hdc, push_checkedbrush);


                    RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 10, 10);


                    SelectObject(item->hdc, old_pen);
                    SelectObject(item->hdc, old_brush);
                    DeleteObject(pen);


                    return CDRF_DODEFAULT;
                }
                else
                {
                    if (item->uItemState & CDIS_HOT)
                    {
                        if (push_hotbrush2 == NULL)
                            push_hotbrush2 = CreateGradientBrush(RGB(255, 230, 0), RGB(245, 0, 0), item);

                        HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));

                        HGDIOBJ old_pen = SelectObject(item->hdc, pen);
                        HGDIOBJ old_brush = SelectObject(item->hdc, push_hotbrush2);

                        RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 10, 10);

                        SelectObject(item->hdc, old_pen);
                        SelectObject(item->hdc, old_brush);
                        DeleteObject(pen);

                        return CDRF_DODEFAULT;
                    }

                    if (push_uncheckedbrush == NULL)
                        push_uncheckedbrush = CreateGradientBrush(RGB(255, 180, 0), RGB(180, 0, 0), item);

                    HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));

                    HGDIOBJ old_pen = SelectObject(item->hdc, pen);
                    HGDIOBJ old_brush = SelectObject(item->hdc, defaultbrush);

                    RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 10, 10);

                    SelectObject(item->hdc, old_pen);
                    SelectObject(item->hdc, old_brush);
                    DeleteObject(pen);

                    return CDRF_DODEFAULT;
                }
            }
            return CDRF_DODEFAULT;
        }
        break;
        case WM_CTLCOLORBTN: //In order to make those edges invisble when we use RoundRect(),
            {                //we make the color of our button's background match window's background
                return (LRESULT)GetSysColorBrush(COLOR_WINDOW+1);
            }
        break;
        case WM_CLOSE:
            {
                DestroyWindow(hwnd);
                return 0;
            }
        break;
        case WM_DESTROY:
            {
                DeleteObject(defaultbrush);
                DeleteObject(selectbrush);
                DeleteObject(hotbrush);
                DeleteObject(push_checkedbrush);
                DeleteObject(push_hotbrush1);
                DeleteObject(push_hotbrush2);
                DeleteObject(push_uncheckedbrush);
                PostQuitMessage(0);
                return 0;
            }
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG msg;
    const wchar_t ClassName[] = L"Main_Window";

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = MainWindow;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = ClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, L"Window Registration Failed!", L"Error", MB_ICONEXCLAMATION | MB_OK);
        exit(EXIT_FAILURE);
    }

    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, ClassName, L"Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 368, 248, NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, L"Window Creation Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
        exit(EXIT_FAILURE);
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while(GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.message;
}

回答by AlwaysLearningNewStuff

I do not remember the link for the original code, but code bellow helped me in the past to solve the problem you currently face.

我不记得原始代码的链接,但下面的代码在过去帮助我解决了您目前面临的问题。

Notice that it doesn't have resource file, as you have requested, and is in plain Win32 API.

请注意,它没有您所要求的资源文件,并且是普通的 Win32 API。

Study it carefully, everything is commented by the original author.

仔细研究,一切都是原作者评论的。

Hopefully it will help you, as it helped me in the past.

希望它会帮助你,因为它在过去帮助了我。

If you have any questions, ask, I will try to answer them.

如果您有任何问题,请提问,我会尽力回答。

There are 4 ways, as far as I know, to change the color of the button:

据我所知,有 4 种方法可以更改按钮的颜色:

  1. Owner draw( obvious solution ).

  2. Custom draw( in my opinion the best solution ).

  3. Subclassingthe control ( I do not like it, but it is possible ).

  4. Use bitmapsas your buttons background.

  5. Handling WM_CTLCOLORBTN:

  1. 所有者绘制(明显的解决方案)。

  2. 自定义绘制(在我看来是最好的解决方案)。

  3. 子类化控件(我不喜欢它,但它是可能的)。

  4. 使用位图作为按钮背景。

  5. 处理WM_CTLCOLORBTN

From MSDN :

only owner-drawnbuttons respond to the parent window processing this message.

从 MSDN :

只有所有者绘制的按钮响应处理此消息的父窗口。

Emphasis is mine.If you plan to use this option read the Remarks sectioncarefully.

重点是我的。如果您打算使用此选项,请仔细阅读备注部分

Code bellow demonstrates cases 1, 2 and 4.

下面的代码演示了案例 1、2 和 4。

#pragma comment(linker, "/manifestdependency:\"type='win32' \
    name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
    processorArchitecture='*' \
    publicKeyToken='6595b64144ccf1df' language='*'\"")

#pragma comment(lib, "comctl32.lib")

#include <windows.h>
#include <commctrl.h>

ATOM RegisterWndClass(HINSTANCE hInst);

BOOL CreateMainWnd(HINSTANCE hInstance, int nCmdShow);

LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

HINSTANCE hInst;

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hInstPrev, LPWSTR lpszCmdLine, 
    int nCmdShow)
{
    INITCOMMONCONTROLSEX icex = {0};
    icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    icex.dwICC  = ICC_LISTVIEW_CLASSES | ICC_USEREX_CLASSES | ICC_BAR_CLASSES |
                  ICC_COOL_CLASSES | ICC_TAB_CLASSES | ICC_WIN95_CLASSES | 
                  ICC_PROGRESS_CLASS | ICC_PAGESCROLLER_CLASS;

    InitCommonControlsEx(&icex);

    MSG msg;

    hInst = hInstance;

    if (!RegisterWndClass(hInstance))
       return NULL;

    if (!CreateMainWnd(hInstance, nCmdShow))
       return NULL;

    while (GetMessage(&msg, NULL, NULL, NULL))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
};

ATOM RegisterWndClass(HINSTANCE hInstance)
{

    WNDCLASS wndClass = {0};
    wndClass.style = CS_DBLCLKS;
    wndClass.lpfnWndProc = MainWndProc;
    wndClass.hInstance = hInstance;
    wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndClass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
    wndClass.lpszMenuName = NULL;
    wndClass.lpszClassName = L"MainClass";
    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = 0;

    return RegisterClass(&wndClass);
 }

BOOL CreateMainWnd(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd = CreateWindow(L"MainClass", L"Buttons sample",
         WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
         GetSystemMetrics(SM_CXSCREEN) / 2 - 115,
         GetSystemMetrics(SM_CYSCREEN) / 2 - 50,
         230, 100, NULL, NULL, hInstance, NULL);

    if (!hWnd)
        return FALSE;

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    return TRUE;
}

HBITMAP hBitmap = NULL;

LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_CREATE:
        {
            // Owner draw button

            CreateWindow(L"BUTTON", L"", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | 
                BS_OWNERDRAW, 10, 10, 60, 30, hWnd, 
                (HMENU)10001, hInst, NULL);

            // Custom draw button

            CreateWindow(L"BUTTON", L"", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 80, 
                10, 60, 30, hWnd, (HMENU)10002, hInst, NULL);

            // Bitmap button

            HWND hBitmapButton = CreateWindow(L"BUTTON", L"", WS_CHILD | WS_VISIBLE 
                | BS_PUSHBUTTON | BS_BITMAP,
                150, 10, 60, 30, hWnd,
                (HMENU)10003, hInst, NULL);

            HDC hDC = GetDC(hWnd);

            HDC hMemDC = CreateCompatibleDC(hDC);

            hBitmap = CreateCompatibleBitmap(hDC, 55, 25);

            SelectObject(hMemDC, hBitmap);

            SetDCBrushColor(hMemDC, RGB(0, 0, 255));

            RECT r = {0};
            r.left = 0;
            r.right = 55;
            r.top = 0;
            r.bottom = 25;

            FillRect(hMemDC, &r, (HBRUSH)GetStockObject(DC_BRUSH));

            DeleteDC(hMemDC);
            ReleaseDC(hWnd, hDC);

            SendMessage(hBitmapButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, 
                (LPARAM)hBitmap);

            return 0;
        }

    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case 10001:
            MessageBox(hWnd, L"Owner draw button clicked", L"Message", NULL);
            return 0;
        case 10002:
            MessageBox(hWnd, L"Custom draw button clicked", L"Message", NULL);
            return 0;
        case 10003:
            MessageBox(hWnd, L"Bitmap button clicked", L"Message", NULL);
            return 0;
        }
        break;

    // Owner draw button

    case WM_DRAWITEM:
        if (wParam == 10001)
        {
            LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam;

            SetDCBrushColor(lpDIS -> hDC, RGB(255, 0, 0));

            SelectObject(lpDIS -> hDC, GetStockObject(DC_BRUSH));

            RoundRect(lpDIS -> hDC, lpDIS -> rcItem.left, lpDIS -> rcItem.top,
                lpDIS -> rcItem.right, lpDIS -> rcItem.bottom, 5, 5);

            return TRUE;
        }
        break;

    // Custom draw button

    case WM_NOTIFY:
        switch (((LPNMHDR)lParam) -> code)
        {
        case NM_CUSTOMDRAW:
            if (((LPNMHDR)lParam) -> idFrom == 10002)
            {
                LPNMCUSTOMDRAW lpnmCD = (LPNMCUSTOMDRAW)lParam;

                switch (lpnmCD -> dwDrawStage)
                {
                case CDDS_PREPAINT:

                    SetDCBrushColor(lpnmCD -> hdc, RGB(0, 255, 0));
                    SetDCPenColor(lpnmCD -> hdc, RGB(0, 255, 0));
                    SelectObject(lpnmCD -> hdc, GetStockObject(DC_BRUSH));
                    SelectObject(lpnmCD -> hdc, GetStockObject(DC_PEN));

                    RoundRect(lpnmCD -> hdc, lpnmCD -> rc.left + 3, 
                        lpnmCD -> rc.top + 3, 
                        lpnmCD -> rc.right - 3, 
                        lpnmCD -> rc.bottom - 3, 5, 5);

                    return TRUE;
                }
            }
            break;
        }
        break;

    case WM_DESTROY:
        if (hBitmap != NULL)
            DeleteObject((HBITMAP)hBitmap);
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

回答by Jo?o Marcelo Brito

You can edit a button(which has the flag BS_OWNERDRAW) in the message WM_DRAWITEM on the DialogProc(MSDN About WM_DRAWITEM), heres a simple example of how to draw a simple button:

您可以在 DialogProc(MSDN About WM_DRAWITEM)消息 WM_DRAWITEM 中编辑按钮(具有标志 BS_OWNERDRAW),这是如何绘制简单按钮的简单示例:

LPDRAWITEMSTRUCT Item;
    Item = (LPDRAWITEMSTRUCT)lParam;
    SelectObject(Item->hDC, CreateFont(16, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial Black"));
    FillRect(Item->hDC, &Item->rcItem, CreateSolidBrush(0));
    SelectObject(Item->hDC, CreateSolidBrush(0));
    if (Item->itemState & ODS_SELECTED)
    {
        SetTextColor(Item->hDC, 0);
        SelectObject(Item->hDC, CreateSolidBrush(0xFF00));
        SelectObject(Item->hDC, CreatePen(PS_SOLID, 2, 0xFF00));
    }
    else
    {
        SetTextColor(Item->hDC, 0x00FF00);  
        SelectObject(Item->hDC, CreatePen(PS_SOLID, 2, 0x00FF00));

    }
    SetBkMode(Item->hDC, TRANSPARENT);
    RoundRect(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, 20, 20);
    int len;
    len = GetWindowTextLength(Item->hwndItem);
    LPSTR lpBuff;
    lpBuff = new char[len+1];
    GetWindowTextA(Item->hwndItem, lpBuff, len+1);
    DrawTextA(Item->hDC, lpBuff, len, &Item->rcItem, DT_CENTER);

回答by Igor Tandetnik

You need an owner-drawn buttonfor that. For some reason, unlike other controls, regular buttons don't react to changes made in WM_CTLCOLORBTNmessage handler.

为此,您需要一个所有者绘制的按钮。出于某种原因,与其他控件不同,常规按钮不会对WM_CTLCOLORBTN消息处理程序中所做的更改做出反应。