#mfc #fonts
#mfc #шрифты
Вопрос:
У меня есть класс CListCtrl, который я хотел бы иметь возможность легко изменять размер шрифта. Я подкласс CListCtrl как MyListControl. Я могу успешно установить шрифт, используя этот код в обработчике событий PreSubclassWindow:
void MyListControl::PreSubclassWindow()
{
CListCtrl::PreSubclassWindow();
// from http://support.microsoft.com/kb/85518
LOGFONT lf; // Used to create the CFont.
memset(amp;lf, 0, sizeof(LOGFONT)); // Clear out structure.
lf.lfHeight = 20; // Request a 20-pixel-high font
strcpy(lf.lfFaceName, "Arial"); // with face name "Arial".
font_.CreateFontIndirect(amp;lf); // Create the font.
// Use the font to paint a control.
SetFont(amp;font_);
}
Это работает. Однако то, что я хотел бы сделать, это создать метод с именем SetFontSize(int size), который просто изменит существующий размер шрифта (оставив лицо и другие характеристики как есть). Поэтому я считаю, что для этого метода потребуется получить существующий шрифт, а затем изменить размер шрифта, но мои попытки сделать это не увенчались успехом (это убивает мою программу):
void MyListControl::SetFontSize(int pixelHeight)
{
LOGFONT lf; // Used to create the CFont.
CFont *currentFont = GetFont();
currentFont->GetLogFont(amp;lf);
LOGFONT lfNew = lf;
lfNew.lfHeight = pixelHeight; // Request a 20-pixel-high font
font_.CreateFontIndirect(amp;lf); // Create the font.
// Use the font to paint a control.
SetFont(amp;font_);
}
Как я могу создать этот метод?
Комментарии:
1. Каким образом это «убивает» вашу программу?
2. Существует ошибка mfc ASSERT, которая завершается с ошибкой.
Ответ №1:
Я нашел рабочее решение. Я открыт для предложений по улучшению:
void MyListControl::SetFontSize(int pixelHeight)
{
// from http://support.microsoft.com/kb/85518
LOGFONT lf; // Used to create the CFont.
CFont *currentFont = GetFont();
currentFont->GetLogFont(amp;lf);
lf.lfHeight = pixelHeight;
font_.DeleteObject();
font_.CreateFontIndirect(amp;lf); // Create the font.
// Use the font to paint a control.
SetFont(amp;font_);
}
Два ключа к тому, чтобы заставить это работать, были:
- Удаление копии шрифта журнала, lfNew.
- Вызов
font_.DeleteObject();
перед созданием нового шрифта. По-видимому, уже не может быть существующего объекта шрифта. В коде MFC есть некоторое УТВЕРЖДЕНИЕ, которое проверяет наличие существующего указателя. Это УТВЕРЖДЕНИЕ является причиной сбоя моего кода.
Комментарии:
1. Что такое font_ ? Это не объявлено.
2. font_ имеет тип CFont и является переменной-членом моего класса MyListControl .
3. font_. DeleteObject() — это реальная экономия времени. В wingdi.cpp примерно в строке 1113, которая проверяет наличие существующего прикрепленного объекта.