自动计算标准 WinAPI 控件的宽度

问题描述 投票:0回答:1

我正在尝试编写一个通用函数来根据当前标题/文本内容自动计算几种标准类型的WinAPI控件的宽度。此代码非常适合获取文本的宽度:

HWND hWnd = GetDlgItem(GetWindowHandle(), GetControlID());
int textLen = GetWindowTextLengthW(hWnd);
std::wstring ctrlText(textLen, 0);
GetWindowTextW(hWnd, ctrlText.data(), static_cast<int>(ctrlText.size()));
HDC hdc = GetDC(hWnd);
HFONT hFont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0);
if (!hFont)
    hFont = (HFONT)GetStockObject(SYSTEM_FONT);
HFONT hOldFont = (HFONT)SelectObject(hdc, hFont);
SIZE textSize{};
GetTextExtentPoint32W(hdc, ctrlText.data(), static_cast<int>(ctrlText.size()), &textSize);

尽管文档说

textSize.cx
中的结果是“逻辑单位”,但结果似乎是窗口水平像素。如果我假设这个比例,我就能够在我的 dpi 感知应用程序中得出正确的像素数。

问题在于如何处理我用于单选按钮和复选框的

WC_BUTTON
控件。有没有正确的方法来计算单选按钮或复选框的附加宽度?目前,我正在对每个控件类型的附加值进行硬编码。但这似乎是一个糟糕的选择,尽管 ChatGPT 也建议对其进行硬编码。我正在寻找更好的解决方案。

编辑:根据上面的代码(现在包括分配字体),我添加了以下代码以尝试按照建议使用主题:

HTHEME hTheme = OpenThemeData(hWnd, L"BUTTON");
if (hTheme)
{
    RECT rcContent{}, rcBounds{};
    HRESULT rslt = GetThemeBackgroundContentRect(hTheme, hdc, partID, contentID, &rcBounds, &rcContent);
    if (rslt != S_OK)
    {
        LONG errCode = GetLastError();
    }
    MARGINS margins{};
    rslt = GetThemeMargins(hTheme, hdc, partID, contentID, TMT_CONTENTMARGINS, NULL, &margins);
    if (rslt != S_OK)
    {
        LONG errCode = GetLastError();
    }
    CloseThemeData(hTheme);
    LONG width = (rcBounds.right - rcBounds.left) + margins.cxLeftWidth + margins.cxRightWidth;
}
SelectObject(hdc, hOldFont);
ReleaseDC(hWnd, hdc); // release hdc moved here (compared to above)

我已经在调试器中验证没有发生错误。 (也就是说,没有采用

!= S_OK
路径。)但是返回的矩形(和边距)全为零。有人看出我哪里误入歧途了吗?

winapi checkbox radio-button controls
1个回答
0
投票

GetThemePartSize可以检索参考Parts and States的尺寸数据,@JonathanPotter也指出了这一点。

HTHEME hTheme = OpenThemeData(NULL, L"BUTTON");
if (hTheme)
{
    SIZE size{};
    HRESULT hr = GetThemePartSize(hTheme,NULL, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL,NULL, TS_DRAW,&size);//13*13
    hr = GetThemePartSize(hTheme,NULL, BP_CHECKBOX, CBS_UNCHECKEDNORMAL,NULL, TS_DRAW,&size);//13*13
}
© www.soinside.com 2019 - 2024. All rights reserved.