Platform SDK: DirectX

デバイスの取得

DirectInput デバイスの取得とは、アプリケーションにデバイスへのアクセスをさせることである。デバイスが取得されている限り、DirectInput は、アプリケーションがデバイスのデータを使用できるようにする。デバイスが取得されていない場合、デバイスの特性に対する操作はできるが、データは一切取得できない。

取得は永続するものではない。アプリケーションは、デバイスを何回でも取得し、解放することができる。

協調レベルによっては、アプリケーションがバックグラウンドに移行すると必ず自動的にデバイスが解放されることがある。マウスの場合、ユーザーがメニューをクリックすると自動的に解放される。クリックした時点で Windows がデバイスの制御を引き継ぐからである。

デバイス プロパティの変更に先立って、そのデバイスを解放する必要がある。唯一の例外として、フォース フィードバック デバイスは、取得状態にあってもゲインを変更できる。

取得の仕組みが必要な理由は、次の 2 つである。

第一に、DirectInput は、デバイスからのデータの流れがシステムにより中断されたときには、アプリケーションに通知できなければならない。たとえば、ユーザーが Alt+Tab を使用して別のアプリケーションに切り替え、切り替え後のアプリケーションで入力デバイスを使用した場合に、元のアプリケーションは、入力デバイスがもはや自身に属さず、バッファ状態が変化した可能性があることを知る必要がある。DISCL_FOREGROUND 協調レベルでのアプリケーションを観察してみよう。ユーザーが Shift キーを押す。Shift キーを押し続けている間に、別のアプリケーションに切り替える。その後、ユーザーは Shift キーを離し、元のアプリケーションに戻る。元のアプリケーションからみれば、Shift キーは依然として押されている状態である。取得の仕組みでは、元のアプリケーションに入力が終了したことを通知して、この状態から回復させることができる。

第二に、アプリケーションがデバイスのプロパティを変更できるので、保護がなければユーザーがデータを取得しようとするたびに、DirectInput がプロパティをチェックしなければならなくなる。これは、かなり非効率であろう。さらに悪いことには、バッファ サイズを変更している最中に、データ バッファにアクセスするハードウェア割り込みが発生する可能性がある。そうした理由で、DirectInput は、プロパティを変更する前に、アプリケーションに対してデバイスを解放するように要求する。デバイスを再取得すると、DirectInput はプロパティを確認して、デバイスからアプリケーションへの最適なデータ転送の方法を決定する。この処理は一度しか行われないので、データ取得の各メソッドを非常に高速にすることができる。

[C++]

デバイスを喪失する最も一般的な原因は、アプリケーションがバックグラウンドに移行することである。したがって、アプリケーションがアクティブになったときには常に、デバイスを再取得することが必要になる。しかし、起動時の WM_ACTIVATE ハンドラに依存するには注意が必要である。最初の WM_ACTIVATE メッセージが到着するのは、おそらくウィンドウの初期化中で、DirectInput のセットアップ前である。起動時にデバイスを確実に取得するには、デバイスが初期化されたらすぐに IDirectInputDevice7::Acquire を呼び出すようにする。

特に標準のキーボードやマウス以外のデバイスの場合、プログラム ウィンドウがアクティブになったときにデバイスを取得しても、デバイスが解放されるすべてのケースに対応できるとは限らない。アプリケーションがデバイスを不意に解放する場合もあるので、デバイスからデータを取得しようとする前に、取得状態を確認する仕組みが必要である。Scrawl サンプル アプリケーションでは、Scrawl_OnMouseInput 関数でこの確認を行っている。この関数では、DIERR_INPUTLOST エラーが、マウスを再取得するメッセージのトリガになる(「チュートリアル 2 : マウスの使用」も参照すること)。

[Visual Basic]

特に排他協調レベルを設定した場合は、アプリケーションがデバイスを不意に解放する場合もあるので、アプリケーションが確実に取得状態を追跡するようにする。データを取得しようとした後で、DIERR_INPUTLOST エラーが発生したかどうかをチェックするのも 1 つの方法である。このエラーが発生していると、デバイスが解放されていたことがわかる。アプリケーションがイベント通知に応じて入力を取得している場合、取得が喪失すると、イベントが信号を発する。

排他モードでデバイスを管理する方法の詳細については、「ScrawlB サンプル」を参照すること。

取得済みのデバイスを再取得しようとしても、害はまったくない。Acquire に対する冗長な呼び出しは無視され、デバイスは常時 Unacquire を 1 回呼び出すことで解放することができる。

[C++]

Windows は、アプリケーションがマウスを排他モードで使用しているときは、マウスにアクセスしない。Windows にマウスを使用させたい場合は、マウスを解放しなければならない。Scrawl サンプルの 1 つの例では、右ボタンのクリックに反応するために、マウスを解放し、Windows カーソルを同じ点に表示し、コンテキスト メニューをポップアップし、メニュー選択が行われるまで Windows が入力を処理するようにしている。

[Visual Basic]

Windows は、アプリケーションがマウスを排他モードで使用しているときは、マウスにアクセスしない。Windows にマウスを使用させたければ、マウスを解放しなければならない。ScrawlB サンプル の 1 つの例では、右ボタンのクリックに反応するために、マウスを解放し、Windows カーソルを同じ点に表示し、コンテキスト メニューをポップアップし、メニュー選択が行われるまで Windows が入力を処理するようにしている。