Как изменить цвет кнопки winapi

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 ...

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

Nothing is selected
First button is selected and was pushed
Second button was pushed and the mouse is over it (notice the increse of brightness - 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.

#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;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "work_project.h"
 
extern HINSTANCE hInst;
extern COLORREF clrs[];
 
 
INT_PTR CALLBACK settings_proc (HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
{
    int wmid, wmevent;
    char buf[ 8 ];
    const int items = 12;
    HWND hcmbox, hstatic1, hstatic2;
    HWND clr_butns[ 12 ];
    HDC hdc;
    int IDS_BTNS[] = {
        ID_CLRBTN1, ID_CLRBTN2, ID_CLRBTN3,
        ID_CLRBTN4, ID_CLRBTN5, ID_CLRBTN6,
        ID_CLRBTN7, ID_CLRBTN8, ID_CLRBTN9,
        ID_CLRBTN10, ID_CLRBTN11, ID_CLRBTN12
    };
 
    switch (msg) {
        
    case WM_INITDIALOG:
        {
            int i = 2;
            int x, y, sx = 45, sy = 45, cnt = 0;
            
            /* create COMBOBOX window */
            hcmbox = CreateWindowEx(WS_EX_CLIENTEDGE,"COMBOBOX", NULL, 
                CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL| WS_VISIBLE | WS_CHILD | SS_LEFT,
                170, 35, 100, 200, hdlg, (HMENU)IDD_COMBO_LST,
                hInst, NULL);
 
            /* set values in COMBOBOX window */
            for (; i <= items; ++i) {
                memset(buf, 0, 8);
                itoa(i, buf, 10);
                SendMessage(hcmbox, CB_ADDSTRING, 0, (LPARAM)buf);
            }
            SendMessage ( hcmbox, CB_SETCURSEL, 2, 0);
            
            /* create STATIC frame window. just for beauty */
            hstatic1 = CreateWindowEx(WS_EX_CLIENTEDGE,"STATIC", NULL, 
                WS_VISIBLE | WS_CHILD | SS_ETCHEDFRAME,
                5, 15, 305, 70, hdlg, 0, hInst, NULL);
            
            x = 20;
            y = 135;
 
            /* create button windows for change color */
            for (i = 0; i < items; ++i) {
 
                clr_butns[ i ] = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", NULL,
                    BS_OWNERDRAW | WS_CHILD | WS_VISIBLE, x, y, sx, sy, hdlg, 
                    (HMENU)IDS_BTNS[ i ], hInst, NULL);
 
                x += sx + 5;
                ++cnt;
 
                if (cnt == 4) {
                    cnt = 0;
                    x = 20;
                    y += sx + 5;
                }               
            }
 
            /* create STATIC frame window. just for beauty */
            hstatic2 = CreateWindowEx(WS_EX_CLIENTEDGE,"STATIC", NULL, 
                WS_VISIBLE | WS_CHILD | SS_ETCHEDFRAME,
                5, 105, 305, 200, hdlg, 0, hInst, NULL);
            
            return (INT_PTR) TRUE;
            break;
        }
    case WM_CTLCOLORBTN:
        {
            int i;
            HBRUSH hbrush, hbrus_old;
            HDC hdc;
 
            /* set background mode for buttons */
            for (i = 0; i < items; ++i) {
 
                hdc = GetDC(clr_butns[ i ]);
                hbrush = CreateSolidBrush(clrs[ i ]);
                hbrus_old = (HBRUSH)SelectObject(hdc, hbrush);
                SetBkMode(hdc, clrs[ i ]);
                ReleaseDC(clr_butns[ i ], hdc);
                SelectObject(hdc, hbrus_old);
                DeleteObject(hbrush);
            }
            return (INT_PTR) TRUE;
            break;
        }
 
    case WM_COMMAND:
        {
            wmid = LOWORD(wparam);
            wmevent = HIWORD(wparam);
 
            switch (wmid) {
 
            case IDOK:
 
                /*-----------------------------------TODO----------------------------------*/
            case IDCANCEL:
                
                EndDialog(hdlg, wmid);
                return (INT_PTR) TRUE;
                break;              
            }
            return (INT_PTR) TRUE;
            break;
        }
    }
 
 
    return (INT_PTR) FALSE;
}

Nothing is selected
First button is selected and was pushed
Second button was pushed and the mouse is over it (notice the increse of brightness - 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.

#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;
}

Nothing is selected
First button is selected and was pushed
Second button was pushed and the mouse is over it (notice the increse of brightness - 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.

#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;
}

Я искал это много раз, но все, что я нахожу, это MFC. Я хочу это в C ++ WinAPI. Я знаю, как изменить стиль элемента управления кнопки, но не могу понять, как сделать кнопку другого цвета. Итак, как я могу изменить цвет фона элемента управления кнопки WinAPI с помощью C ++? Я не хочу делать это с файлом ресурсов.

Спасибо!

9

Решение

Вместо ссылки я просто выложу копию из моего другого поста, используя пользовательский рисунок, похожий на alwayslearningnewstuff пример:

Ничего не выбрано
Первая кнопка выбрана и нажата
Вторая кнопка была нажата, и мышь находится над ней (обратите внимание на увеличение яркости - резкость подсветки)

Первое изображение показывает, когда ничего не выбрано, второе показывает, когда первая кнопка выбрана и нажата, а последняя показывает, когда была нажата вторая кнопка и мышь находится над ней (обратите внимание на увеличение яркости — яркость резания). Для этого вы должны поймать сообщение 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;
}

