Поскольку DirectX предоставляет прямой доступ к аппаратуре, очень важен уровень кооперации устройства. Он определяет как программа может использовать данный ресурс совместно с другими приложениями. Если вы установите монопольный режим, больше никто не сможет воспользоваться данным ресурсом. Если вы установите совместный режим, то доступ к клавиатуре смогут получить все желающие. Уверен, вы можете вспомнить игры, которые не делят клавиатуру ни с кем. Мне на ум приходит EverQuest. Поскольку создатели игры не хотели, чтобы сторонние разработчики писали приложения для их игры, они заблокировали использование клавиатуры вне их программы. Это не слишком хорошо и может вызвать настоящие проблемы, если вы переключитесь из игры на другое приложение, чтобы проверить почту или сделать что-нибудь еще.
Для установки уровня кооперации применяется функция IDirectInputDevice8::SetCooperativeLevel(). Вот ее прототип:
HRESULT SetCooperativeLevel(
HWND hwnd,
DWORD dwFlags
);
В ее первом параметре, hwnd, передается дескриптор окна, которое будет связано с устройством. Я в этом параметре передаю дескриптор, который был возвращен мне при создании главного окна.
DISCL_BACKGROUND Доступ к клавиатуре будет предоставлен даже если окно свернуто.
DISCL_EXCLUSIVE Предоставляется монопольный доступ к клавиатуре, для всех остальных клавиатура недоступна.
DISCL_FOREGROUND Доступ к данным клавиатуры предоставляется только когда окно активно.
DISCL_NONEXCLUSIVE Устройство используется совместно с другими программами.
DISCL_NOWINKEY Блокирует клавишу Windows.
Для рассматриваемого примера я устанавливаю флаги уровня кооперации DISCL_NONEXCLUSIVE и DISCL_FOREGROUND. Благодаря этому программа использует клавиатуру совместно с другими приложениями, а сама может читать данные клавиатуры только когда ее окно активно.
Захват клавиатуры
Последний, относящийся к DirectX этап — вызов функции IDirectInputDevice8::Acquire(). Эта функция необходима для привязки приложения к используемому им устройству ввода. Всякий раз когда окно теряет фокус клавиатура должна быть захвачена снова.
Раскладка клавиатуры
В рассматриваемом примере я покажу вам как считывать коды клавиш DirectInput и ASCII-коды клавиш. Чтобы получить возможность преобразования кодов DIK в коды ASCII вы должны вызвать функцию GetKeyboardLayout(). Она получает раскладку подключенной к системе клавиатуры для дальнейшего использования.