В первом примере используется системный шрифт (SYSTEM_FONT
), полученный с помощью функции GetStockObject
, которая является растровым шрифтом, который не использовался со времен Windows 3. Подробнееинформация доступна в блоге Раймонда Чена и блоге Майкла Каплана .
Во втором примере используется шрифт MS Shell Dlg ,как ты и просил.Это фактически соответствует шрифту, называемому «Microsoft Sans Serif» или «MS Sans Serif», шрифт пользовательского интерфейса еще во времена Windows 95 и 98. Он также известен как DEFAULT_GUI_FONT
, который действительно был точным именем дляэто, но увы, это уже не точно.
Начиная с Windows 2000 (и продолжая в XP), Tahoma использовался в качестве шрифта пользовательского интерфейса по умолчанию.Это то, что вы видите в третьем примере: Tahoma 8 pt.К сожалению, даже в этих операционных системах «MS Shell Dlg» не возвращает Tahoma - он по-прежнему возвращает MS Sans Serif, поэтому выглядит неправильно.
Таким образом, вы можете просто указать Tahoma в качестве шрифта GUI, но это не совсем правильно, потому что он сломается в старых версиях ОС, где Tahoma не установлена или не поддерживается, или на иностранных языкахверсии операционной системы, где другой шрифт используется по необходимости.Вместо этого вы должны указать флаг DS_SHELLFONT
, о котором Рэймонд говорит здесь .
И все было хорошо и хорошо, пока не вышла Windows Vista.А в Windows Vista все силы Microsoft решили, что Tahoma немного затрепетала, и Windows должна была еще одно обновление шрифта пользовательского интерфейса .Они разработали собственный специальный шрифт под названием Segoe UI , предположительно разработанный для оптимальной читаемости на экране.И в небольшом повороте они решили, что размер по умолчанию теперь должен составлять 9 пт вместо 8 пт, используемых в каждой предыдущей версии ОС, независимо от шрифта.И вы бы , вероятно думали, что либо "MS Shell Dlg", "MS Shell Dlg2", либо DS_SHELLFONT
(или все три) получат вам этот новомодный шрифт Segoe UI, но вы будетенеправильно.
Э-э-эТеперь все становится сложнее ... Мало того, что Vista использует другой шрифт, чем XP, который нелегко получить с помощью идентификатора "один размер подходит всем", но она также использует другой размер , изменяя способваш диалог будет выглядеть в этих системах, если вы вообще сможете его отобразить.Во многих, многих местах команда оболочки Windows, казалось, просто решала задачу - Tahoma 8 pt используется повсеместно , даже с включенной темой Aero, когда предполагается использовать Segoe UI 9пт.Подобные вещи действительно заставляют пользовательский интерфейс выглядеть безупречно, и это было предметом большого придирки в первые дни Vista.Похоже, что большинство людей об этом забыли, но пользовательский интерфейс не стал выглядеть менее рассеянным и непоследовательным.
И вы не команда оболочки Windows: вы не можете сойти с рук в этомваше собственное приложение. Основные правила для пользователей Windows Vista даже прямо заявляют, что вы всегда должны:
- Использовать пользовательский интерфейс Segoe, новый системный шрифт Windows Vista.
- Уважайте пользовательские настройки, всегда ссылаясь на системный шрифт, размеры и цвета с помощью API тем Windows.Не используйте фиксированные значения для шрифтов, размеров или цветов.
Если честно, я пока не слышал хорошего решения этой проблемы.И я подозреваю, что к тому времени, когда я это сделаю, никому больше не нужно будет поддерживать Windows XP (хотя большинство людей еще не вполне пока ).Но вот что я делаю: я извлекаю системный шрифт по умолчанию во время выполнения, используя SystemParametersInfo
функцию .К счастью, системный шрифт окна сообщения (lfMessageFont
) - это правильный шрифт и размер шрифта, независимо от текущей версии Windows и выбранной пользователем темы.
Мой код для инициализации окон или диалогов обычно выглядит примерно так (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
.Это упрощает код инициализации lot .