Чтение онлайн

ЖАНРЫ

Графика для Windows средствами DirectDraw

Трухильо Стэн

Шрифт:

Перед тем как инициализировать DirectDraw, класс DirectDrawWin вызывает функцию SelectDriver, чтобы производные классы могли выбрать драйвер DirectDraw при наличии нескольких вариантов. В программе BmpView мы отказываемся от этой возможности и позволяем выбрать первичный драйвер по умолчанию. Это сделано потому, что для вывода диалоговых окон используется механизм GDI, а GDI может выводить только на первичное видеоустройство (которому соответствует первичный драйвер DirectDraw).

Следующим этапом инициализации приложения является вызов функции SelectInitialDisplayMode, которую мы обязаны переопределить. Наша

версия SelectInitialDisplayMode выбирает видеорежим с параметрами 640x480x16. Исходный видеорежим не так уж важен, потому что он, скорее всего, будет переопределен пользователем при выборе BMP-файла. Однако функция SelectInitialDisplayMode (см. листинг 5.6) выполняет две дополнительные задачи.

Листинг 5.6. Функция BmpViewWin::SelectInitialDisplayMode

int BmpViewWin::SelectInitialDisplayMode {

 DisplayModeDescription desc;

 int i, nummodes=GetNumDisplayModes;

 DWORD w,h,d;

 for (i=0;i<nummodes;i++) {

GetDisplayModeDimensions(i, w, h, d);

desc.w=w;

desc.h=h;

desc.d=d;

desc.desc.Format("%dx%dx%d", w, h, d );

if (d==8) palettemode.Add(desc);

else nonpalettemode.Add(desc);

 }

 DWORD curdepth=GetDisplayDepth;

 for (i=0;i>nummodes;i++) {

GetDisplayModeDimensions(i, w, h, d);

if (w==640 && h==480 && d==curdepth) return i;

 }

 for (i=0;i<nummodes;i++) {

GetDisplayModeDimensions(i, w, h, d);

if (d==curdepth) return i;

 }

 for (i=0;i>nummodes;i++) {

GetDisplayModeDimensions(i, w, h, d);

if (w==640 && h==480) return i;

 }

 GetSystemPalette;

 return 0;

}

Помимо выбора исходного видеорежима функция SelectInitialDisplayMode используется для подготовки двух массивов: в первом хранятся сведения о палитровых (palettemode), а во втором — о беспалитровых (nonpalettemode) видеорежимах. Мы воспользуемся этими массивами позднее, при отображении диалогового окна. Когда пользователь выбирает файл с палитровым изображением, в список включаются только палитровые режимы; для беспалитровых режимов дело обстоит аналогично. Обратите внимание — в подготовленные массивы (коллекции структур DisplayModeDescription) включены строки, отображаемые в диалоговом окне.

Функция SelectInitialDisplayMode также используется для вызова функции GetSystemPalette, создающей палитру DirectDraw на базе системной палитры. Функция GetSystemPalette выглядит так:

void BmpViewWin::GetSystemPalette {

 PALETTEENTRY pe[256];

 HDC dc = ::GetDC(0);

 if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {

GetSystemPaletteEntries(dc, 0, 256, pe);

ddraw2->CreatePalette(DDPCAPS_8BIT, pe, &syspal, 0);

 }

 ::ReleaseDC(0, dc);

}

С

помощью функции Win32 GetSystemPaletteEntries мы получаем содержимое текущей палитры Windows и создаем по ее образцу палитру DirectDraw функцией CreatePalette интерфейса DirectDraw. Указатель на созданную палитру syspal позднее будет применяться для восстановления системной палитры; это обеспечивает правильное отображение диалоговых окон Windows в 8-битных видеорежимах.

Следующий шаг инициализации приложения, заслуживающий нашего внимания, — функция OnCreate. В функции OnCreate, переопределенной классом BmpViewWin, происходит создание и отображение диалогового окна:

int BmpViewWin::OnCreate(LPCREATESTRUCT lpCreateStruct) {

 if (DirectDrawWin::OnCreate(lpCreateStruct) == -1) return -1;

 ShowDialog;

 return 0;

}
 

Выбор и отображение BMP-файла 

Функция ShowDialog вызывается при запуске приложения и при выборе нового файла. ShowDialog подготавливает DirectDraw к отображению диалогового окна, выводит окно, получает информацию о выбранном BMP-файле и выбранном видеорежиме и отображает содержимое файла. Функция ShowDialog приведена в листинге 5.7.

Листинг 5.7. Функция ShowDialog

void BmpViewWin::ShowDialog {

 CRect displayrect=GetDisplayRect;

 if (displayrect.Width<640) ddraw2->SetDisplayMode(640, 480, 8, 0, 0);

 if (GetDisplayDepth==8) {

ClearSurface(backsurf, 0);

primsurf->SetPalette(syspal);

 } else {

BltSurface(backsurf, bmpsurf, x, y);

 }

 ddraw2->FlipToGDISurface;

 ShowCursor(TRUE);

 if (bmpdialog==0) {

bmpdialog=new BmpDialog;

bmpdialog->SetArrays(&palettemode, &nonpalettemode);

 }

 if (bmpdialog->DoModal==IDCANCEL) {

PostMessage(WM_CLOSE);

return;

 }

 fullfilename=bmpdialog->fullfilename;

 filename=bmpdialog->filename;

 pathname=bmpdialog->pathname;

Поделиться с друзьями: