2015-07-03 6 views
1

пример:Новичок В MFC C++, почему контекст устройства должен создать старый указатель Font/Bitmap/etc, а затем selectObject() в конце?

void CMainWindow::OnPaint() 
{ 
    CRect rect; 
    GetClientRect (&rect); 

    CPaintDC dc (this); 
    dc.SetViewportOrg (rect.Width()/2, rect.Height()/2); 
    dc.SetBkMode (TRANSPARENT); 

    for (int i=0; i<3600; i+=150) { 
     LOGFONT lf; 
     ::ZeroMemory (&lf, sizeof (lf)); 
     lf.lfHeight = 160; 
     lf.lfWeight = FW_BOLD; 
     lf.lfEscapement = i; 
     lf.lfOrientation = i; 
     ::lstrcpy (lf.lfFaceName, _T ("Arial")); 

     CFont font; 
     font.CreatePointFontIndirect (&lf); 

     CFont* pOldFont = dc.SelectObject (&font); 
     dc.TextOut (0, 0, CString (_T ("   Hello, MFC"))); 

     //WHY THIS LINE? 
     dc.SelectObject (pOldFont); 
    } 
} 

код выводит «Hello, MFC» в окружности вокруг начала координат (который перемещается в центр окна).

Output

Почему этот указатель CFont создан, а затем постоянный ток выбирает его в качестве шрифта? Это просто хорошая практика программирования или действительно ли это приложение действительно нужно?

Я видел аналогичный код в Интернете, делающий это с помощью растровых изображений и других объектов контекста устройства. В чем цель?

Когда я удаляю последнюю строку кода, ничего не меняется. Заранее спасибо за помощь.

ответ

3

Device Context:

Контекст устройства представляет собой структуру, которая определяет набор графических объектов и связанных с ними атрибутов, а также графических режимов, которые влияют на выход. graphic objects включает ручку для рисования линии, кисть для рисования и наполнения, растровое изображение для копирования или прокрутки частей экрана, палитру для определения набора доступных цветов, область для обрезки и другие операции и путь для рисования и операции рисования.

В любое время, есть ровно один графический объект выбран в контекст устройства. Поскольку система сохраняет набор объектов по умолчанию в контексте устройства при его создании, приложение должно сохранить это состояние, когда контекст устройства возвращается в систему для очистки. Это то, что

dc.SelectObject (pOldFont); 

несет ответственность за.

Это требование документально под SelectObject:

Эта функция возвращает ранее выбранный объект указанного типа. Приложение должно всегда заменять новый объект исходным объектом по умолчанию после того, как он закончил рисование с помощью нового объекта.


Примечание: Это не относится к MFC, а скорее для Windows GDI. MFC просто реализует автоматическую обертку управления ресурсами. Для управления государством по-прежнему требуется явный код.

+0

Я смущен вашим объяснением. MFC имеет автоматическое управление ресурсами. Вы имеете в виду 'dc.SelectObject (pOldFont)' по-прежнему необходимо? –

+0

@Barmak: Строка кода, который вы цитируете, выполняет ** состояние ** управление. Это необходимо и для MFC. Я имел в виду управление ** resource **: вам не нужно вызывать 'DeleteObject' на объекте' font'; это делается для вас на днере. – IInspectable

+0

У меня большие проблемы, если это так. Я думал, что новым версиям MFC это не нужно. Я не восстанавливаю 'oldfont'. Я использую 'GetGuiResources (GetCurrentProcess(), GR_GDIOBJECTS)' для контроля дескрипторов GDI, он по-прежнему показывает нулевые утечки. «GDI-объекты» Taskmanager выглядят одинаково с восстановлением «oldfont» (тестирование Windows 8) или без него. Раньше я просматривал 'CDC :: SelectObject' и' CDC', и я заключил, что MFC автоматически восстанавливает 'oldfont'. Но теперь я снова посмотрел на него, я не уверен, что он делает. В любом случае, я буду использовать «SaveDC» и «RestoreDC». –

 Смежные вопросы

  • Нет связанных вопросов^_^