問題描述
下圖(放大,以便您更好地看到差異)顯示了動態創建的編輯控件(上面的兩個示例)和從對話框編輯器創建的編輯控件(下面的示例)之間的字體差異.如何使動態創建的 CEdit 控件的字體看起來像默認的(下例)?
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 控件,如下所示:
I have created the CEdit Controls like following:
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 以來就沒有使用過.更多信息可在 RaymondChen 的博客,以及 Michael Kaplan 的博客.
The first example is using the System font (SYSTEM_FONT
), as retrieved with the GetStockObject
function, 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.
第二個例子是使用 "MS Shell Dlg" 字體,就像您要求的那樣.這實際上映射到一種名為Microsoft Sans Serif"或MS Sans Serif"的字體,這是 Windows 95 和 98 時代的 UI 字體.這也稱為 DEFAULT_GUI_FONT
,它確實用于為它取一個準確的名字,但唉,它不再準確了.
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.
從 Windows 2000 開始(并在 XP 中繼續),Tahoma 被用作默認的 UI 字體.這就是您在第三個示例中看到的:Tahoma 8 pt.不幸的是,即使在這些操作系統上,MS Shell Dlg"也不返回 Tahoma——它仍然返回 MS Sans Serif,這就是它看起來錯誤的原因.
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.
因此,您可以簡單地將 Tahoma 指定為 GUI 字體,但這實際上并不正確,因為它會在未安裝或支持 Tahoma 的舊版操作系統或外語版本的操作系統中中斷操作系統,其中出于需要使用不同的字體.相反,您應該指定 DS_SHELLFONT
標志,該標志 雷蒙德在這里談論.
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_SHELLFONT
flag, which Raymond talks about here.
在 Windows Vista 出現之前,一切都很好.在 Windows Vista 中,Microsoft 的權力決定 Tahoma 有點老了,而 Windows 應該是 另一個 UI 字體升級.他們在內部開發了自己的特殊字體,稱為 Segoe UI,據稱專為優化屏幕顯示而設計可讀性.在一個特別的小變化中,他們決定默認大小現在應該是 9 pt,而不是每個以前版本的操作系統使用的 8 pt,無論字體如何.而且您可能認為MS Shell Dlg"、MS Shell Dlg2"或DS_SHELLFONT
(或所有三個)都會為您提供這種新穎的 Segoe UI 字體,但你錯了.
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 probably think 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.
哦哦.現在事情變得棘手了……Vis??ta 不僅使用了與 XP 不同的字體,這種字體不容易通過通用標識符訪問,而且它還使用了不同的大小,從而改變了你的對話框在這些系統上的顯示方式,如果你能讓它顯示的話.在很多很多地方,Windows shell 團隊似乎只是簡單地放棄了挑戰——Tahoma 8 pt 被到處使用,即使啟用了 Aero 主題,當它應該使用 Segoe UI 時9 點這種東西確實讓 UI 看起來很粗糙,而且在 Vista 的早期,它是很多吹毛求疵的主題.現在,似乎大多數人已經忘記了它,但 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.
而且您不是 Windows shell 團隊:您無法在自己的應用程序中擺脫這種情況.TopWindows Vista 用戶體驗規則甚至明確指出您應該始終:
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 Experience even state explicitly that you should always:
- 使用新的 Windows Vista 系統字體 Segoe UI.
- 通過始終使用 Windows 主題 API 引用系統字體、大小和顏色來尊重用戶的設置.不要對字體、大小或顏色使用固定值.
老實說,我還沒有真正聽說過這個問題的好的解決方案.而且我懷疑到我這樣做的時候,沒有人將需要支持 Windows XP(盡管大多數人還沒有完全).但這是我所做的:我在運行時使用 SystemParametersInfo
函數.幸運的是,無論當前版本的 Windows 和用戶選擇的主題如何,系統消息框字體 (lfMessageFont
) 都是正確的字體和大小.
To be honest, I haven't really heard a good solution 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 quite there yet). But here's what I do: I extract the default system font at runtime using the SystemParametersInfo
function. 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.
我的初始化窗口或對話框的代碼通常看起來像這樣(SystemInfo::IsVistaOrLater
是我編寫的輔助函數;實現是顯而易見的):
My code to initialize windows or dialogs generally looks something like this (SystemInfo::IsVistaOrLater
is a helper function I've written; the implementation is the obvious):
// 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
對象):
Or even easier in MFC, with the handy SendMessageToDescendants
method
(m_DlgFont
is a CFont
object defined for the class):
// 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
遞歸版本.它使初始化代碼很多更簡單.
If you're not using MFC, I highly recommend implementing your own recursive version of SendMessageToDescendants
. It makes the initialization code a lot simpler.
這篇關于哪種字體是 MFC 對話框控件的默認字體?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!