windows 哪种字体是 MFC 对话框控件的默认字体?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6057239/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 08:23:38  来源:igfitidea点击:

Which Font is the default for MFC Dialog Controls?

windowsvisual-studiovisual-studio-2008winapimfc

提问by Christian Ammer

The picture below (enlarged, so you better see the differences) shows Font differences between dynamically created Edit controls (the upper two examples) and Edit Controls created from the Dialog Editor (the lower example). How can I make the font of my dynamically created CEdit controls looking like the default (the lower example)?

下图(放大,以便您更好地看到差异)显示了动态创建的编辑控件(上面的两个示例)和从对话框编辑器创建的编辑控件(下面的示例)之间的字体差异。我怎样才能让我动态创建的 CEdit 控件的字体看起来像默认的(下面的例子)?

enter image description here

在此处输入图片说明

I have created the CEdit Controls like following:

我创建了 CEdit 控件,如下所示:

obj->CreateEx(WS_EX_CLIENTEDGE, _T("EDIT"), _T(""),
              WS_CHILD | WS_VISIBLE | WS_TABSTOP,
              rect.left, rect.top, rect.Width(), rect.Height(),
              GetSafeHwnd(), reinterpret_cast<HMENU>(mId));

obj->SetFont(&mFont); // mFont was created in the Dialog Constructor
                      // with mFont.CreatePointFont(80, _T("MS Shell Dlg"));

Thanks for your help!

谢谢你的帮助!

回答by Cody Gray

The first example is using the System font (SYSTEM_FONT), as retrieved with the GetStockObjectfunction, which is a bitmap font that has not been used since the days of Windows 3. More information is available on Raymond Chen's blog, and Michael Kaplan's blog.

第一个示例是使用系统字体 ( SYSTEM_FONT),它是通过GetStockObject函数检索到的,这是一种自 Windows 3 时代以来就没有使用过的位图字体。更多信息可以在Raymond Chen 的博客Michael Kaplan 的博客上找到

The second example is using the "MS Shell Dlg" font, just like you asked it to. That actually maps to a font called "Microsoft Sans Serif" or "MS Sans Serif", the UI font back in the days of Windows 95 and 98. This is also known as DEFAULT_GUI_FONT, which indeed used to be an accurate name for it, but alas, it is accurate no longer.

第二个示例是使用“MS Shell Dlg”字体,就像您要求的那样。这实际上映射到一种名为“Microsoft Sans Serif”或“MS Sans Serif”的字体,这是 Windows 95 和 98 时代的 UI 字体。这也被称为DEFAULT_GUI_FONT,这确实曾经是它的准确名称,但是唉,它不再准确了。

Beginning with Windows 2000 (and continued in XP), Tahoma was used as the default UI font. This is what you are seeing in the third example: Tahoma 8 pt. Unfortunately, even on those operating systems, "MS Shell Dlg" does not return Tahoma--it still returns MS Sans Serif, which is why it looks wrong.

从 Windows 2000 开始(并在 XP 中继续),Tahoma 被用作默认的 UI 字体。这就是您在第三个示例中看到的内容:Tahoma 8 pt。不幸的是,即使在这些操作系统上,“MS Shell Dlg”也不返回 Tahoma——它仍然返回 MS Sans Serif,这就是它看起来错误的原因。

So, you could simply specify Tahoma as the GUI font, but that wouldn't really be correct, because it would break in older versions of the OS where Tahoma isn't installed or supported, or on foreign language versions of the operating system, where a different font is used out of necessity. Instead, you're supposed to specify the DS_SHELLFONTflag, which Raymond talks about here.

因此,您可以简单地将 Tahoma 指定为 GUI 字体,但这实际上并不正确,因为它会在未安装或支持 Tahoma 的旧版操作系统或外语版本的操作系统中中断,出于必要使用不同字体的地方。相反,您应该指定Raymond 在此处讨论DS_SHELLFONT标志。

And all was fine and good until Windows Vista came out. And in Windows Vista, the powers that be at Microsoft decided that Tahoma was getting a little long-in-the-tooth and Windows was due for another UI font upgrade. They developed their own special font in-house called Segoe UI, supposedly designed for optimum on-screen readability. And in a special little twist, they decided that the default size should now be 9 pt, instead of 8 pt as used by every previous version of the OS, regardless of the font face. And you would probablythink that either "MS Shell Dlg", "MS Shell Dlg2", or DS_SHELLFONT(or all three) would get you this new-fangled Segoe UI font, but you'd be wrong.

在 Windows Vista 出现之前,一切都很好。在 Windows Vista 中,Microsoft 的权力决定 Tahoma 有点老了,Windows 需要进行另一次 UI 字体升级。他们在内部开发了自己的特殊字体,称为Segoe UI,据称是为获得最佳屏幕可读性而设计的。在一个特殊的小转折中,他们决定默认大小现在应该是9 pt,而不是每个以前版本的操作系统使用的 8 pt ,无论字体如何。您可能认为“MS Shell Dlg”、“MS Shell Dlg2”或DS_SHELLFONT(或所有这三个)都会为您提供这种新颖的 Segoe UI 字体,但您错了。

