Графика для Windows средствами DirectDraw
Шрифт:
Первый аргумент AfxBeginThread — указатель на функцию, выполняемую новым потоком; в нашем случае используется функция MouseThread. Второй аргумент — значение, которое передается функции потока при вызове. Мы передаем указатель this, чтобы функция MouseThread могла обращаться к членам нашего класса.
Третий аргумент — приоритет потока. По умолчанию для потока устанавливается нормальный приоритет (флаг THREAD_PRIORITY_NORMAL), но мы переопределяем его и задаем флаг THREAD_PRIORITY_TIME_CRITICAL,
Четвертый аргумент — размер стека для нового потока. Ноль означает, что размер стека выбирается по умолчанию. Пятый и последний аргумент определяет исходное состояние потока. Если он равен нулю, создается активный поток; в нашем случае использован флаг CREATE_SUSPENDED, чтобы создавался приостановленный поток.
На создании потока ввода работа функции InitMouse заканчивается. Благодаря флагу CREATE_SUSPENDED поток ввода приостанавливается до момента, когда основной поток завершит инициализацию DirectDraw. Затем, перед возвратом из функции OnCreate, поток ввода активизируется функцией ResumeThread (см. листинг 7.2).
Функция DrawScene отвечает за подготовку нового кадра во вторичном буфере, обновление курсора и переключение страниц. Функция DrawScene выполняется в основном потоке, поэтому она должна синхронизировать доступ к первичной поверхности и очереди событий мыши с потоком ввода. Функция DrawScene приведена в листинге 7.4.
Листинг 7.4. Функция DrawScene
Функция DrawScene состоит из семи этапов:
1. Проверка клавиши Escape.
2. Подготовка нового кадра во вторичном буфере.
3. Обновление курсора (также во вторичном буфере).
4. Переключение страниц.
5. Проверка очереди событий мыши.
6. Проверка очереди событий мыши.
7. Обновление поверхности меню задержки.
Первый этап выполняется функцией GetDeviceState интерфейса DirectInputDevice. Если будет обнаружено нажатие клавиши Escape, функция посылает сообщение WM_CLOSE, сигнализируя о завершении приложения.
Подготовка вторичного буфера (этап 2) включает его стирание и последующее копирование в него внеэкранной поверхности. Для перебора поверхностей из массива coil используется статическая целая переменная (массив coil подготавливается функцией CustomSurfaces, которую мы не рассматриваем).