我发现Win32 ChooseFont()API有些奇怪,更重要的是,行为不一致。
LOGFONT lf = { 0 };
strcopy(lf.lfFaceName, m_face_name);
const int ppi = GetDeviceCaps(pView, LOGPIXELSY);
lf.lfHeight = -MulDiv(m_font_height, ppi, 72);
CFontDialog fd(&lf);
if (fd.DoModal() != IDOK)
return;
m_face_name = fd.GetFaceName();
m_font_height = lf.lfHeight;
假设第一次,脸部名称是“Segoe UI”,这是有效的。
但是如果用户将对话框更改为“Segoe UI”,“Light”,“9”,(面部,样式,高度),我们再次进行上述操作,那么字体选择常用对话框失败选择“Segoe UI”作为面部名称。相反,我将Font:字段视为空白。
如果用户选择“常规”,“斜体”,“粗体”,“粗体斜体”样式,这不是问题,因为这些样式存储在样式位中,并且不会使名称变硬。我放弃它们进行第二次运行,因为我忽略了它们(我会禁用字体样式:如果有一种方法可以轻松地这样做 - 我不希望将CFontDialog子类化为此 - 这是一个整体'其他级别的时间&努力,这一刻不允许)。
我尝试根据对话框中的先前细节创建字体,然后尝试将LOGFONT拉回来。没有骰子。
同样,我已经尝试查询FontStyle()的对话框 - 但是返回空白 - 所以没有什么可以从这里删除字体名...
这似乎只是MS对话框的一个错误 - 它告诉我一件事,但是然后不能使用它自己的输出来第二次正确地初始化自己(被授予,我只是坚持一些,而不是所有的LOGFONT在这种情况下)。
有谁知道WTH对此有用吗?或者我可能习惯的方法(缺少硬编码在字体名称的末尾寻找“Light” - YUCK!)?
答案 0 :(得分:4)
字体设计的发展明显超过了传统api的跟进能力。 OpenType发生了,一个。除了LOGFONT可以支持的其他字体样式。对于Segoe UI,控制粗体的属性可以是Light和Semibold。对于其他字体,字体拉伸是另一种属性,常见的是Condensed和Expanded。使用该字体可以实现专用的字体文件,使这些样式看起来很好,而不依赖于从现有字体合成样式,就像在过去那样。查看WPF FontStretch和FontWeight枚举类型以获取可能的值。
这些是LOGFONT无法表达的属性。有一个兼容性黑客来处理这个,类型的面部名称被映射。因此,具有“Light”风格的“Segoe UI”变成了“Segoe UI Light”。 Windows字体映射器将从这样的名称中选择正确的真实字体文件。然而,什么不起作用是使用“Segoe UI Light”初始化LOGFONT.lfFaceName。实际上不确定为什么,可能避免不必处理歧义。或者只是简单的流淌。一种可能的解决方法是在字体外观名称中识别这些附加的样式名称,但这也不完美。
GDI耗气。很像User32。
答案 1 :(得分:-1)
首先,在proc中初始化LOGFONT时,不能只将其设置为0
ala "= { 0 };"
使用类似
的内容memset(&lf, 0, sizeof(lf));
否则你的proc中的你的lf包含随机垃圾。其次,没有保存LOGFONT结构的所有设置有什么大不了的?你正在使用MFC,这不是因为它会有太大的开销。如果修复lf的初始化不起作用,只需保存整个LOGFONT。