Microsoft DirectX 8.0 (C++)

通知とイベントの処理

アプリケーションでパフォーマンス イベントに応答しなければならない場合がある。たとえば、セグメントの終了に到達したことを知る必要がある場合や、グラフィックスを音楽の拍に同期させたい場合がある。特定のタイプのイベントが発生したときに、そのことを通知するよう DirectMusic に指示して、必要な情報を取得することができる。

  パフォーマンス通知と DirectSound のバッファ通知を混同してはならない。DirectSound のバッファ通知は、バッファに対して直接ウェーブ データをストリーミングするアプリケーションでのみ使用される。「再生バッファの通知」および「キャプチャ バッファの通知」を参照すること。

通知を受けたい音楽イベントの種類を指定するには、イベントの種類ごとに一度だけ IDirectMusicPerformance8::AddNotificationType メソッドを呼び出す。次のサンプル コードでは、DirectMusic にセグメントに関連するイベントを設定するように指示している。実際のイベントの種類 (セグメントの開始やセグメントの終了など) は、通知メッセージから得られる。

// pPerformance は有効な IDirectMusicPerformance8 ポインタである。
 
GUID guid = GUID_NOTIFICATION_SEGMENT;
 
pPerformance->AddNotificationType(guid);

IDirectMusicSegment8::AddNotificationType メソッドを使って、特定のセグメントに対して通知タイプを追加することもできる。たとえば、特定のセグメントが演奏を停止したときに通知を受け取るような場合に、この設定を行うことができる。このメソッドを使って GUID_NOTIFICATION_PERFORMANCE 型を要求することはできない。これらの型は、パフォーマンス オブジェクトから取得しなければならない。

  ほとんどのアプリケーションは、IDirectMusicTrack8::AddNotificationType メソッドを直接呼び出さない。

通知に関する情報は、DMUS_NOTIFICATION_PMSG メッセージ構造体で送信される。IDirectMusicPerformance8::GetNotificationPMsg メソッドを呼び出して、Windows メッセージ ループ内で保留中の通知メッセージをポーリングすることができる。また、メッセージが保留中のときに、DirectMusic に別のスレッドでイベント オブジェクトを通知させることもできる。

Windows イベント オブジェクトを使って、保留中の DirectMusic 通知メッセージを知らせたい場合は、まず Microsoft® Win32® CreateEvent 関数を呼び出して、イベント ハンドルを取得しなければならない。通常は、次のような呼び出しを行って、自動リセット イベントを作成する。

HANDLE g_hNotify = CreateEvent(NULL, FALSE, FALSE, NULL);

イベントの作成後、このハンドルを IDirectMusicPerformance8::SetNotificationHandle メソッドに渡してパフォーマンスに割り当てる。このメソッドの 2 番目のパラメータを使用して、DirectMusic で、取得されていないイベントを待機する時間を指定できる。このパラメータの値が 0 の場合は、デフォルトの時間である 2 秒が使用される。

次の例では、g_pPerfIDirectMusicPerformance8 インターフェイスへの有効なポインタを表している。

g_pPerf->SetNotificationHandle(g_hNotify, 0);

次のサンプル関数は、独自のスレッドで繰り返し実行され、通知されたイベントを確認して、通知メッセージを取り出している。

void WaitForEvent( LPVOID lpv)
{
    DWORD dwResult;
    DMUS_NOTIFICATION_PMSG* pPmsg;
    char szCount[4];
 
    while (TRUE)
    {
        dwResult = WaitForSingleObject(g_hNotify, 100);
        while (S_OK == g_pPerf->GetNotificationPMsg(&pPmsg))
        {
            // 通知タイプをチェックし、それに応じて処理を行う。
            .
            .
            .
            g_pPerf->FreePMsg((DMUS_PMSG*)pPmsg); 
        }
    }
}

このスレッドは次のように実行される。

_beginthread(WaitForEvent, 0, NULL);

通知が必要なくなった場合は、次のコードに示すように、スレッドをシャット ダウンし、パフォーマンスから通知ハンドルを削除し、イベント オブジェクトを破棄する。

_endthread();
g_pPerf->SetNotificationHandle(0, 0);
CloseHandle(g_hNotify);

アプリケーションのメッセージ ループで、イベントを作成して通知メッセージを取得する必要はない。AddNotificationType メソッドのいずれかを呼び出して通知を要求している場合、メッセージはパフォーマンスによって送信され、IDirectMusicPerformance8::GetNotificationPMsg の呼び出しで取得することができる。

イベントが通知される場合、またはメッセージ ループで GetNotificationPMsg を呼び出す場合は、複数のメッセージを待機することができる。すべての通知を確実に受け取るには、S_FALSE が返されるまで GetNotificationPMsg の呼び出しを繰り返す。

同じタイム スタンプを持つメッセージが複数ある場合、これらのメッセージはキューに格納されるときに特定の順序にはならない。

アプリケーションは、IDirectMusicPerformance8::FreePMsg メソッドを呼び出して、取得したメッセージを解放する必要がある。