9

Другие решения

Я не помню ссылку на оригинальный код, но приведенный ниже код помог мне в прошлом решить проблему, с которой вы сталкиваетесь в настоящее время.

Обратите внимание, что он не имеет файла ресурсов, как вы и просили, и находится в простом Win32 API.

Изучите его внимательно, все комментирует оригинальный автор.

Надеюсь, это поможет вам, как это помогло мне в прошлом.

Если есть вопросы, задавайте, я постараюсь на них ответить.

Насколько я знаю, есть 4 способа изменить цвет кнопки:

  1. Владелец розыгрыша (очевидное решение).

  2. Пользовательский розыгрыш (на мой взгляд лучшее решение).

  3. Наследование контроль (мне это не нравится, но это возможно).

  4. использование растровые изображения как фон ваших кнопок.

  5. обращение WM_CTLCOLORBTN :

Из MSDN:

только Владелец нарисованные кнопки реагируют на обработку этого родительского окна
сообщение.

Акцент мой. Если вы планируете использовать эту опцию, прочитайте Раздел замечаний внимательно.

Код ниже демонстрирует случаи 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);
}

4

Вы можете редактировать кнопку (которая имеет флаг BS_OWNERDRAW) в сообщении WM_DRAWITEM на DialogProc (MSDN О WM_DRAWITEM) вот простой пример того, как нарисовать простую кнопку:

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

3

Вам нужен кнопка, нарисованная владельцем для этого. По некоторым причинам, в отличие от других элементов управления, обычные кнопки не реагируют на изменения, сделанные в WM_CTLCOLORBTN обработчик сообщений

1

Модераторы:Duncon, Hawk, Romeo, Eugie

iscan

Сообщения:5
Зарегистрирован:20 фев 2005, 22:16

По умолчанию, если поставить какой-нибудь контрол, например:
CreateWindow(«button»,»»,WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX|BS_DEFPUSHBUTTON|WS_BORDER,20,30,100,20,hWnd,(HMENU)ID_BUTTON,Inst,NULL);
то цвет его фона будет серый. Такими же получаются и кнопки.

Никак не могу найти где это поменять методами API.
(На форуме искал)

Kolinus

Сообщения:449
Зарегистрирован:23 авг 2004, 14:02
Откуда:Минск

05 апр 2005, 19:19

на самом деле все просто — создаешь свой класс на основе стандартного и указываешь нужную тебе кисть в соотв поле WNDCLASSEX? а именно изменить — по моему через setwindowlong можно — где-то в инете я видел пример — поискай — найдешь

В SAD — все в SAD.

Hawk

Сообщения:215
Зарегистрирован:17 фев 2004, 14:52
Откуда:СПб
Контактная информация:

06 апр 2005, 13:39

Есть такие сообщения, они шлются родительскому окну WM_CTLCOLOR… для многих контролсов свои (для кнопок WM_CTLCOLORBTN). Они и предназначены для изменения стандартных цветов.

Код: Выделить всё

  HDC hdcButton = (HDC) wParam; 
  HWND hwndButton = (HWND) lParam;
  SetTextColor(hdcButton, RGB(255,0,0)); // Set red color for text of the button
  SetBkMode(hdcButton, TRANSPARENT); // Don't use text backgrtound color
  return CreateSolidBrush(RGB(0,0,255)); // Return backround blue brush

Лучше конечно не создавать кисть в каждом сообщении т.к. она каждый раз создается заного и получается лик ресурсов, но для примера сойдет

(GiG)*fh

Сообщения:48
Зарегистрирован:05 ноя 2004, 14:08
Откуда:Russia
Контактная информация:

08 май 2005, 21:14

