DirectDrawCreate(0, &ddraw1, 0);

 ddraw1->QueryInterface(IID_IDirectDraw2, (void**)&ddraw2);  ddraw1->Release(), ddraw1=0;  ddraw2->SetCooperativeLevel (GetSafeHwnd(), DDSCL_NORMAL);

 DetectDisplayMode();

 if (CreateFlippingSurfaces()==FALSE) {

  AfxMessageBox('CreateFlippingSurfaces() failed');

  return FALSE;

 }

 if (CreateCustomSurfaces()==FALSE) {

  AfxMessageBox('CreateCustomSurfaces() failed');

  return FALSE;

 }

 return 0;

}

Сначала указатель на интерфейс DirectDraw(ddraw1) инициализируется функцией DirectDrawCreate(). Указатель ddraw1, как и в полноэкранной версии, используется только для получения указателя на интерфейс DirectDraw2, после чего освобождается.

Затем функция OnCreate() вызывает функцию SetCooperativeLevel(). В полноэкранном приложении уровень кооперации определялся тремя флагами: DDSCL_EXCLUSIVE, DDSCL_FULLSCREEN и DDSCL_ALLOWMODEX. В данном случае используется только флаг DDSCL_NORMAL.

Функция DetectDisplayMode() инициализирует некоторые переменные класса DirectDrawWin. Она выглядит так:

BOOL DirectDrawWin::DetectDisplayMode() {

 DDSURFACEDESC desc;

 ZeroMemory(&desc, sizeof(desc));

 desc.dwSize=sizeof(desc);

 if (ddraw2->GetDisplayMode(&desc)!=DD_OK) {

  TRACE('GetDisplayMode() failed ');

  return FALSE;

 }

 displayrect.left=0;

 displayrect.top=0;

 displayrect.right=desc.dwWidth;

 displayrect.bottom=desc.dwHeight;

 displaydepth=desc.ddpfPixelFormat.dwRGBBitCount;

 return TRUE;

}

Функция DetectDisplayMode() с помощью функции GetDisplayMode() интерфейса DirectDraw получает информацию о текущем видеорежиме Windows. Говоря точнее, разрешение экрана и глубина пикселей текущего видеорежима сохраняются в переменных displayrect и displaydepth.

Далее OnCreate() вызывает функцию CreateFlippingSurfaces(). Хотя оконное приложение не может выполнять настоящего переключения страниц (как можно было бы решить, исходя из имени функции), имя было сохранено, потому что создаваемые в ней поверхности эмулируют переключение страниц. Код функции приведен в листинге 3.4.

Листинг 3.4. Функция CreateFlippingSurfaces() в оконном приложении

BOOL DirectDrawWin::CreateFlippingSurfaces() {

 HRESULT r;

 DDSURFACEDESC desc;

 desc.dwSize = sizeof(desc);

 desc.dwFlags = DDSD_CAPS;

 desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

 r=ddraw2->CreateSurface(&desc, &primsurf, 0);

 if (r!=DD_OK) {

  TRACE('FAILED to create 'primsurf' ');

  return FALSE;

 }

 r=ddraw2->CreateClipper(0, &clipper, 0);

 if (r!=DD_OK) {

  TRACE('CreateClipper() failed ');

  return FALSE;

 }

 r=clipper->SetHWnd(0, GetSafeHwnd());

 if (r!=DD_OK) {

  TRACE('SetHWnd() failed ');

  return FALSE;

 }

 r=primsurf->SetClipper(clipper);

 if (r!=DD_OK) {

  TRACE('SetClipper() failed ');

  return FALSE;

 }

 ZeroMemory(&desc, sizeof(desc));

 desc.dwSize = sizeof(desc);

 desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;

 desc.dwWidth = displayrect.Width();

 desc.dwHeight = displayrect.Height();

 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;

 r=ddraw2->CreateSurface(&desc, &backsurf, 0);

 if (r!=DD_OK) {

  TRACE('failed to create 'backsurf' in video ');

  videobacksurf=FALSE;

 } else {

  TRACE('Created backsurf in video ');

  videobacksurf=TRUE;

 }

 return TRUE;

}

Сначала мы создаем первичную поверхность. В полноэкранном варианте код выглядит по-другому, потому что здесь создается обычная, несоставная первичная поверхность. В структуре DDSURFACEDESC мы описываем первичную поверхность, используя только флаг DDSCAPS_PRIMARYSURFACE. Затем описанная поверхность создается функцией CreateSurface() интерфейса DirectDraw.

Далее функция CreateClipper() интерфейса DirectDraw создает объект отсечения. CreateClipper() получает три аргумента, однако первый и последний из них чаще всего равны нулю. Второй аргумент представляет собой адрес указателя на интерфейс DirectDrawClipper. В нашем случае используется переменная класса DirectDrawWin с именем clipper.

Объект отсечения нужен для ограничения вывода в программе. Поскольку наше приложение работает в окне, которое находится на рабочем столе вместе с другими окнами, при обновлении изображения необходимо учитывать присутствие этих окон. Чтобы объект отсечения автоматически выполнял свою работу, его необходимо присоединить к окну функцией SetHWnd() интерфейса DirectDrawClipper. Функция SetHWnd() получает два аргумента — двойное слово (DWORD), которое зарезервировано для будущего использования и

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату