windows - 如何计算静态控件中文本的实际高度

标签 windows winapi

我的简单 Win32 对话框包含两个静态文本控件(IDC_STATIC_TITLE 和 IDC_STATIC_SECONDARY),它在资源编辑器中的外观如下:

在运行时,文本第一个字符串会动态更新。此外,该文本字符串的字体也会被替换,使其大于其下面的 IDC_STATIC_SECONDARY 字符串。生成的文本字符串可能跨越单行、两行或更多行。

我希望在运行时将保存辅助文本的另一个静态控件直接放置在标题字符串下方。但是,我在 WM_INITDIALOG 回调中重新定位此控件的尝试效果不佳。第二根弦与第一根弦重叠。我想我可以使用 DrawText 和 DT_CALCRECT 来计算主要文本字符串的高度,然后根据结果移动辅助文本字符串。我的代码有点短,如下所示:

DrawText 返回一个坐标为 {top=42 Bottom=74 left=19 right=461} 的 RECT,从顶部减去底部是“32”。这似乎有点短。我怀疑我没有正确调用 API 和/或逻辑单元和像素单元之间的不同映射存在问题。

这是相关的ATL代码。 CMainWindow 类只是继承自 ATL 的 CDialogImpl 类。

CMainWindow::CMainWindow():
_titleFont(NULL),
_secondaryFont(NULL)
{
    LOGFONT logfont = {};
    logfont.lfHeight = 30;
    _titleFont = CreateFontIndirect(&logfont);
}

LRESULT CMainWindow::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    CString strTitle;
    RECT rectDrawText = {}, rectTitle={}, rectSecondary={};
    CWindow wndTitle = GetDlgItem(IDC_STATIC_TITLE);
    CWindow wndSecondary = GetDlgItem(IDC_STATIC_SECONDARY);

    this->GetDlgItemText(IDC_STATIC_TITLE, strTitle);

    wndTitle.SetFont(_titleFont);   // font created with Create

    wndTitle.GetWindowRect(&rectTitle);
    wndSecondary.GetWindowRect(&rectSecondary);
    ScreenToClient(&rectTitle);
    ScreenToClient(&rectSecondary);

    rectDrawText = rectTitle;
    DrawText(wndTitle.GetDC(), strTitle, strTitle.GetLength(), &rectDrawText, DT_CALCRECT|DT_WORDBREAK); // compute the actual size of the text

    UINT height = rectSecondary.bottom - rectSecondary.top;  // get the original height of the secondary text control
    rectSecondary.top = rectDrawText.bottom;                 // position it to be directly below the bottom of the title control
    rectSecondary.bottom = rectSecondary.top + height;       // add the height back
    wndSecondary.MoveWindow(&rectSecondary);

    return 0;
}

我做错了什么?

最佳答案

不管它的名字听起来如何,wndTitle.GetDC() 不会返回一些属于 CWindow 一部分的指针/引用,并且每次调用都是相同的。相反,它每次都会为窗口检索一个全新的设备上下文。 (它基本上是 GetDC() Windows API 调用的薄包装器,直接返回 HDC 而不是 MFC 等效项。)

尽管该设备上下文与窗口关联,但仍加载了默认参数,包括默认字体(IIRC 为 that old "System" font from the 16-bit days (most of this screenshot) )。

所以你需要做的是:

  1. 调用wndTitle.GetDC()以获取HDC
  2. 调用SelectObject()来选择正确的窗口字体(您可以使用WM_GETFONT来获取它;不确定MFC是否有它的包装函数),保存返回值,之前的字体,用于步骤 4
  3. 调用DrawText()
  4. 调用 SelectObject()select the previous font back in
  5. 调用 wndTitle.ReleaseDC() 表明您已完成使用 HDC

更多详细信息请参见 the MSDN page for CWindow::GetDC() .

关于windows - 如何计算静态控件中文本的实际高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28516145/

相关文章:

windows - qt 应用程序 64 位 Windows

windows - "Register"一个 .exe,因此您可以从 Windows 中的任何命令行运行它

c - 如何将马拉雅拉姆语打印为 c/c++ 程序输出?

c++ - 提高 Windows 应用程序的性能

c++ - Winapi 专用鼠标/键盘

c# - 我最快什么时候可以关闭窗口?

c++ - 两个 Windows 应用程序可以使用命令行进行通信吗?

linux - 在 GNU/Linux 上生成 lnk 文件传输到 windows

c++ - 检查单选按钮状态 winapi

c++ - 使用 Visual C++ 设计器在主窗口上进行控制?