我的简单 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) )。
所以你需要做的是:
- 调用
wndTitle.GetDC()
以获取HDC
。 - 调用
SelectObject()
来选择正确的窗口字体(您可以使用WM_GETFONT
来获取它;不确定MFC是否有它的包装函数),保存返回值,之前的字体,用于步骤 4 - 调用
DrawText()
- 调用
SelectObject()
至 select the previous font back in - 调用
wndTitle.ReleaseDC()
表明您已完成使用HDC
更多详细信息请参见 the MSDN page for CWindow::GetDC() .
关于windows - 如何计算静态控件中文本的实际高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28516145/