Microsoft DirectX 8.0 (C++) |
Microsoft® DirectInput® デバイスの取得とは、アプリケーションにデバイスへのアクセスをさせることである。デバイスが取得されている限り、DirectInput は、アプリケーションがデバイスのデータを使用できるようにする。デバイスが取得されていない場合、デバイスの特性に対する操作はできるが、データは一切取得できない。
取得は永続するものではない。アプリケーションは、デバイスを何回でも取得し、解放することがある。
協調レベルによっては、アプリケーションがバックグラウンドに移行すると必ず自動的にデバイスが解放されることがある。マウスの場合、ユーザーがメニューをクリックすると自動的に解放される。クリックした時点で Microsoft Windows® がデバイスの制御を引き継ぐからである。
デバイス プロパティの変更に先立って、そのデバイスを解放する必要がある。唯一の例外として、フォース フィードバック デバイスは、取得状態にあってもゲインを変更できる。
取得の仕組みが必要な理由は、次の 2 つである。
第 1 に、DirectInput は、デバイスからのデータの流れがシステムにより中断されたときには、アプリケーションに通知できなければならない。たとえば、ユーザーが Alt+Tab を使用して別のアプリケーションに切り替え、切り替え後のアプリケーションで入力デバイスを使用した場合に、元のアプリケーションは、入力デバイスがもはや自身に属さず、バッファ状態が変化した可能性があることを知る必要がある。DISCL_FOREGROUND 協調レベルでのアプリケーションを観察してみよう。ユーザーが Shift キーを押しながら別のアプリケーションに切り替える。その後、ユーザーは Shift キーを離し、元のアプリケーションに戻る。元のアプリケーションからみれば、Shift キーは依然として押されている状態である。取得の仕組みでは、元のアプリケーションに入力が終了したことを通知して、この状態から回復させることができる。
第 2 に、アプリケーションがデバイスのプロパティを変更できるので、保護がなければユーザーがデータを取得しようとするたびに、DirectInput がプロパティをチェックしなければならなくなる。これは、かなり非効率であろう。さらに悪いことには、バッファ サイズを変更している最中に、データ バッファにアクセスするハードウェア割り込みなど、事故が発生する可能性がある。そうした理由で、DirectInput は、プロパティを変更する前に、アプリケーションに対してデバイスを解放するように要求する。デバイスを再取得すると、DirectInput はプロパティを確認して、デバイスからアプリケーションへの最適なデータ転送の方法を決定する。この処理は一度しか行われないので、データ取得の各メソッドを非常に高速にすることができる。
デバイスを喪失する最も一般的な原因は、アプリケーションがバックグラウンドに移行することである。したがって、アプリケーションがアクティブになったときには常に、デバイスを再取得することが必要になる。しかし、起動時の WM_ACTIVATE ハンドラに依存するには注意が必要である。最初の WM_ACTIVATE メッセージが到着するのは、おそらくウィンドウの初期化中で、DirectInput のセットアップ前である。起動時にデバイスを確実に取得するには、デバイスが初期化されたらすぐに IDirectInputDevice8::Acquire を呼び出すようにする。
特に標準のキーボードやマウス以外のデバイスの場合、プログラム ウィンドウがアクティブになったときにデバイスを取得しても、デバイスが解放されるすべてのケースに対応できるとは限らない。アプリケーションがデバイスを不意に解放する場合もあるので、デバイスからデータを取得しようとする前に、取得状態を確認する仕組みが必要である。Scrawl サンプル アプリケーションでは、Scrawl_OnMouseInput 関数でこの確認を行っている。この関数では、DIERR_INPUTLOST エラーが、マウスを再取得するメッセージのトリガになる(詳細については、「チュートリアル 2 : マウスの使い方」を参照すること)。
取得済みのデバイスを再取得しようとしても、害はまったくない。Acquire に対する冗長な呼び出しは無視され、デバイスは常時 Unacquire を 1 回呼び出すことで解放することができる。
Windows は、アプリケーションがマウスを排他モードで使用しているときは、マウスにアクセスしない。Windows にマウスを取得させたければ、マウスを解放しなければならない。Scrawl サンプルでは、右ボタンのクリックに反応するために、マウスを解放し、Windows カーソルを同じ点に表示し、ショートカット メニューを表示し、メニュー選択が行われるまで Windows が入力を処理するようにしている。