Подтвердить что ты не робот

Какой шрифт является стандартным для MFC Dialog Controls?

Рисунок ниже (увеличенный, чтобы вы лучше различили различия) показывает различия шрифта между динамически создаваемыми элементами управления Edit (два верхних примера) и Edit Controls, созданные из Редактора диалоговых окон (нижний пример). Как я могу сделать шрифт моих динамически созданных элементов управления CEdit похожим на значение по умолчанию (нижний пример)?

enter image description here

Я создал элементы управления 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"));

Спасибо за вашу помощь!

4b9b3361

Ответ 1

В первом примере используется системный шрифт (SYSTEM_FONT), полученный с помощью функции GetStockObject, которая является растровым шрифтом который не использовался со времен Windows 3. Дополнительная информация доступна на блог Raymond Chen и Блог Майкла Каплана.

Во втором примере используется шрифт "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 pt, вместо 8 pt, используемого каждой предыдущей версией ОС, независимо от лица шрифта. И вы, вероятно, подумали бы, что либо "MS Shell Dlg", "MS Shell Dlg2", либо DS_SHELLFONT (или все три) предоставят вам этот шрифт с новым шрифтом Segoe UI, но вы ошибаетесь.

О, о. Теперь все становится сложно... Не только Vista использует другой шрифт, чем XP, который нелегко доступен с идентификатором одного размера для всех, но он также использует другой размер, меняя как ваш диалог будет выглядеть в этих системах, если вы можете его отобразить вообще. Во многих и многих местах команда оболочки Windows, похоже, просто пыталась решить проблему - Tahoma 8 pt используется повсеместно, даже с включенной темой Aero, когда предполагается использовать Segoe UI 9 pt. Подобная вещь действительно делает пользовательский интерфейс неполированным, и это было предметом многократного поиска в первые дни Vista. Теперь, похоже, большинство людей забыли об этом, но пользовательский интерфейс не стал выглядеть менее рассеянным и непоследовательным.

И вы не команда оболочки Windows: вы не можете уйти от этого в своем приложении. Верхние правила для пользователя Windows Vista даже явно указывают, что вы всегда должны:

  • Используйте пользовательский интерфейс Segoe, новый системный шрифт Windows Vista.
  • Уважайте пользовательские настройки, всегда ссылаясь на системный шрифт, размеры и цвета с помощью API-интерфейсов Windows. Не используйте фиксированные значения для шрифтов, размеров или цветов.

Честно говоря, я пока не слышал хорошего решения этой проблемы. И я подозреваю, что к тому моменту, когда я когда-либо это сделаю, никто больше не будет нуждаться в поддержке Windows XP (хотя большинство людей еще не совсем там). Но вот что я делаю: я извлекаю системный шрифт по умолчанию во время выполнения с помощью SystemParametersInfo function. К счастью, шрифт окна системного сообщения (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. Это делает код инициализации намного проще.