Графика для Windows средствами DirectDraw | страница 58
Нам остается рассмотреть лишь функцию GetSurfaceDimensions(), которая получает указатель на поверхность и возвращает ее ширину и высоту. Код этой функции выглядит так:
>BOOL DirectDrawWin::GetSurfaceDimensions(LPDIRECTDRAWSURFACE surf, DWORD& w, DWORD& h) {
> if (surf==0) return FALSE;
> DDSURFACEDESC desc;
> ZeroMemory(&desc, sizeof(desc));
> desc.dwSize=sizeof(desc);
> desc.dwFlags=DDSD_WIDTH | DDSD_HEIGHT;
> if (surf->GetSurfaceDesc(&desc)!=DD_OK) return FALSE;
> w=desc.dwWidth;
> h=desc.dwHeight;
> return TRUE;
>}
После проверки указателя мы подготавливаем экземпляр структуры DDSURFACEDESC. Нас интересуют ширина и высота поверхности, поэтому в поле dwFlags заносятся флаги DDSD_WIDTH и DDSD_HEIGHT.
Затем мы вызываем функцию GetSurfaceDesc() интерфейса DirectDrawSurface и передаем ей указатель на структуру с описанием поверхности. Функция GetSurfaceDesc() сохраняет размеры поверхности в полях dwWidth и dwHeight. Они присваиваются переданным по ссылке переменным w и h типа DWORD, после чего функция завершается.
Все рассмотренные функции встречаются в демонстрационных программах этой книги, однако вы вовсе не обязаны пользоваться ими. Впрочем, независимо от этого вам будет полезно познакомиться с их реализацией.
Графический вывод
Приложение Bounce прошло стадию инициализации, и теперь все готово к графическому выводу. Однако сначала мы посмотрим, как в классах DirectDrawWin и DirectDrawApp организуется обновление кадров.
Класс CWinApp, базовый для DirectDrawApp, содержит виртуальную функцию OnIdle(), которая вызывается при отсутствии необработанных сообщений. Поскольку эта функция автоматически вызывается во время пассивной работы приложения, она хорошо подходит для обновления изображения на экране. Функция DirectDrawApp::OnIdle() выглядит так:
>BOOL DirectDrawApp::OnIdle(LONG) {
> if (ddwin->PreDrawScene()) ddwin->DrawScene();
> return TRUE;
>}
Функция OnIdle() вызывает функцию DirectDrawWin::PreDrawScene() и в зависимости от полученного результата вызывает функцию DrawScene(). Функция OnIdle() всегда возвращает TRUE, потому что при возврате FALSE MFC перестает ее вызывать. Функция PreDrawScene() реализована так:
>BOOL DirectDrawWin::PreDrawScene() {
> if (window_active && primsurf->IsLost()) {
> HRESULT r;
> r=primsurf->Restore();
> if (r!=DD_OK) TRACE("can't restore primsurf\n");
> r=backsurf->Restore();
> if (r!=DD_OK) TRACE("can't restore backsurf\n");
> RestoreSurfaces();
> }
> return window_active;
>}
Функция