Кроме опроса устройств существует и альтернативный вариант — оповещение (notification). В этом случае программный поток (thread) блокируется и ожидает поступления оповещающего события. С наступлением такого события поток автоматически активизируется. Оповещение позволяет приложению реагировать на изменения в состоянии устройства ввода без расходов процессорного времени, связанных с опросом.
Для однопоточных приложений оповещение используется редко, потому что во время ожидания события поток блокируется и не может ничего делать. Если только вся работа приложения не сводится к получению ввода от пользователя, для оповещения потребуется по крайней мере два потока. В программах этой главы оповещение не используется, однако мы встретимся с ним в главе 7.
Уровни кооперации
Чтобы приложение могло задать нужную степень контроля над устройством, в DirectInput используются уровни кооперации. DirectInput, как и DirectDraw, позволяет установить монопольный (exclusive) и совместный (nonexclusive) режим доступа для каждого устройства. Если приложение DirectInput обладает монопольным доступом к устройству ввода, то никакое другое приложение заведомо не сможет получить монопольного доступа к тому же устройству (хотя сможет получить совместный доступ).
DirectInput также позволяет задать уровень кооперации для активного (foreground) и фонового (background) режимов работы — эти два термина часто приводят к недоразумениям. Активный доступ (foreground access) означает, что приложение работает с устройством только тогда, когда обладает фокусом ввода (по аналогии с тем, как ввод с клавиатуры по умолчанию передается приложению, обладающему фокусом). Фоновый доступ (background access) означает, что приложение может обращаться к устройству независимо от того, обладает ли оно фокусом ввода. Интуитивно кажется, будто активный доступ обладает большими возможностями, но на самом деле это не так. В программах Qwerty и Smear используется совместный активный уровень кооперации.
Данные об осевых смещениях
Устройство, возвращающее информацию об осевых смещениях (например, мышь или джойстик), можно настроить так, чтобы оно возвращало относительные или абсолютные данные. Относительные осевые смещения описывают перемещение по данной оси по отношению к предыдущему положению, а абсолютные — текущую позицию по данной оси.
По умолчанию мышь возвращает относительные данные, а джойстик — абсолютные. В программе Smear для мыши используется установка по умолчанию, однако следует помнить о том, что тип данных можно изменить как для джойстика, так и для мыши.
Захват устройств
Приложение DirectDraw в случае необходимости может уступить видеопамять другому приложению и восстановить ее, когда исходное приложение снова получит фокус. В DirectInput приложение тоже может потерять устройство и восстановить контроль над ним перед тем, как продолжить работу. В таких случаях говорят, что приложение захватывает устройство (acquire) или уступает его (unacquire). Для получения данных необходимо захватить устройство. Приложение может уступить устройство по требованию (доступ к устройству передается Windows или другому приложению) или автоматически (например, если DirectInput отбирает право доступа к устройству, чтобы передать его другому приложению).
Некоторые устройства (особенно клавиатуры и мыши) регулярно захватываются и уступаются приложениями. Обычно они уступаются автоматически в тот момент, когда приложение теряет фокус. Когда ваше приложение опять получает фокус, оно должно снова захватить устройство.
До выхода DirectX 3 библиотека DirectInput была построена на существующих функциях Win32 и не поддерживала ввода с клавиатуры или от мыши. В DirectX 3 появились COM-интерфейсы для клавиатуры и мыши, но все остальные устройства продолжали зависеть от функций Win32 (и особенно от функции joyGetPosEx()). В DirectX 5 зависимость DirectInput от Win32 полностью устранена, а все устройства ввода переведены на использование COM-интерфейсов. Работа с устройствами ввода реализована через три интерфейса:
• DirectInput
• DirectInputDevice
• DirectInputEffect
Первичным, или главным, является интерфейс DirectInput. Создание его экземпляра приводит к инициализации библиотеки, а все остальные интерфейсы DirectInput могут быть инициализированы лишь с помощью его функций.
Интерфейс DirectInputDeviceпредставляет устройство ввода. Его функции выполняют инициализацию, настройку, захват и отпускание устройств. Что еще важнее, DirectInputDeviceсодержит функции для получения данных от устройства.
Читать дальше