伝統的なキーボードやマウス以外にも入力装置はたくさんあります。
例えば、ジョイスティック、タッチパネル、マイクなどは、柔軟性の高い入力装置です。
それらの機器のことを ヒューマン インターフェイス機器 (HID) と呼びます。
直接入力関数を使えば、キーボードやマウスも含めて、どんな HID からでも、強固で安定した入力の受けとりができます。
この節にある記事は……
直接入力形式
これまでは、データの入力と言ったら、キーボードとマウスでした。
システムは機器特有の細かい情報を削った上で、それらの機器から届く情報を翻訳してきました。
例えば、キーボードなら機器特有のスキャン
コードを生成しますが、アプリケーションがシステムから受けとるのは、スキャンコードではなく、仮想キーコードといった具合です。
直接入力の細かい情報を隠せはしますが、ウィンドウの管理機構が新しい HID すべてに対応しているというわけではありません。
未対応の HID から情報を得るには、アプリケーションがいろんな処理をしなければなりませんでした。
その機器を開いたり、共有状態を管理したり、定期的に機器から情報を取得したり、入出力のポートを設定したりです。
直接入力形式とその関数が開発された理由は、あらゆる入力機器からの直接入力をもっと簡単に操作できるようにするためです。
その対象には、キーボードとマウスも入っています。
直接入力形式は、これまでのキーボードとマウス用のマイクロソフト ウィンドウズの入力形式とはまったく別のものです。
これまでの形式では、アプリケーションが受けとる通知は機器非依存でした。
アプリケーションのウィンドウに送信される
WM_CHAR(英語)、
WM_MOUSEMOVE(英語)、
WM_APPCOMMAND(英語) などです。
それとは対照的に、直接入力では、まずデータを取得したい入力機器を登録しなければなりません。
登録すると
WM_INPUT(英語) 通知で直接入力を受けとることになります。
直接入力形式の利点は……
-
アプリケーションが入力機器を検出したり開く必要がありません。
-
アプリケーションは、機器から直接情報を取得でき、必要なデータを処理できます。
-
アプリケーションは、入力源を特定できます。
たとえ同じ機器の種類が複数あったとしてもです。
例えば、二つのマウスでも区別できます。
-
アプリケーションは、データを指定して、ある機器の集合か、特定の種類の機器からだけデータの流通量を管理します。
-
市場に新しく登場した HID 機器でも、通知の種類が増えるまで待ったり WM_APPCOMMAND に新しい命令が加わった新しい OS
を待つまでもなく、すぐに利用可能になります。
WM_APPCOMMAND は、いくつかの HID 機器に対応していることに注意してください。
ただし WM_INPUT は機器特有の低レベルの情報を直接送信しますが WM_APPCOMMAND は機器非依存の高レベル入力イベントです。
直接入力の登録
規定では、直接入力を受けとるアプリケーションはありません。
ある機器から直接入力を受けとるには、その機器を登録する必要があります。
機器を登録するには、まず
RAWINPUTDEVICE 構造体(英語)の配列を用意して、情報が欲しい機器の TLC (最高レベルの集合、top level
collection) を指定してください。
TLC は、UsagePage (機器のクラス) と Usage (クラス内の機器) で決まります。
例えば、キーボードの TLC を取得するには UsagePage = 1、Usage = 6 に設定してください。
(訳注: Usage 表は翻訳時点では http://www.usb.org/developers/hidpage/#Usage_Tables
にあります。)
RegisterRawInputDevices 関数(英語)を呼びだして、その機器を登録してください。
システムに接続されていない機器でも、アプリケーションが登録できることに注意してください。
その機器が接続されると、ウィンドウ管理機構が自動的にアプリケーションに直接入力を送ってきます。
システム上にある直接入力機器の一覧を取得するには
GetRawInputDeviceList 関数(英語)を呼びだしてください。
その呼びだしで得られた hDevice を
GetRawInputDeviceInfo 関数(英語)に渡すと、その機器の情報を取得できます。
RAWINPUTDEVICE の dwFlags メンバで、列挙したい装置と飛ばしたい装置を選べます。
例えば、留守番電話以外の電話すべてからの入力を要求できます。
コード例は 直接入力の登録 を参照してください。
マウスとキーボードが同じ HID を持つことに注意してください。
HID 通知の WM_INPUT からも、伝統的な通知からも、情報が来ます。
RAWINPUTDEVICE のフラグを適切に設定すれば、どちらからの通知にするか選べます。
アプリケーションの登録状況を取得するには
GetRegisteredRawInputDevices 関数(英語)を呼びだしてください。
いつでも使えます。
直接入力の読みとり
アプリケーションは、登録した TLC と一致するどの HID からでも直接入力を受けとることになります。
アプリケーションが直接入力を受けとれるようになると、通知の処理待ち行列に WM_INPUT 通知が入って、行列の状態フラグには
QS_RAWINPUT (QS_INPUT は QS_RAWINPUT も入っています)が設定されます。
アプリケーションが前面にある時でも、後面にある時でもデータは受けとれます。
(訳注: 「受けとれる」というのは、「通知が来る」という意味ではなく、このあとの記述にある関数で受けとれるという意味です。)
直接データの読みとりには二つの方法があります。
非蓄積(標準)型と蓄積型です。
非蓄積型は、たいていの HID には十分な方法で、直接データを一度に
RAWINPUT 構造体(英語)へ一つ取得することになります。
アプリケーションが
GetMessage 関数(英語)を呼びだして WM_INPUT 通知を取得したとします。
次に
GetRawInputData 関数(英語)に WM_INPUT で渡された RAWINPUT ハンドルを渡します。
例については 直接入力の標準の読みとり を参照してください。
一方、蓄積型では RAWINPUT 構造体の配列を取得します。
この方法は、入力情報を多く生成する機器用です。
この方法では
GetRawInputBuffer 関数(英語)を呼びだして RAWINPUT 構造体の配列を取得することになります。
RAWINPUT 構造体の配列を見ていくには
NEXTRAWINPUTBLOCK マクロ(英語)を使う必要があることに注意してください。
例については 直接入力の蓄積型の読みとり を参照してください。
直接入力を解釈するには、その HID の詳しい情報が必要となります。
アプリケーションは GetRawInputDeviceInfo 関数に機器のハンドルを渡して、その機器の情報を取得することになります。
その関数に渡すハンドルは WM_INPUT で渡されたものか
RAWINPUTHEADER.hDevice(英語)を使うことになります。