c++ - 如何从 CFont 对象获取自动计算的字体宽度?

标签 c++ mfc

我使用的是固定大小的字体(例如:“Courier New”)。当我通过调用 CFont::CreateFont 函数初始化 CFont 对象时,我只想指定字体高度。

CFont Font;
Font.CreateFont( nFontHeight, 0, 0, 0, 0, false, false,
    0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
    FIXED_PITCH|FF_MODERN, _T("Courier New") );

根据文档,字体宽度将自动计算。我需要该自动计算的值来进行其他计算。

GetLogFont 函数是无用的,因为CFont 似乎只保存我们给的值,即width = 0 并且它只在第一次使用时计算该值。 (请查看Microsoft documentation)

另一种选择是使用单个字符的 CDC::GetTextExtent。但在那种情况下,即使在高度上我也能看到一些细微的差异。例如,当我给 -32 作为高度时,GetTextExtent 返回 33 作为 y 值。

有什么方法可以得到正确的计算宽度?

最佳答案

首先,如果只想指定字体高度,通常要使用CreatePointFont。其次,Windows 95/98/SE/Me 已经过时了——随着它们的到来,基本上所有的理由都使用 Microsoft 的“文本”宏,如 _T("whatever")。如果您想要宽字符,请直接询问:

CFont font;   
font.CreatePointFont(nFontHeight, L"Courier New");

然后,按照@MikMik 的建议,您可以使用GetTextMetrics 获取宽度——但只有您将字体选择到 DC 中(GetTextMetrics 将所选字体的数据获取到 DC 中,而不仅仅是原始字体的数据——尤其是在小字体大小的情况下,一些内容会进行调整以补偿输出设备的分辨率。

但是请注意,即使对于固定宽度的字体,字符串的宽度也不一定 char_width * num_chars。至少如果我没记错的话,即使是固定宽度的字体仍然可以进行紧排,这意味着间距是根据同时出现的字符对来调整的。经典的例子就是一对AV。因为它们彼此相邻的线通常处于相同的角度(或至少非常接近相同),所以将调整间距以使它们靠得更近——事实上,“V”的顶部将经常与“A”的底部重叠。一串字符的宽度可能会有所不同,即使每个字符的宽度都相同。

顺便说一下,我不确定 Courier New 是否会这样做,但我有理由相信至少有一些固定宽度的字体会这样做。

关于c++ - 如何从 CFont 对象获取自动计算的字体宽度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6055541/

相关文章:

c++ - 无法使用 cuda 进入 __global__ 函数

c++ - G++ 警告 : narrowing conversion of

c++ - 不同机器上 list 中的不同版本

winapi - 强制组合框位于上方而不是下方的 "dropdown"

c++ - 使用 Boost.Python 设置包装类的元类

c++ - 交错 std::map 插入和迭代

c++ - Visual Studio 2019中的C2011 'CMemDC' :'class'类型重新定义

c++ - MFC 执行 while 循环

c++ - MFC PreCreateWindow 创建一个填满屏幕但任务栏除外的窗口

java - 将成员函数放在成员变量之前或反之亦然的原因是什么?