如何使用win32 API更改ComboBox的颜色

时间:2018-06-14 06:03:30

标签: winapi visual-c++

ComboBox在创建时的颜色为白色。我想改变外观,使其着色(不是背景颜色)。我使用原生的winapi,不知道该怎么做。我用谷歌搜索,我可以找到通过处理WM_CTLCOLORLISTBOX来改变背景颜色的例子,但这不是我想要的。我也有谷歌提示我应该继承ComboBox并处理WM_NCPAINT消息,但是没有例子可以实现我想要的效果。我一直在争夺这几天没有运气。任何帮助表示赞赏。

enter image description here enter image description here

1 个答案:

答案 0 :(得分:2)

如果启用了视觉样式,您可以对组合框进行子类化并覆盖WM_PAINT。这仅适用于CBS_DROPDOWNLIST(资源编辑器调用它"删除列表")。您必须手动绘制下拉箭头。

#include <Windows.h>
#include <CommCtrl.h>

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

LRESULT CALLBACK ComboProc(HWND hwnd, UINT msg, WPARAM wParam,
    LPARAM lParam, UINT_PTR uIdSubClass, DWORD_PTR)
{
    switch(msg)
    {
    case WM_PAINT:
    {
        DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE);
        if(!(style & CBS_DROPDOWNLIST))
            break;

        RECT rc;
        GetClientRect(hwnd, &rc);

        PAINTSTRUCT ps;
        auto hdc = BeginPaint(hwnd, &ps);
        auto bkcolor = RGB(80, 140, 0);
        auto brush = CreateSolidBrush(bkcolor);
        auto pen = CreatePen(PS_SOLID, 1, RGB(128, 128, 128));
        auto oldbrush = SelectObject(hdc, brush);
        auto oldpen = SelectObject(hdc, pen);
        SelectObject(hdc, (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0));
        SetBkColor(hdc, bkcolor);
        SetTextColor(hdc, RGB(255, 255, 255));

        Rectangle(hdc, 0, 0, rc.right, rc.bottom);

        if(GetFocus() == hwnd)
        {
            RECT temp = rc;
            InflateRect(&temp, -2, -2);
            DrawFocusRect(hdc, &temp);
        }

        int index = SendMessage(hwnd, CB_GETCURSEL, 0, 0);
        if(index >= 0)
        {
            int buflen = SendMessage(hwnd, CB_GETLBTEXTLEN, index, 0);
            TCHAR *buf = new TCHAR[(buflen + 1)];
            SendMessage(hwnd, CB_GETLBTEXT, index, (LPARAM)buf);
            rc.left += 5;
            DrawText(hdc, buf, -1, &rc, DT_EDITCONTROL|DT_LEFT|DT_VCENTER|DT_SINGLELINE);
            delete[]buf;
        }

        SelectObject(hdc, oldpen);
        SelectObject(hdc, oldbrush);
        DeleteObject(brush);
        DeleteObject(pen);

        EndPaint(hwnd, &ps);
        return 0;
    }

    case WM_NCDESTROY:
    {
        RemoveWindowSubclass(hwnd, ComboProc, uIdSubClass);
        break;
    }

    }

    return DefSubclassProc(hwnd, msg, wParam, lParam);
}

用法:

INT_PTR CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lParam)
{
    static HBRUSH hbrBkgnd = CreateSolidBrush(RGB(0, 255, 0));
    switch(msg)
    {
    case WM_INITDIALOG:
    {
        HWND hcombo = GetDlgItem(hwnd, IDC_COMBO1);
        SetWindowSubclass(hcombo, ComboProc, 0, 0);
        ...
        break;
    }
    ...
}