Вход/Регистрация
Графика для Windows средствами DirectDraw
вернуться

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

Шрифт:

 return TRUE;

}

Функция InitMouse состоит из семи этапов:

1. Инициализация устройства DirectInput, которое представляет мышь.

2. Выбор формата данных, получаемых от мыши.

3. Установка уровня кооперации для мыши.

4. Инициализация буфера данных мыши.

5. Создание двух объектов CEvent.

6. Инициализация механизма оповещений DirectInput.

7. Создание потока ввода.

На этапах 1-4 происходит нормальная инициализация DirectInput, подробно рассмотренная в главе 6, поэтому основное внимание будет уделено этапам 5, 6 и 7.

На этапе 5 создаются два динамических объекта CEvent, а полученные указатели сохраняются в маленьком массиве. Положение этих указателей в массиве определяется константами mouse_event_index и quit_event_index (которые равны 0 и 1 соответственно). Первое событие блокирует или активизирует поток ввода в зависимости от того, поступили ли от мыши новые данные. Второе событие сообщает потоку мыши о завершении приложения. Как мы вскоре увидим, указатели сохраняются в массиве для того, чтобы мы могли заблокировать поток мыши по двум событиям одновременно.

На этапе 6 функция SetEventNotification интерфейса DirectInputDevice приказывает DirectInput устанавливать событие мыши при появлении новых данных. Функция SetEventNotification получает один аргумент типа HANDLE, однако наш объект CEvent наследует оператор преобразования типа от класса CSyncObject, благодаря чему мы можем использовать объект CEvent так, словно он имеет тип HANDLE (тип HANDLE, в частности, используется потоковым API Win32 для представления событий).

На этапе 7 создается поток ввода от мыши. Я снова приведу соответствующий фрагмент листинга 7.2:

mousethread=AfxBeginThread((AFX_THREADPROC)MouseThread, this, THREAD_PRIORITY_TIME_CRITICAL, 0, CREATE_SUSPENDED);

Существуют и другие способы создания потоков, но функция AfxBeginThread является самым простым вариантом. Она получает шесть аргументов, однако последние четыре имеют значения по умолчанию, так что обязательными являются лишь два аргумента. В нашем случае передается пять аргументов.

Первый аргумент AfxBeginThread — указатель на функцию, выполняемую новым потоком; в нашем случае используется функция MouseThread. Второй аргумент — значение, которое передается функции потока при вызове. Мы передаем указатель this, чтобы функция MouseThread могла обращаться к членам нашего класса.

Третий аргумент — приоритет потока. По умолчанию для потока устанавливается нормальный приоритет (флаг THREAD_PRIORITY_NORMAL), но мы переопределяем его и задаем флаг THREAD_PRIORITY_TIME_CRITICAL, чтобы добиться наискорейшего отклика курсора.

Четвертый аргумент — размер стека для нового потока. Ноль означает, что размер стека выбирается по умолчанию. Пятый и последний аргумент определяет исходное состояние потока. Если он равен нулю, создается активный поток; в нашем случае использован флаг CREATE_SUSPENDED, чтобы создавался приостановленный поток.

На создании потока ввода работа функции InitMouse заканчивается. Благодаря флагу CREATE_SUSPENDED поток ввода приостанавливается до момента, когда основной поток завершит инициализацию DirectDraw. Затем, перед возвратом из функции OnCreate, поток ввода активизируется функцией ResumeThread (см. листинг 7.2).

Функция DrawScene 

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

Листинг 7.4. Функция DrawScene

void CursorWin::DrawScene {

 //------ Проверить клавишу ESCAPE -------

 static char key[256];

 keyboard->GetDeviceState(sizeof(key), &key);

 if (key[DIK_ESCAPE] & 0x80) PostMessage(WM_CLOSE);

 //------ Обычные задачи ------

 ClearSurface(backsurf, 0);

 BltSurface(backsurf, dm_surf, 539, 0);

 static coil_idx;

 BltSurface(backsurf, coil[coil_idx], coilx, coily);

  • Читать дальше
  • 1
  • ...
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: