Графика для Windows средствами DirectDraw
Шрифт:
Функция Acquire вызывается для каждого устройства независимо от того, уступалось ли оно. DirectInput игнорирует лишние вызовы Acquire.
Хлопоты с инициализацией мыши и клавиатуры закончены, теперь можно получать от них данные. Функция DrawScene (см. листинг 6.6) через указатели mouse и keyboard обращается к обоим устройствам и получает от них данные.
Листинг 6.6.
Функция DrawScene сначала проверяет состояние клавиатуры функцией GetDeviceState интерфейса DirectInputDevice. Если была нажата клавиша Escape, она посылает сообщение WM_CLOSE, что приводит к завершению приложения. О функции GetDeviceState и проверке состояния клавиш рассказано в программе Qwerty, поэтому сейчас мы займемся кодом, относящимся к мыши. DrawScene в цикле извлекает элементы буфера мыши. Для получения данных, а также для проверки отсутствия элементов при пустом буфере используется функция GetDeviceData интерфейса DirectInputDevice.
Каждый элемент буфера представлен структурой DIDEVICEOBJECTDATA. Эта структура используется независимо от типа устройства, поэтому ее поля были сделаны универсальными. DirectInput определяет структуру DIDEVICEOBJECTDATA следующим образом:
Для мыши поле dwOfs определяет тип события. В DirectInput определены следующие константы, описывающие ввод от мыши:
• DIMOFS_X
• DIMOFS_Y
• DIMOFS_Z
• DIMOFS_BUTTON0
• DIMOFS_BUTTON1
• DIMOFS_BUTTON2
• DIMOFS_BUTTON3
Программа Smear
Поле dwData определяет новые значения осевых координат и кнопок. Поскольку мы используем относительные значения, содержимое этого поля равно смещению по данной оси с момента получения последних данных. Следовательно, оно может быть и отрицательным. Поле dwData используется для обновления переменных x и y.
Поля dwTimeStamp и dwSequence содержат информацию о том, когда произошло данное событие. Поле dwTimeStamp определяет время в миллисекундах (о том, как интерпретируется эта величина, можно подробно узнать в описании функции Win32 GetTickCount). Поле dwSequence определяет порядок наступления событий. События с меньшими номерами наступили раньше, однако несколько событий могут иметь одинаковые порядковые номера. Например, если мышь или рукоять джойстика смещается по диагонали, события для координат x и y будут иметь одинаковые номера.
Вернемся к функции DrawScene. Цикл ввода извлекает элементы буфера до тех пор, пока буфер не опустеет. Этот цикл выглядит так:
Третий аргумент GetDeviceData используется двояко. Значение, передаваемое функции, определяет количество элементов, извлекаемых из буфера. В нашем случае используется всего одна структура DIDEVICEOBJECTDATA, поэтому передается число 1. При возврате из функции это значение показывает количество полученных элементов.
Если вызов функции прошел успешно и значение elements осталось равным 1, значит, элемент буфера был прочитан, а поля dwOfs и dwData определяют тип события. Нулевое значение elements говорит о том, что буфер пуст и цикл завершается.
После извлечения всех элементов буфера остается лишь вывести поверхность в позиции, определяемой переменными x и y. Для этого используется функция BltSurface: