【问题标题】:Different result on laptop and stationary computer笔记本电脑和固定电脑上的不同结果
【发布时间】:2023-04-03 17:59:01
【问题描述】:

下面的代码计算将文本保存到复选框的矩形的大小。当我使用具有不同屏幕分辨率的显示器的固定计算机时,代码工作正常。但是当我在连接了外接显示器的笔记本电脑上运行完全相同的代码时,盒子太小了。笔记本电脑屏幕分辨率为 1680x1050,显示器为 1920x1080。

无论我在哪台计算机上运行 pclRect,它的值都是相同的。

有人知道如何解决这个问题吗?

结果:

void CForm::SetSize(CWnd *pCWnd, CRect *pclRect)
{       
    CDC *pclDC = m_pclPanel->GetDC();

    CFont* font = pCWnd->GetFont();
    LOGFONT logFont;
    font->GetLogFont(&logFont);

    CString str;
    pCWnd->GetWindowText(str);//Get controller text

    CClientDC dc(pCWnd);
    dc.SelectObject(font);

    int iWidth;
    int iHeight;

    long lFontSize = -MulDiv(logFont.lfHeight, GetDeviceCaps(pclDC->m_hDC, LOGPIXELSY), 72);

    iWidth = dc.GetTextExtent(str).cx; //Get controller text length
    iWidth += GetExtraWidth(); //This adds 18 to the width since it's the width of the checkbox itself
    iHeight = abs(lFontSize) + GetExtraHeight();

    pclRect->bottom = pclRect->top + iHeight;
    pclRect->right = pclRect->left + iWidth;

    pCWnd->MoveWindow(pclRect);
}

【问题讨论】:

    标签: c++ windows mfc


    【解决方案1】:

    如果目标窗口是 Vista 或更高版本,请使用 BCM_GETIDEALSIZE 查找最小尺寸。但复选框不能有多行标志 (BS_MULTILINE)。例如

    m_checkBox.SetWindowText(L"long text xxx xxx xxx xxx xxx xxx");
    SIZE sz;
    if (Button_GetIdealSize(m_checkBox.m_hWnd, &sz) && sz.cx > 0 && sz.cy > 0)
    {
        m_checkBox.SetWindowPos(0, 0, 0, sz.cx, sz.cy, SWP_NOZORDER|SWP_NOMOVE);
    }
    else
    {
        //use another method ...
    }
    

    否则,请修改您的代码,而不是为复选框宽度提供 18 像素,而是使用 GetSystemMetrics 查找复选框的宽度(这会导致默认 DPI 为 15 像素,因此您必须为文本填充添加更多像素)。

    如果主题处于活动状态,请使用 GetThemePartSize。例如:

    CClientDC dc(this);
    SIZE sz;
    HTHEME ht = OpenThemeData(m_hWnd, L"Button");
    if (ht)
    {
        GetThemePartSize(ht, dc, BP_CHECKBOX, CBS_CHECKEDNORMAL, NULL, TS_TRUE, &sz);
        CloseThemeData(ht);
        //sz.cx is 13 pixels in default DPI
    }
    else
    {
        sz.cx = GetSystemMetrics(SM_CXMENUCHECK);
        //sz.cx is 15 pixels in default DPI
    }
    

    屏幕分辨率与此处无关。发布的图像表明两个显示器具有相同的 DPI 设置。请注意,如果 DPI 设置发生更改,并且您的应用程序是 DPI aware,那么 sz.cx 将有所不同。

    【讨论】:

    • 感谢您的回复,这很有帮助。但由于我使用BS_MULTILINE,我还没有尝试过第一部分。但是当我运行答案的第二部分时,我确实在ht 上得到了不同的结果。但是,sz.cx 在这两种情况下都是 13。我错过了什么吗?
    • 左边的图片,看起来主题已经结束了;因此ht 有效,sz.cx 将是 13。右侧的图像看起来主题未启用;因此htNULLsz.cx 将是15。
    • ht、valid 和 NULL 是对的,但是 sz.cx 无论是否有效都是 13。但是你帮了很多忙,我可以从这里继续前进。非常感谢,谢谢!
    • 我在 Windows 10 上,其中主题始终处于活动状态,因此 sz.cx 始终为 13(我认为 Windows 8 也是如此)。在 Windows XP/Vista/7 上,如果主题未激活,ht 将是 NULLsz.cx 将是 13。
    猜你喜欢
    • 2017-10-10
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    • 2015-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-30
    相关资源
    最近更新 更多