步骤 6:处理图形事件
[与此页面关联的功能 DirectShow 是旧版功能。 它已被 MediaPlayer、 IMFMediaEngine 和 Media Foundation 中的音频/视频捕获所取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能在 Media Foundation 中使用 MediaPlayer、 IMFMediaEngine 和 音频/视频捕获 ,而不是 DirectShow。 如果可能,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;
}
}
相关主题