如何从按钮控件中删除边框并设置复选框背景

Posted

技术标签:

【中文标题】如何从按钮控件中删除边框并设置复选框背景【英文标题】:How to remove border from button control and set checkbox background 【发布时间】:2019-04-26 22:48:50 【问题描述】:

我是win32 API的初学者,我做了

HWND button = CreateWindowEx(0, "BUTTON", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP, 150, 100, 150, 30, hwnd, (HMENU)ID_BUTTON, hInstance, NULL);

HWND check = CreateWindowEx(0, "BUTTON", "text", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, 150, 100, 300, 20, hwnd, (HMENU)ID_CHECK, hInstance, NULL);

我想从插入位图的按钮控件中删除白色边框,并在BS_CHECKBOX 上设置黑色背景和白色文本。我读到了WM_CTLCOLORBTN,但我不知道如何正确地做到这一点。

【问题讨论】:

我相信您需要制作一个所有者绘制的按钮。类似:Remove border from win32 button 我看到了这个解决方案,但我不知道如何在复选框中应用它。感谢您的回复。 【参考方案1】:

WM_CTLCOLORBTN 应与BS_OWNERDRAW 一起使用。

也就是说,只有添加了BS_OWNERDRAW,才会触发WM_CTLCOLORBTN,并且可以重绘按钮。

但是当你使用BS_OWNERDRAW时,你原来的复选框样式会被替换,像​​这样。

check = CreateWindowEx(0,L"BUTTON",L"text", WS_CHILD | WS_VISIBLE | BS_CHECKBOX | BS_OWNERDRAW, 150, 100, 60, 20, hWnd, (HMENU)ID_CHECK, (HINSTANCE)GetWindowLong(hWnd, GWLP_HINSTANCE), NULL);
 case WM_CTLCOLORBTN:

    return (INT_PTR)CreateSolidBrush(RGB(0, 0, 0));
    break;

case WM_DRAWITEM:

    LPDRAWITEMSTRUCT pDIS = (LPDRAWITEMSTRUCT)lParam;
    if (pDIS->hwndItem == check)
    
        SetTextColor(pDIS->hDC, RGB(255, 255, 255));
        SetBkColor(pDIS->hDC, RGB(0, 0, 0));
        WCHAR Text[99];
        int len = SendMessage(check, WM_GETTEXT,
            ARRAYSIZE(Text), (LPARAM)Text);
        TextOut(pDIS->hDC, pDIS->rcItem.left, pDIS->rcItem.top, Text, len);
    
    return TRUE;

调试结果:

你会发现和你想的不一样。

根据 MSDN,创建一个所有者绘制的按钮。所有者窗口 当按钮的视觉方面有时收到 WM_DRAWITEM 消息 改变了。不要将 BS_OWNERDRAW 样式与任何其他按钮组合 样式。

所以,我建议你这样做。

check = CreateWindowEx(0,L"BUTTON",L"text123", WS_CHILD | WS_VISIBLE | BS_CHECKBOX ,150, 100, 60, 20, hWnd, (HMENU)ID_CHECK, (HINSTANCE)GetWindowLong(hWnd, GWLP_HINSTANCE), NULL);
case WM_CTLCOLORSTATIC:

    HDC hdc = (HDC)wParam;
    HWND hWnd = (HWND)lParam;
    if (hWnd == check)
    
        SetBkMode(hdc, TRANSPARENT);
        SetTextColor(hdc, RGB(255, 255, 255));
        return (INT_PTR)CreateSolidBrush(RGB(0, 0, 0));
    
break;

通过触发WM_CTLCOLORSTATIC,文字和背景颜色自绘。

【讨论】:

感谢您的回复。很有帮助。【参考方案2】:

Strive answer 不适用于按钮。似乎它只适用于文本框和复选框。 顺便说一句,这里仍然是边界。

您应该以这种方式创建按钮:

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

 CreateWindowEx(WS_EX_TRANSPARENT, "Button", NULL, WS_CHILD | WS_VISIBLE | BS_FLAT | BS_OWNERDRAW, start_x, start_y, size_y, size_x, hWnd, (HMENU)(i + 2000), NULL, NULL);

.

case WM_DRAWITEM: 
            auto id = LOWORD(wParam);
            if (id >= 2000) 
                id -= 2000;
                drawButton(dis, id);
                return true;
            


case WM_INITDIALOG: 
    INITCOMMONCONTROLSEX icx;
    icx.dwSize = sizeof(INITCOMMONCONTROLSEX);
    icx.dwICC = ICC_STANDARD_CLASSES;
    InitCommonControlsEx(&icx);

【讨论】:

以上是关于如何从按钮控件中删除边框并设置复选框背景的主要内容,如果未能解决你的问题,请参考以下文章

如何设置复选框边框颜色

DIV+CSS中复选框的背景颜色不显示,但是边框显示,为啥?

winform公共控件

如何删除自定义按钮上的细边框?

Java 添加删除Excel表单控件

MFC中如何向列表控件中嵌入单选按钮radio控件