次の方法で共有


IDirectInputDevice8::SetEventNotification メソッド

IDirectInputDevice8::SetEventNotification メソッド

デバイス状態が変化したときに設定されるイベントを指定する。イベント通知をオフにするためにも使う。

構文

HRESULT SetEventNotification(      
    HANDLE hEvent
);

パラメータ

  • hEvent
    デバイス状態が変化したときに設定されるイベントへのハンドル。Microsoft® DirectInput® はデバイスの状態が変化したときに、このハンドルに対して Microsoft Win32® SetEvent 関数を使う。hEvent パラメータを NULL にすると、通知は無効になる。

    アプリケーションは、Win32 CreateEvent 関数を使って、手動リセット イベントまたは自動リセット イベントとしてハンドルを作成することができる。イベントを自動リセット イベントとして作成すると、オペレーティング システムは、待ち時間が経過したときに自動的にイベントをリセットする。イベントを手動リセット イベントとして作成すると、アプリケーションは、Win32 ResetEvent 関数を呼び出してイベントをリセットしなければならない。DirectInput は、イベント通知ハンドルに対して、Win32 ResetEvent 関数を呼び出さない。アプリケーションは、通常、イベントを自動リセット イベントとして作成する。

戻り値

成功した場合は、DI_OK または DI_POLLEDDEVICE を返す。

失敗した場合は、次のいずれかのエラー値を返す。

DIERR_ACQUIRED 操作は、デバイスが取得状態の間は実行できない。
DIERR_HANDLEEXISTS デバイスは、既に自身にイベント通知を関連付けている。この値は、標準のコンポーネント オブジェクト モデル (COM) 戻り値である E_ACCESSDENIED に等しい。
DIERR_INVALIDPARAM 無効なパラメータが、戻ってくる関数に渡されたか、オブジェクトがその関数を呼び出せる状態になかった。この値は、標準の COM 戻り値である E_INVALIDARG に等しい。
DIERR_NOTINITIALIZED このオブジェクトは初期化されていない。

注意

デバイス状態の変更は次のいずれかで定義される。

  • 軸の位置の変更
  • ボタンの状態 (押した状態または離した状態)
  • 視点コントロールの方向の変更
  • 取得の喪失

DirectInputDevice オブジェクト中に選択されているイベントに対しては、Win32 CloseHandle 関数を呼び出してはならない。イベント ハンドルを終了する前に、hEvent パラメータに NULL を設定して、このメソッドを呼び出さなければならない。

イベント通知ハンドルは、デバイスが取得されている間は変更できない。この関数が成功すれば、アプリケーションは、他の Win32 イベント ハンドルと同様に、このイベント ハンドルを使える。

次の例は、ハンドルが現在ブロッキングなしに設定されているかどうかをチェックする。

dwResult = WaitForSingleObject(hEvent, 0); 
if (dwResult == WAIT_OBJECT_0) { 
    // Event is set.If the event was created as 
    // autoreset, it has also been reset. 
} 

次の例は、イベントが設定されるまで、繰り返しブロッキングを行う処理を示している。待ち時間が経過するまで、スレッドはシステムに応答できないので、この動作は厳禁である。特に、スレッドは Microsoft Windows® メッセージに応答しなくなる。

dwResult = WaitForSingleObject(hEvent, INFINITE); 
if (dwResult == WAIT_OBJECT_0) { 
    // Event has been set.If the event was created 
    // as autoreset, it has also been reset. 
} 

次の例は、2 つのイベントを使う非メッセージベースのアプリケーションの、典型的なメッセージ ループを示している。

HANDLE ah[2] = { hEvent1, hEvent2 }; 

while (TRUE) { 

    dwResult = MsgWaitForMultipleObjects(2, ah, FALSE, 
                        INFINITE, QS_ALLINPUT); 
    switch (dwResult) { 
    case WAIT_OBJECT_0: 
        // Event 1 has been set.If the event was created as
        // autoreset, it has also been reset. 
        ProcessInputEvent1(); 
        break; 

    case WAIT_OBJECT_0 + 1: 
        // Event 2 has been set.If the event was created as
        // autoreset, it has also been reset. 
        ProcessInputEvent2(); 
        break; 

    case WAIT_OBJECT_0 + 2: 
        // A Windows message has arrived.Process 
        // messages until there aren't any more. 
        while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){ 
            if (msg.message == WM_QUIT) { 
                goto exitapp; 
            } 
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        } 
        break; 

    default: 
        // Unexpected error. 
        Panic(); 
        break; 
    } 
} 

次の例は、2 つのイベントを使うメッセージベースのアプリケーションの、典型的なメッセージ ループを示している。

HANDLE ah[2] = { hEvent1, hEvent2 }; 
DWORD dwWait = 0; 

while (TRUE) { 

    dwResult = MsgWaitForMultipleObjects(2, ah, FALSE, 
                                         dwWait, QS_ALLINPUT); 
    dwWait = 0; 

    switch (dwResult) { 
    case WAIT_OBJECT_0: 
        // Event 1 has been set.If the event was 
        // created as autoreset, it has also 
        // been reset. 
        ProcessInputEvent1(); 
        break; 

    case WAIT_OBJECT_0 + 1: 
        // Event 2 has been set.If the event was 
        // created as autoreset, it has also 
        // been reset. 
        ProcessInputEvent2(); 
        break; 

    case WAIT_OBJECT_0 + 2: 
        // A Windows message has arrived.Process 
        // messages until there aren't any more. 
        while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){ 
            if (msg.message == WM_QUIT) { 
                goto exitapp; 
            } 
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        } 
        break; 

    default: 
        // No input or messages waiting. 
        // Do a frame of the game. 
        // If the game is idle, tell the next wait 
        // to wait indefinitely for input or a message. 
        if (!DoGame()) { 
            dwWait = INFINITE; 
        } 
        break; 
    } 
} 

参照

ポーリングとイベント通知