手順 6: グラフ イベントを処理する
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]
このトピックは、 DirectShow でのオーディオ/ビデオ再生に関するチュートリアルの手順 6 です。 完全なコードは、「 DirectShow 再生の例」トピックに示されています。
アプリケーションが Filter Graph Manager の新しいインスタンスを作成すると、アプリケーションは IMediaEventEx::SetNotifyWindow を呼び出します。 このメソッドは、フィルター グラフからイベントを受信するアプリケーション ウィンドウを登録します。
hr = m_pGraph->QueryInterface(IID_PPV_ARGS(&m_pEvent));
if (FAILED(hr))
{
goto done;
}
// Set up event notification.
hr = m_pEvent->SetNotifyWindow((OAHWND)m_hwnd, WM_GRAPH_EVENT, NULL);
if (FAILED(hr))
{
goto done;
}
値 WM_GRAPH_EVENT
はプライベート ウィンドウ メッセージです。 アプリケーションはこのメッセージを受信するたびに、 メソッドを DShowPlayer::HandleGraphEvent
呼び出します。
case WM_GRAPH_EVENT:
g_pPlayer->HandleGraphEvent(OnGraphEvent);
return 0;
DShowPlayer::HandleGraphEvent
メソッドは以下を実行します。
- ループ内の IMediaEvent::GetEvent を 呼び出して、キューに入っているすべてのイベントを取得します。
- コールバック関数 (pfnOnGraphEvent) を呼び出します。
- IMediaEvent::FreeEventParams を呼び出して、各イベントに関連付けられているデータを解放します。
// Respond to a graph event.
//
// The owning window should call this method when it receives the window
// message that the application specified when it called SetEventWindow.
//
// Caution: Do not tear down the graph from inside the callback.
HRESULT DShowPlayer::HandleGraphEvent(GraphEventFN pfnOnGraphEvent)
{
if (!m_pEvent)
{
return E_UNEXPECTED;
}
long evCode = 0;
LONG_PTR param1 = 0, param2 = 0;
HRESULT hr = S_OK;
// Get the events from the queue.
while (SUCCEEDED(m_pEvent->GetEvent(&evCode, ¶m1, ¶m2, 0)))
{
// Invoke the callback.
pfnOnGraphEvent(m_hwnd, evCode, param1, param2);
// Free the event data.
hr = m_pEvent->FreeEventParams(evCode, param1, param2);
if (FAILED(hr))
{
break;
}
}
return hr;
}
次のコードは、 に渡されるコールバック関数を DShowPlayer::HandleGraphEvent
示しています。 関数は、グラフ イベントの最小数 (EC_COMPLETE、 EC_ERRORABORT、 およびEC_USERABORT) を処理します。関数を展開して、追加のイベントを処理できます。
void CALLBACK OnGraphEvent(HWND hwnd, long evCode, LONG_PTR param1, LONG_PTR param2)
{
switch (evCode)
{
case EC_COMPLETE:
case EC_USERABORT:
g_pPlayer->Stop();
break;
case EC_ERRORABORT:
NotifyError(hwnd, L"Playback error.");
g_pPlayer->Stop();
break;
}
}
関連トピック