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

Класс AviPlayWin


Большинство возможностей программы AviPlay обеспечивается классом AviPlayWin, который наследует поддержку DirectDraw от класса DirectDrawWin. В отличие от других программ этой книги класс AviPlayWin

использует диалоговое окно для выбора файла. Вместо того чтобы создавать поверхности при запуске, программа AviPlay (как и программа BmpView из главы 5) ожидает, пока пользователь выберет файл. Затем программа создает поверхности и настраивает их в соответствии с содержимым выбранного файла. Определение класса AviPlayWin приведено в листинге 8.1.

Листинг 8.1. Класс AviPlayWin


class AviPlayWin : public DirectDrawWin { public: AviPlayWin(); protected: //{{AFX_MSG(AviPlayWin) afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); afx_msg void OnRButtonDown(UINT nFlags, CPoint point); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnDestroy(); //}}AFX_MSG DECLARE_MESSAGE_MAP() private: int SelectInitialDisplayMode(); BOOL CreateCustomSurfaces() { return TRUE; } void DrawScene(); void RestoreSurfaces(); void GetSystemPalette(); void ShowDialog(); BOOL LoadAvi(); BOOL CreateAviSurface(); BOOL UpdateAviSurface(); BOOL InstallPalette(); private: AviDialog* avidialog;

CString fullfilename; CString filename; CString pathname;

CRect displayrect; LPDIRECTDRAWSURFACE avisurf; CRect avirect; int x,y; DisplayModeArray displaymode;

LPDIRECTDRAWPALETTE syspal; LPDIRECTDRAWPALETTE avipal;

PAVISTREAM avistream; AVISTREAMINFO streaminfo; HIC decomp; long fmtlen, buflen; long startframe, endframe; long curframe; LPBITMAPINFOHEADER srcfmt; LPBITMAPINFOHEADER dstfmt; BYTE* rawdata; BYTE* finaldata; };


Сначала мы объявляем конструктор класса AviPlayWin, предназначенный только для инициализации переменных класса.

В классе определены четыре обработчика сообщений: OnKeyDown(), OnRButtonDown(), OnCreate() и OnDestroy(). Функция OnKeyDown() следит за нажатием клавиш Escape

и пробела во время воспроизведения, прерывает ролик и отображает диалоговое окно для выбора AVI-файла (мы могли воспользоваться DirectInput, но программа AviPlay не стоит подобных хлопот).
Функция OnRButtonDown() тоже вызывает диалоговое окно для выбора AVI-файла, но по щелчку правой кнопки мыши. Функция OnCreate() инициализирует DirectDraw и AVI, а функция OnDestroy() завершает их работу.

Затем мы объявляем 10 закрытых (private) функций. Первой идет функция SelectInitialDisplayMode(), которая выполняет три задачи: выбор исходного видеорежима (то, для чего предназначена сама функция), построение списка 8-битных режимов для диалогового окна и захват системной палитры. Вскоре мы рассмотрим эту функцию. Функция GetSystemPalette() вызывается функцией SelectInitialDisplayMode(); мы увидим, как она работает, при знакомстве с последней.

Функция CreateCustomSurfaces() объявлена встроенной (inline). Она всего лишь возвращает TRUE, потому что при запуске приложения поверхности не создаются.

Следующая функция, ShowDialog(), отображает диалоговое окно и в случае выбора допустимого AVI-файла загружает его функцией LoadAvi(). Основная часть функциональных возможностей программы обеспечивается этими двумя функциями, поэтому мы рассмотрим их подробно.

За функций LoadAvi() объявляется функция DrawScene(). Мы воспользуется ею для вывода кадров видеоролика. Помимо извлечения и восстановления кадров видеопотока DrawScene() осуществляет блиттинг и переключение страниц, необходимые для отображения кадра.

Функция RestoreSurfaces()

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

Функции CreateAviSurface() и UpdateAviSurface()

отвечают за создание и обновление поверхности AVI. Размеры поверхности AVI определяются размерами кадров AVI-файла, выбранного пользователем, поэтому при каждом открытии нового AVI-файла создается новая поверхность AVI. Функция UpdateAviSurface() готовит поверхность AVI к отображению, копируя выходные данные функции ICDecompress() в память поверхности.

Последней объявлена функция InstallPalette(), которая устанавливает палитру AVI перед началом воспроизведения ролика.Однако перед этим она должна извлечь данные палитры из потока AVI.

Оставшаяся часть класса содержит лишь переменные. Мы познакомимся с ними во время рассмотрения программы.


Содержание раздела