Восстановление поверхностей
Наше приложение благополучно инициализируется и выводит графические данные. Теперь необходимо справиться с возможной потерей поверхностей. При рассмотрении функции DirectDrawWin::PreDrawSceneмы видели, что DirectDrawWinвызывает виртуальную функцию RestoreSurfaces(), чтобы производный класс получил возможность восстановить потерянные поверхности. Функция RestoreSurfaces()отвечает за восстановление как потерянной памяти поверхности, так и ее содержимого. Функция BounceWin::RestoreSurfaces()выглядит так:
void BounceWin::RestoreSurfaces() {
if (surf1->IsLost()==FALSE) return;
CString filename;
if (GetCurDisplayDepth()==8) filename="tri08.bmp";
else filename="tri24.bmp";
surf1->Restore();
LoadSurface(surf1, filename);
}
DirectDraw может отнимать у неактивного приложения только поверхности, находящиеся в видеопамяти, так что нет смысла в восстановлении поверхностей из системной памяти. Поэтому RestoreSurfaces()сначала проверяет, была ли потеряна единственная вспомогательная поверхность нашего приложения, и если нет — функция прекращает работу. Если же поверхность была потеряна, мы восстанавливаем ее память функцией Restore(), а содержимое — функцией LoadSurface().
Завершение
Как бы ни была хороша программа Bounce, рано или поздно вам захочется убрать ее с экрана. Нажатие клавиши Escapeзавершает работу программы. Это происходит в обработчике OnKeyDown():
void bounceWin::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
if (nChar==VK_ESCAPE) PostMessage(WM_CLOSE);
DirectDrawWin::OnKeyDown(nChar, nRepCnt, nFlags);
}
Приложение завершает работу, отправляя сообщение WM_CLOSE. В нашем приложении на это сообщение реагирует и класс окна, и класс приложения. Класс окна отвечает сообщением WM_DESTROY, для которого в DirectDrawWinпредусмотрен обработчик OnDestroy(). Класс DirectDrawWinв данном обработчике освобождает объекты DirectDraw и всю память, занимаемую приложением. Функция OnDestroy()выглядит так:
void DirectDrawWin::OnDestroy() {
if (primsurf) primsurf->Release(), primsurf=0;
if (palette) palette->Release(), palette=0;
if (ddraw2) ddraw2->Release(), ddraw2=0;
for (int i=0;i
if (driver[i].guid) delete[] driver[i].guid;
free(driver[i].desc);
free(driver[i].name);
}
}
}
Каждый из указателей на интерфейсы DirectDraw сначала освобождается, а затем обнуляется. Затем мы освобождаем память, занятую информацией о драйверах DirectDraw.
Класс приложения обрабатывает завершение в функции ExitInstance(), в которой удаляется класс окна:
int DirectDrawApp::ExitInstance() {
delete ddwin;
return CWinApp::ExitInstance();
}
На этом наше знакомство с программой Bounce заканчивается. Однако до сих пор речь шла только о полноэкранных приложениях. Оставшаяся часть этой главы посвящена оконным приложениям.
Наверное, вы уже поняли, что полноэкранным приложениям в этой книге уделяется особое внимание. Все программы на CD-ROM работают в полноэкранном режиме, и в этой главе до настоящего момента все внимание было сосредоточено исключительно на полноэкранных приложениях.
Дело в том, что книга посвящена быстродействующим графическим Windows-приложениям, а оконные приложения не обеспечивают оптимального быстродействия. Для полноты картины мы рассмотрим оконные приложения, но не так подробно, как полноэкранные. Впрочем, если вы захотите поддерживать оконный режим в своих приложениях, не все потеряно. Многие описанные приемы, реализованные в полноэкранных приложениях, в равной степени относятся и к оконным.
В начале этой главы мы воспользовались DirectDraw AppWizard и создали приложение Bounce. При этом мы указали, что создаваемая программа должна быть полноэкранной. Чтобы получить рассматриваемый ниже код, следует снова запустить AppWizard и выбрать оконное приложение.
Структура приложения
По своей структуре оконная версия приложения Bounce почти не отличается от полноэкранной. Как и прежде, классы DirectDrawWinи DirectDrawAppорганизуют поддержку DirectDraw и используются в качестве базовых для классов, относящихся к конкретным приложениям.
Инициализация
В полноэкранном варианте класса DirectDrawWinфункция OnCreate()инициализирует DirectDraw за несколько этапов. Оконный вариант выглядит проще, потому что ему не приходится перечислять драйверы DirectDraw или видеорежимы. Оконная версия функции OnCreate()выглядит так:
Читать дальше