Блин, чё-то не получается ни один из способов… Чё-нить другое не посоветуете?

И пусть удача повернется к тебе нужным местом :)

Hawk

Сообщения:215
Зарегистрирован:17 фев 2004, 14:52
Откуда:СПб
Контактная информация:

10 май 2005, 09:38

Ну тогда тебе надо рисовать кнопку самому, глянь стиль BS_OWNERDRAW

Аватара пользователя

Romeo

Сообщения:3091
Зарегистрирован:02 мар 2004, 17:25
Откуда:Крым, Севастополь
Контактная информация:

10 май 2005, 16:45

Плохо пробуешь, если не получается. А ты в паренте это пишешь или в самом контроле?

Entites should not be multiplied beyond necessity @ William Occam

Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)

Сообщение «Спасибо» малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой «Reputation» в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.

(GiG)*fh

Сообщения:48
Зарегистрирован:05 ноя 2004, 14:08
Откуда:Russia
Контактная информация:

11 май 2005, 15:16

В паренте

И пусть удача повернется к тебе нужным местом :)

Eugie

Сообщения:707
Зарегистрирован:17 фев 2004, 23:59
Откуда:SPb

12 май 2005, 16:43

Для стандартых кнопок обрабатывать WM_CTLCOLORBTN смысла мало: все равно будет использован системный цвет,
цитата:

Buttons with the BS_PUSHBUTTON, BS_DEFPUSHBUTTON, or BS_PUSHLIKE styles do not use the returned brush. Buttons with these styles are always drawn with the default system colors. Drawing push buttons requires several different brushes-face, highlight and shadow-but the WM_CTLCOLORBTN message allows only one brush to be returned. To provide a custom appearance for push buttons, use an owner-drawn button.

Т.е. придется рисовать кнопку самому, используя стиль BS_OWNERDRAW, либо примерно то же самое с помощью subclassing.

    1. Работа с кнопками и цветом

Приложение позволяет изменять цвет
прямоугольника, увеличивая или уменьшая
составляющие цвета.

Рис.2
Исходный вид окна в л/р №2

Порядок работы

1. Сначала создадим простейшее приложение.

2. Добавим определения констант-идентификаторов
для кнопок:

#define
ID_Red1
1

#define
ID_Red2
2

#define
ID_Green1
3

#define
ID_Green2
4

#define
ID_Blue1 5

#define
ID_Blue2 6

3. Создадим главное окно и кнопки:

BOOL
InitInstance(HINSTANCE hInstance, int
nCmdShow)

{

HWND
hWnd, hRed1, hRed2, hGreen1,hGreen2,hBlue1,hBlue2 ;

hInst
= hInstance; // Сохранить дескриптор экземпляра
в глобальной //переменной

hWnd
= CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,

200,
200, 500, 320, NULL, NULL, hInstance, NULL);

hRed1
= CreateWindow(«button»,
«красный
+»,
WS_CHILD | WS_VISIBLE ,

20,
20, 180, 30, hWnd, (HMENU) ID_Red1, hInstance, NULL);

hRed2
= CreateWindow(«button»,
«красный
-«,
WS_CHILD | WS_VISIBLE ,

20,
60, 180, 30, hWnd, (HMENU) ID_Red2, hInstance, NULL);

hGreen1
= CreateWindow(«button»,
«зеленый
+»,
WS_CHILD | WS_VISIBLE ,

20,
100, 180, 30, hWnd, (HMENU) ID_Green1, hInstance, NULL);

hGreen2
= CreateWindow(«button»,
«зеленый
-«,
WS_CHILD | WS_VISIBLE ,

20,
140, 180, 30, hWnd, (HMENU) ID_Green2, hInstance, NULL);

hBlue1
= CreateWindow(«button»,
«синий
+»,
WS_CHILD | WS_VISIBLE ,

20,
180, 180, 30, hWnd, (HMENU) ID_Blue1, hInstance, NULL);

hBlue2=
CreateWindow(«button»,
«синий
-«,
WS_CHILD | WS_VISIBLE ,

20,
220, 180, 30, hWnd, (HMENU) ID_Blue2, hInstance, NULL);

if
(!hWnd)

{

return
FALSE;

}

ShowWindow(hWnd,
nCmdShow);

UpdateWindow(hWnd);

return
TRUE;

}

4.Изменим функцию окна:

LRESULT
CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)

