コールバック関数の使い方

コールバック関数の使い方

コールバック関数は基本的にイベント ハンドラの 1 つであり、アプリケーションが実装し、システムが呼び出す。通常、Microsoft® Windows® アプリケーションには複数のコールバック関数が実装されており、それぞれ異なるグループのイベントの処理に使われる。イベントが発生すると、システムは適切なコールバック関数を呼び出してアプリケーションに通知する。また、通常、コールバック関数はパラメータ リストを保持しており、システムはこのリストを使ってイベントに関する詳細情報をアプリケーションに渡す。コールバック関数の最も一般的な例は、ウィンドウ プロシージャである。この関数は、システムがウィンドウを所有するアプリケーションに Windows メッセージを渡すときに使う。

Microsoft DirectX® では、コールバック関数をさまざまな目的に使う。たとえば、システムは複数のデバイスをサポートしている。Microsoft DirectInput® は各デバイスをデバイス オブジェクトで表す。デバイス オブジェクトには、そのデバイスの機能に関する詳細情報が含まれている。通常、アプリケーションがユーザーの入力を正しく処理するには、利用可能なデバイスを列挙して、デバイス オブジェクトを調べる必要がある。この列挙を実行するには、DIEnumDeviceObjectsCallback コールバック関数を実装しなければならない。

列挙を実行するための最初の処理は、IDirectInputDevice8::EnumObjects の呼び出しである。次に、DIEnumDeviceObjectsCallback コールバック関数へのポインタをメソッドに渡す。システムは、各デバイスに対して 1 回ずつこの関数を呼び出し、デバイスの機能に関する情報を含む DIDEVICEOBJECTINSTANCE 構造体を渡す。コールバック関数は、この情報を処理した後、次のデバイス オブジェクトを要求する場合は DIENUM_CONTINUE を返し、列挙を停止する場合は DIENUM_STOP を返す。

DirectX では、他にもさまざまなコールバック関数がさまざまな目的のために使われる。詳細については、各 DirectX コンポーネントのドキュメントを参照すること。

コールバック関数の実装

コールバック関数には、さまざまな目的および用途がある。このため、通常の関数と同様に、コールバック関数についても、各関数のトピックで説明する。ただし、コールバック関数のリファレンスは、通常のアプリケーション プログラミング インターフェイス (API) のリファレンスと異なり、その関数を実装する方法を示すテンプレートになっている。コールバック関数のリファレンスには、次の情報を記載している。

  • 関数の使い方
  • 関数の構文
  • 各パラメータに格納される情報の説明
  • 返される可能性のある戻り値の説明

コールバック関数は、CALLBACK 型または WINAPI 型として宣言する。どちらのタイプを使ってもよい。任意の関数名を使える。ドキュメントで使われている名前は、コールバック関数の単なる便宜上のラベルである。

リファレンスの説明に従って関数を実装する。実装方法の詳細は、各関数やアプリケーションの要件によって異なる。さまざまなコールバック関数の実装方法の例については、サンプル コードを参照すること。

関数へのポインタを適切な DirectX コンポーネントに渡す。DirectX コンポーネントは、この関数ポインタを使って関数を呼び出す。このポインタの渡し方は、関数によって異なるので、詳細については各関数のリファレンスを参照すること。

次のコードは、DirectInput Joystick サンプルの一部である。このコードには、ジョイスティックの軸を列挙するために使われる DIEnumDeviceObjectsCallback の実装の基本的な要素が含まれている。

// The function declaration
BOOL CALLBACK EnumAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
                                VOID* pContext );
...
// Pass the function pointer to DirectInput by calling the 
// IDirectInputDevice9::EnumObjects method

if ( FAILED( hr = g_pJoystick->EnumObjects(EnumAxesCallback, 
                                            (VOID*)hDlg,
                                            DIDFT_AXIS )));

...

// The function implementation
BOOL CALLBACK EnumAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
                                VOID* pContext )
{
// Process the information passed in through the two parameters
// Return DIENUM_CONTINUE to request the next device object
// Return DIENUM_STOP to stop the enumeration
}