}

 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;

 int index=bmpdialog->GetIndex();

 DWORD w,h,d;

 if (bmpdialog->FilePalettized()) {

  w=palettemode[index].w;

  h=palettemode[index].h;

  d=palettemode[index].d;

 } else {

  w=nonpalettemode[index].w;

  h=nonpalettemode[index].h;

  d=nonpalettemode[index].d;

 }

 if (GetDisplayDepth()==8) primsurf->SetPalette(palette);

 ActivateDisplayMode(GetDisplayModeIndex(w, h, d));

 LoadBmp();

 ShowCursor(FALSE);

}

Функция ShowDialog() прежде всего проверяет, что текущий видеорежим имеет разрешение не менее 640×480. Из обсуждения функции SelectInitialDisplayMode() нам известно, что при инициализации приложения это условие заведомо выполняется, однако функция ShowDialog() также вызывается при каждом отображении BMP-файла. Если в данный момент установлен режим низкого разрешения, то перед тем, как продолжать, мы переходим в режим 640×480×8. Это обусловлено тем, что режимы низкого разрешения часто являются режимами Mode X, а GDI в таких режимах не может правильно отображать диалоговые окна.

Далее мы готовимся к отображению диалогового окна. Для палитровых режимов мы очищаем вторичный буфер и устанавливаем сохраненную ранее системную палитру, не пытаясь выводить диалоговое окно вместе с текущим изображением. Для беспалитровых режимов текущее изображение копируется на вторичный буфер и выводится за диалоговым окном.

СОВЕТ

Диалоговое окно и изображение

Чтобы организовать совместный вывод текущего изображения и диалогового окна в палитровом видеорежиме, вам придется сократить 256 элементов палитры изображения до 236, добавить новые цвета в середину палитры (системные цвета занимают по 10 элементов в начале и в конце палитры) и пересчитать пиксели изображения в соответствии с внесенными изменениями. Обычно это ведет к снижению качества изображения, но присутствие диалогового окна все равно отвлекает внимание пользователя. Чтобы восстановить прежнее изображение, необходимо сохранить предыдущие варианты изображения и палитры.

Вызов функции FlipToGDISurface() гарантирует, что вывод GDI будет присутствовать на экране. Кроме того, мы включаем курсор мыши (отключенный при запуске приложения классом DirectDrawWin), чтобы для работы с диалоговым окном можно было пользоваться мышью.

Далее мы создаем экземпляр класса BmpDialog, если он не был создан ранее. Класс-оболочка BmpDialog создается ClassWizard, он предназначен для отображения диалогового окна и работы с ним. Класс содержит код для работы с управляющими элементами окна и реакции на действия пользователя. Код класса BmpDialog здесь не рассматривается, так как он не имеет никакого отношения к DirectDraw.

Обратите внимание: при создании диалогового окна мы вызываем функцию SetArrays() и передаем ей массивы palettemode и nonpalettemode в качестве аргументов. Эта функция передает диалоговому окну информацию о

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

0

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

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