{

int
wmId, wmEvent;

PAINTSTRUCT
ps;

HDC
hdc;

static
short
Red=255,Green=255,Blue=255;//
составляющие
цвета

static
COLORREF mycolor=RGB(Red,Green,Blue);//текущий
цвет

HBRUSH
hBr;//кисть

RECT
Rect;//прямоугольник
для окрашивания

Rect.left=250;

Rect.top=60;

Rect.right=440;

Rect.bottom=205;

switch
(message)

{

case
WM_COMMAND:

wmId
= LOWORD(wParam);

wmEvent
= HIWORD(wParam);

//
Разобрать выбор в меню или сообщение
от дочернего окна

switch
(wmId)

{
case
ID_Red1: Red+=5;if(Red>255)Red=255;

break;

case
ID_Red2: Red-=5;if(Red<0)Red=0;

break;

case
ID_Green1: Green+=5;if(Green>255)Green=255;

break;

case
ID_Green2: Green-=5;if(Green<0)Green=0;

break;

case
ID_Blue1: Blue+=5;if(Blue>255)Blue=255;

break;

case
ID_Blue2: Blue-=5;if(Blue<0)Blue=0;

break;

case
IDM_ABOUT:

DialogBox(hInst,
MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);

break;

case
IDM_EXIT:

DestroyWindow(hWnd);

break;

}

//
создадим цвет

mycolor=RGB(Red,Green,Blue);

//
помечаем область, соответствующую
прямоугольнику, требующей обновления

InvalidateRect(hWnd,&Rect,TRUE);

UpdateWindow(hWnd);

break;

case
WM_PAINT:

//получаем
контекст для рисования

hdc
= BeginPaint(hWnd, &ps);

//создаем
сплошную кисть нужного цвета

hBr=CreateSolidBrush(mycolor);

//окрашиваем
прямоугольник Rect кистью hBr

FillRect(hdc,&Rect,hBr);

//создаем
сплошную кисть черного цвета

hBr=CreateSolidBrush(RGB(0,0,0));

//рисуем
рамку вокруг прямоугольника

FrameRect(hdc,&Rect,hBr);

//заканчиваем
рисовать

EndPaint(hWnd,
&ps);

break;

case
WM_DESTROY:

PostQuitMessage(0);

break;

default:

return
DefWindowProc(hWnd, message, wParam, lParam);

}

return
0;

}

Задание

                1. При каждом изменении цвета выводить
                  значения его составляющих.

                2. Вывод осуществлять в элемент
                  управления Static.

                3. Вывод осуществлять в элемент
                  редактирования Edit.

                4. Вывод осуществлять при помощи
                  функции TextOut.

Соседние файлы в папке Операционные системы

  • #
  • #

Закрашиваем кнопки


Автор: Bob Ryan.

Скачать Исходник (3Kb) и Демонстрационный проект (13Kb)

Одна из проблем в архитектуре Windows — это
невозможность закрашивать кнопки различными
цветами. Класс представленный здесь не
претендует на звание «передовой
технологии», однако многие программисты
нуждаются в таком классе (особенно при
разработке приложений мультимедиа).
Единственный способ рисовать цветные кнопки, это
сделать собственный обработчик рисования кнопки
(или создать bitmap кнопку, что само по себе не
хорошо). Класс CColorButton позволяет Вам:

  • Задавать размеры и свойства кнопки.
  • Устанавливать цвет текста кнопки, цвет самой
    кнопки.

Содержимое класса

Класс содержит единственную функцию, Attach(),
которая инициализирует собственный обработчик
прорисовки кнопки. Обычно эта функция втавляется
в диалоговый метод OnInitDialog().


BOOL Attach(const UINT nID, CWnd* pParent, 
            const COLORREF BGColor = RGB(192, 192, 192), 
            const COLORREF FGColor = RGB(1, 1, 1), 
            const COLORREF DisabledColor = RGB(128, 128, 128), 
            const UINT nBevel = 2);
Где:
  • nID — ID номер Вашей кнопки
  • pParent — родителькое окно.

    Следующие
    три параметра — это цвет самой кнопки, цвет текста
    на кнопке, и запрет на цвета по умолчанию (серая
    кнопка, чёрный текст …).

  • nBevel (bevel width) (я пока не понял
    что это такое, но по умолчанию обычно 2).

Как пользоваться классом CColorButton

  • Добавьте в Ваш проект файлы colorBtn.h и colorBtn.cpp.
  • Нарисуйте кнопку в Developer Studio; проверьте, чтобы
    было отмечено свойство Owner-Draw.
  • Не забудьте добавить в Ваш основной файл .h
    строчку «#include colorbtn.h»
  • Так же добавьте в файл .h, следующие объявления
    (столько же, сколько у Вас будет кнопок)CColorButton m_btn1;
    CColorButton m_btn2;
    и т.д.
  • В функции OnInitDialog , инициализируем цвета:

   VERIFY(m_btn1.SetColors(IDOK, this, CLOUDBLUE, DKBLUE, WHITE));
   VERIFY(m_btn2.SetColors(IDCANCEL, this, DKBLUE, WHITE));

