【问题标题】:Win API Aligning text on a buttonWin API 对齐按钮上的文本
【发布时间】:2018-12-28 23:33:07
【问题描述】:

有没有办法将按钮内的文本水平和垂直居中对齐?

case WM_DRAWITEM:
        {
            LPDRAWITEMSTRUCT Item;
            Item = (LPDRAWITEMSTRUCT)lParam;

            SelectObject(Item->hDC, CreateFont(17, 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(0xE0E0E0) );

            SetBkMode(Item->hDC, 0xE0E0E0);
            SetTextColor(Item->hDC, RGB(255,255,255));

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

【问题讨论】:

    标签: c++ winapi button text center


    【解决方案1】:

    您已经在使用DT_CENTER 标志将文本水平居中。 DrawText() 也有 DT_VCENTERDT_SINGLELINE 标志来垂直居中文本。只需将标志组合在一起即可。

    此外,您还有资源和内存泄漏。您正在从CreateFont() 泄漏HFONT,从CreateSolidBrush() 泄漏HBRUSH,从new[] 泄漏文本缓冲区。使用完毕后,您需要将它们全部释放。

    试试这个:

    case WM_DRAWITEM:
        {
            LPDRAWITEMSTRUCT Item = reinterpret_cast<LPDRAWITEMSTRUCT>(lParam);
    
            HFONT hFont = CreateFont(17, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, TEXT("Arial Black"));
            HFONT hOldFont = (HFONT) SelectObject(Item->hDC, hFont);
    
            HBRUSH hBrush = CreateSolidBrush(RGB(0xE0, 0xE0, 0xE0));
            FillRect(Item->hDC, &Item->rcItem, hBrush);
            DeleteObject(hBrush);
    
            SetBkMode(Item->hDC, TRANSPARENT); // <-- 0xE0E0E0 was not a valid mode value!
            SetTextColor(Item->hDC, RGB(255,255,255));
    
            int len = GetWindowTextLength(Item->hwndItem) + 1;
            LPTSTR lpBuff = new TCHAR[len];
            len = GetWindowText(Item->hwndItem, lpBuff, len);
            DrawText(Item->hDC, lpBuff, len, &Item->rcItem, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
            delete[] lpBuff;
    
            SelectObject(Item->hDC, hOldFont);
            DeleteObject(hFont);
        }
        break;
    

    【讨论】:

    • 我尝试了上述方法,由于某种原因它没有使文本居中,这就是我初始化按钮的方式: button = CreateWindow("BUTTON","Overview",WS_VISIBLE | WS_CHILD | BS_OWNERDRAW, 0,0,200,50, hwnd , (HMENU) 1 , NULL, NULL);
    • 我的错,我也忘记了DT_SINGLELINE 标志。这是DT_VCENTER 工作所必需的。我更新了我的答案,并测试它确实有效。
    【解决方案2】:

    来自https://docs.microsoft.com/en-us/windows/desktop/Controls/button-styles

    可能需要使用BS_OWNERDRAW 来执行您所描述的操作。

    【讨论】:

    • OP 必须已经这样做了,否则他们一开始就不会收到按钮的 WM_DRAWITEM 消息。
    猜你喜欢
    • 2011-07-13
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 2017-11-04
    • 2021-12-26
    • 1970-01-01
    • 2013-03-07
    • 2020-10-05
    相关资源
    最近更新 更多