Uh oh. Now things get tricky... Not only does Vista use a different font than XP that is not easily accessible with a one-size-fits-all identifier, but it also uses a different size, changing the way your dialog will look on those systems, if you can get it to display at all. In many, many places, the Windows shell team appeared to simply punt the challenge--Tahoma 8 pt is used all over the place, even with the Aero theme enabled, when it's supposed to be using Segoe UI 9 pt. This kind of thing really makes the UI look unpolished, and it was the subject of lots of nitpicking back in the early days of Vista. Now, it seems most people have forgotten about it, but the UI hasn't started looking any less scattered and inconsistent.

哦哦。现在事情变得棘手了... Vista 不仅使用了与 XP 不同的字体,这种字体不容易通过通用标识符访问,而且它还使用了不同的大小,改变了对话框在这些字体上的显示方式系统,如果你能让它显示出来。在很多很多地方,Windows shell 团队似乎只是简单地应对挑战——Tahoma 8 pt 被到处使用,即使启用了 Aero 主题,当它应该使用 Segoe UI 9 pt 时也是如此。这种东西确实让 UI 看起来很粗糙,而且在 Vista 的早期,它是很多吹毛求疵的主题。现在,似乎大多数人已经忘记了它,但 UI 并没有开始看起来不那么分散和不一致。

And you're not the Windows shell team: you can't get away with this in your own app. The Top Rules for the Windows Vista User Experienceeven state explicitly that you should always:

而且您不是 Windows shell 团队:您无法在自己的应用程序中摆脱这种情况。Windows Vista 用户体验主要规则甚至明确指出您应该始终:

  • Use Segoe UI, the new Windows Vista system font.
  • Respect the user's settings by always referencing the system font, sizes, and colors using the Windows Theme APIs. Don't use fixed values for fonts, sizes, or colors.
  • 使用 Segoe UI,新的 Windows Vista 系统字体。
  • 通过始终使用 Windows 主题 API 引用系统字体、大小和颜色来尊重用户的设置。不要对字体、大小或颜色使用固定值。

To be honest, I haven't really heard a goodsolution to this problem yet. And I suspect that by the time I ever do, no one will need to support Windows XP anymore (although most people aren't quitethere yet). But here's what I do: I extract the default system font at runtime using the SystemParametersInfofunction. Fortunately, the system message box font (lfMessageFont) is the correct font face and size, regardless of the current version of Windows and the user's chosen theme.

老实说,我还没有真正听说过这个问题的好的解决方案。我怀疑我通过曾经做的时候,没有人会需要支持Windows XP了(虽然大多数人都不是十分尚未)。但这是我所做的:我在运行时使用SystemParametersInfo函数提取默认系统字体。幸运的lfMessageFont是,无论当前版本的 Windows 和用户选择的主题如何,系统消息框字体 ( ) 都是正确的字体和大小。

My code to initialize windows or dialogs generally looks something like this (SystemInfo::IsVistaOrLateris a helper function I've written; the implementation is the obvious):

我初始化窗口或对话框的代码通常看起来像这样(这SystemInfo::IsVistaOrLater是我编写的辅助函数;实现是显而易见的):

// Get the system message box font
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(ncm);

// If we're compiling with the Vista SDK or later, the NONCLIENTMETRICS struct
// will be the wrong size for previous versions, so we need to adjust it.
#if(_MSC_VER >= 1500 && WINVER >= 0x0600)
if (!SystemInfo::IsVistaOrLater())
{
    // In versions of Windows prior to Vista, the iPaddedBorderWidth member
    // is not present, so we need to subtract its size from cbSize.
    ncm.cbSize -= sizeof(ncm.iPaddedBorderWidth);
}
#endif

SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
HFONT hDlgFont = CreateFontIndirect(&(ncm.lfMessageFont));

// Set the dialog to use the system message box font
SetFont(m_DlgFont, TRUE);
SendMessage(hWnd, WM_SETFONT, (WPARAM)hDlgFont, MAKELPARAM(FALSE, 0));

Or even easier in MFC, with the handy SendMessageToDescendantsmethod
(m_DlgFontis a CFontobject defined for the class):

或者在 MFC 中更容易,使用方便的SendMessageToDescendants方法
m_DlgFontCFont为类定义的对象):

// Get the system message box font
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(ncm);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
LOGFONT lfDlgFont = ncm.lfMessageFont;
m_DlgFont.CreateFontIndirect(&lfDlgFont);

// Set the dialog and all its controls to use the system message box font
SetFont(m_DlgFont, TRUE);
SendMessageToDescendants(WM_SETFONT, (WPARAM)m_DlgFont.m_hFont, MAKELPARAM(FALSE, 0), TRUE);

If you're not using MFC, I highly recommend implementing your own recursive version of SendMessageToDescendants. It makes the initialization code a lotsimpler.

如果您不使用 MFC,我强烈建议您实现自己的递归版本SendMessageToDescendants. 它使初始化代码产生很多简单。