下面的图片(放大,所以你最好看到差异)显示dynamic创build的编辑控件(上面的两个例子)和从对话框编辑器(下面的例子)创build的编辑控件之间的字体差异。 我怎样才能使我的dynamic创buildCEdit控件的字体看起来像默认(下面的例子)?
我已经创build了如下的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"));
谢谢你的帮助!
第一个例子是使用系统字体( SYSTEM_FONT
),与GetStockObject
函数一起检索,这是一种从Windows 3开始就没有使用过的位图字体。更多的信息可以在Raymond Chen的博客和Michael Kaplan的博客上找到 。
第二个例子是使用“MS Shell Dlg”字体 ,就像你问的那样。 这实际上映射到一个称为“Microsoft Sans Serif”或“MS Sans Serif”的字体,即在Windows 95和98时代的UI字体。这也被称为DEFAULT_GUI_FONT
,它确实是一个准确的名称,但唉,不再是准确的了。
从Windows 2000开始(在XP中继续),Tahoma被用作默认UI字体。 这就是你在第三个例子中看到的:Tahoma 8 pt。 不幸的是,即使在这些操作系统上,“MS Shell Dlg”也不会返回Tahoma – 它仍然会返回MS Sans Serif,这就是为什么它看起来不对。
因此,您可以简单地指定Tahoma作为GUI字体,但这并不是真的,因为它会在未安装或支持Tahoma的操作系统的旧版本或操作系统的外语版本中打破,在不必要的情况下使用不同的字体。 相反,你应该指定Raymond在这里所说的DS_SHELLFONT
标志。
一切都很好,直到Windows Vista出来。 而在Windows Vista中,微软的权力决定了Tahoma变得有点琐碎,而Windows则是由于另一个UI字体的升级 。 他们开发了自己的内部称为Segoe UI的特殊字体,据称是为了获得最佳的屏幕可读性而设计的。 而在一个特别的小转折,他们决定,现在的默认大小应该是9磅 ,而不是每个以前版本的操作系统使用的8磅,无论字体。 你可能会认为无论是“MS Shell Dlg”,“MS Shell Dlg2”还是DS_SHELLFONT
(或者全部三个)都会为你带来这个新的Segoe UI字体,但是你会错的。
呃哦。 现在,事情变得棘手…… Vista不仅使用与XP不同的字体,而且使用一种通用标识符不易访问,但它也使用不同的大小 ,改变对话框的外观系统,如果你能得到它显示在所有。 在许多地方,Windows shell团队似乎只是为了挑战这个挑战 – 即使启用了Aero主题,Tahoma 8 pt也被使用,当时它应该使用Segoe UI 9 pt。 这样的事情真的让UI看起来不够清爽,而且在Vista的早期,这是很多挑剔的主题。 现在,似乎大多数人都已经忘记了这一点,但是用户界面并没有开始显得更加分散和不一致。
而且你不是Windows外壳团队:你不能在自己的应用程序中脱身。 Windows Vista用户体验的最高规则甚至明确规定您应该始终:
- 使用新的Windows Vista系统字体Segoe UI。
- 通过始终使用Windows Theme API引用系统字体,大小和颜色来尊重用户的设置。 不要为字体,大小或颜色使用固定值。
说实话,我还没有真正听到这个问题的一个很好的解决方案。 我怀疑,到目前为止,没有人会需要支持Windows XP(尽管大多数人还没有到那里)。 但是这是我做的:我使用SystemParametersInfo
函数在运行时提取默认的系统字体。 幸运的是,不管当前版本的Windows和用户选择的主题,系统消息框字体( lfMessageFont
)都是正确的字体和大小。
我初始化窗口或对话框的代码通常看起来像这样( 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));
在MFC中,使用方便的SendMessageToDescendants
方法甚至更简单
( m_DlgFont
是为类定义的CFont
对象):
// 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);
如果你不使用MFC,我强烈建议你实现你自己的递归版本的SendMessageToDescendants
。 它使初始化代码简单得多。