Отображение модельного мира выполняется в три этапа. На первом этапе при помощи функции ClearActi vePage(hdcMem) очищается поверхность рисования, как это показано в листинге 16.4.
Листинг 16.4
void ClearActivePageCHDC hdcMem) {
SaveDC(hdcMem):
SelectObject(hdcMem.hFon);
BitBltC hdcMem.O.O.r.right.r.bottom.NULL.200 .200. PATCOPY):
RestoreDC(hdcMem.-l):
}
Контекст памяти содержит кисть для рисования тележки. Перед отображением фона контекст сохраняется в стеке, в контекст заносится кисть hFon, при помощи функции BitBlt( ) поверхность очищается, а затем контекст восстанавливается.
На втором этапе объекты рисуются в контексте памяти при помощи функции RenderObjects(hdcMem). Все объекты модельного мира принято связывать в список или древовидную структуру. Для отображения мира выполняется цикл просмотра списка или рекурсивная функция обхода дерева и у каждого объекта запускается функция отображения текущего состояния. В данном проекте присутствуют
Контекст памяти и двойная буферизация
только три объекта и каждый из них рисуется отдельным оператором, как показано в листинге 16.5.
Листинг 16.5
void Render-Wheel(HDC hdc. int xC.int yC);
void RenderObjects(HDC hdcMem )
{
SetBrushOrgEx(hdcMem.xC.yC.NULL);
//Привязка линий штриховки к движущемуся объекту
Rectanglе(hdcMem.хС-1/2.yC-3*1/2.хС+7*1/2.уС):
RotateWheel(hdcMem.xC.yC.О);
RotateWheel(hdcMem.хС+3*1.yC.О):
}
Если в этой функции удалить вызов SetBrushOrgEx( ), то при движении тележки линии штриховки останутся неподвижными. От этого возникает ощущение, что прозрачное окно движется над неподвижной разлинованной поверхностью. Указанная функция привязывает базовую точку кисти к точке объекта (хС ,уС).
На третьем этапе, когда рисунок полностью подготовлен, он копируется в видеобуфер, как показано в листинге 16.6.
Листинг 16.6
void FlipPagesCHWND hWnd.HDC hdcMem.RECT r) {
HDC hdc - GetDC(hWnd);
Bi tBlt(hdc.О.О.г.ri ght.r.bottom.hdcMem.0.0.SRCCOPY);
ReleaseDC(hWnd.hdc);
}
Заключительные операции, такие как уничтожение кистей, битовой карты и контекста памяти, вызываются перед закрытием приложения из функции Fi ni sh ( ), как показано в листинге 16.7.