Замечание: цвета, используемые в данном
примере — BLACK, WHITE, BLUE, DKGRAY, и т.д.. — это константы
определённые в COLORREF , которые Вы можете
определить с помощью макросов RGB():


	const COLORREF CLOUDBLUE = RGB(128, 184, 223);
	const COLORREF WHITE = RGB(255, 255, 255);
	const COLORREF BLACK = RGB(1, 1, 1);
	const COLORREF DKGRAY = RGB(128, 128, 128);
	const COLORREF etc...

Ограничения:

  • Невозможно поменять цвета кнопок когда окно уже
    создано.
  • Не поддерживает динамическую функцию Create().
  • Не поддерживается политра в 256 цветов.
  • Нет возможности задать различный шрифт для
    текста на кнопке.

    msm.ru

    Нравится ресурс?

    Помоги проекту!

    !
    Правила раздела Visual C++ / MFC / WTL (далее Раздела)

    >
    цвет надписи на кнопке, WinAPI

    • Подписаться на тему
    • Сообщить другу
    • Скачать/распечатать тему



    Сообщ.
    #1

    ,
    08.05.04, 13:14

      Елена Newbie

      Рейтинг (т): 0

      Подскажите, как поменять цвет надписи на кнопке в WinAPI. Черный как-то не устраивает ;) :wall:


      Bjarne Stroustrup



      Сообщ.
      #2

      ,
      08.05.04, 14:16

        WM_CTLCOLORBTN и SetTextColor()


        UncleBob



        Сообщ.
        #3

        ,
        08.05.04, 19:07

          Пример (только не WM_CTLCOLORBTN, а WM_CLTCOLORSTATIC) можно глянуть здесь.


          SunDay



          Сообщ.
          #4

          ,
          18.05.04, 13:26

            Елена Newbie

            Рейтинг (т): 0

            Спасибо за ответы!!!!!!!!
            У меня есть еще один вопрос:а как можно проверить, надпись на какой именно кнопке я закрашиваю в определенный цвет?

            ExpandedWrap disabled

              case WM_CTLCOLORBTN:

                          {

                           HDC hdcButton14 = (HDC) wParam;

                            HBRUSH hb=CreateSolidBrush(RGB(189,190,198));

                           SetTextColor(hdcButton14,RGB(0,0,255));

                          SetBkColor(hdcButton14,RGB(189,190,198));

                           TextOut(hdcButton14,21,7,»*»,1);

                           return (long)hb;

                    }

            А если теперь я хочу красить Button7?
            Заранее спасибо!


            Ace



            Сообщ.
            #5

            ,
            18.05.04, 13:32

              Цитата

              if( ::GetDlgCtrlID( HWND( lParam)) == IDC_BUTTON_XXX)


              UncleBob



              Сообщ.
              #6

              ,
              18.05.04, 15:13

                Цитата

                SunDay, 18.05.04, 17:26
                case WM_CTLCOLORBTN:
                {
                HDC hdcButton14 = (HDC) wParam;
                HBRUSH hb=CreateSolidBrush(RGB(189,190,198));
                SetTextColor(hdcButton14,RGB(0,0,255));
                SetBkColor(hdcButton14,RGB(189,190,198));
                TextOut(hdcButton14,21,7,»*»,1);
                return (long)hb;
                }

                В выделенной строке ошибка. Brush надо либо создавать один раз, а потом подсовывать в CTLCOLORBTN, либо получать Brush по GetStockObject. В противном случае (из-за отсутствия DeleteObject) возникают утечки ресурсов GDI, что приводит в итоге к неправильному отображению окна приложения.

                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

                0 пользователей:

                • Предыдущая тема
                • Visual C++ / MFC / WTL
                • Следующая тема

                Рейтинг@Mail.ru

                [ Script execution time: 0,0284 ]   [ 16 queries used ]   [ Generated: 10.02.23, 21:28 GMT ]  

                Понравилась статья? Поделить с друзьями:

                Читайте также:

              • Как изменить цвет кнопки contact form 7
              • Как изменить цвет кнопки button
              • Как изменить цвет кнопки bootstrap
              • Как изменить цвет кнопки android java
              • Как изменить цвет кмд

              • 0 0 голоса
                Рейтинг статьи
                Подписаться
                Уведомить о
                guest

                0 комментариев
                Старые
                Новые Популярные
                Межтекстовые Отзывы
                Посмотреть все комментарии