Changing dialog font in MFC
Редактор диалогов Visual Studio позволяет задать базовый шрифт для диалога.
По умолчанию, это MS Shell Dlg
8-го размера. А что, если я хочу выставить Segoe UI
? Точнее, что будет на системах, где этого шрифта физически нет? Не известно.
Уже понятно, что сию беду нужно, как обычно, писать в коде. Ниже - два универсальных способа решить проблему.
Способ 1
У класса CDialog
имеется следующая функция-член: virtual BOOL CreateIndirect(LPCDLGTEMPLATE, CWnd*, void*); Создание любого диалога проходит через нее, поэтому для изменения шрифта в шаблоне диалога это очень подходящее место. В результате - создаем класс-потомок CDialog
, переопределяем CreateIndirect
, меняем шрифт, вызываем базовый метод. Недостаток этого подхода - все классы диалогов нужно будет наследовать от него. Вариант подходит для нового кода, а если в проекте уже 120 диалогов - что делать?
Способ 2
Хак, а как же еще?
class CFontOccManager : public COccManager { virtual const DLGTEMPLATE *PreCreateDialog(_AFX_OCC_DIALOG_INFO *pOccDialogInfo, const DLGTEMPLATE *pOrigTemplate) { const DLGTEMPLATE *lpNewTemplate = __super::PreCreateDialog(pOccDialogInfo, pOrigTemplate); OSVERSIONINFO osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); if ((osvi.dwMajorVersion >= 6) && !pOccDialogInfo->m_pNewTemplate) { CDialogTemplate dlgTemplate(lpNewTemplate); CString origFontFaceName; WORD wOrigFontSize; dlgTemplate.GetFont(origFontFaceName, wOrigFontSize); NONCLIENTMETRICS ncm; ncm.cbSize = sizeof(NONCLIENTMETRICS); SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0); LOGFONT lf = ncm.lfMessageFont; HDC hDC = ::GetDC(NULL); const int logPixelSY = ::GetDeviceCaps(hDC, LOGPIXELSY); ::ReleaseDC(NULL, hDC); const WORD wProposedFontSize = static_cast<WORD>(MulDiv(-lf.lfHeight, 72, logPixelSY)); dlgTemplate.SetFont(lf.lfFaceName, max(wOrigFontSize, wProposedFontSize)); pOccDialogInfo->m_pNewTemplate = reinterpret_cast<DLGTEMPLATE*>(dlgTemplate.Detach()); return(pOccDialogInfo->m_pNewTemplate); } else return(lpNewTemplate); } }; AfxEnableControlContainer(new CFontOccManager());
Класс COccManager
не документирован, но создание диалога проходит в том числе через него. Логика простая:
- проверить версию Windows (наличие шрифта
Segoe UI
); - получить метрики экрана;
- выбрать нужный набор метрик и посчитать размер шрифта;
- поменять шрифт в шаблоне диалога.
В качестве метрик я взял характеристики lfMessageFont
- LOGFONT structure that contains information about the font used in message boxes
. Message box - это же диалог, остальное не подходит. Код простой, объяснений не требует. Единственный нюанс, я беру максимум из старого размера и посчитанного.
В результате - нормального размера диалоги с обалденным шрифтом. Удачи.
1 коммент.:
Hello, Neat post. There is a problem along with your website in internet explorer, would check this?
IE still is the market leader and a big portion of folks will leave out your magnificent
writing because of this problem.
Feel free to surf my blog post GFI Norte
Отправить комментарий