Schritt 6: Behandeln von Graphereignissen
[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde von MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation abgelöst. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code mediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet, wenn möglich. Microsoft schlägt vor, dass vorhandener Code, der die Legacy-APIs verwendet, so umgeschrieben wird, dass nach Möglichkeit die neuen APIs verwendet werden.]
Dieses Thema ist Schritt 6 des Tutorials Audio/Videowiedergabe in DirectShow. Der vollständige Code wird im Thema DirectShow-Wiedergabebeispiel angezeigt.
Wenn die Anwendung eine neue instance des Filter Graph-Managers erstellt, ruft die Anwendung IMediaEventEx::SetNotifyWindow auf. Diese Methode registriert das Anwendungsfenster, um Ereignisse aus dem Filterdiagramm zu empfangen.
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;
}
Der Wert WM_GRAPH_EVENT
ist eine private Fenstermeldung. Immer wenn die Anwendung diese Nachricht empfängt, ruft sie die DShowPlayer::HandleGraphEvent
-Methode auf.
case WM_GRAPH_EVENT:
g_pPlayer->HandleGraphEvent(OnGraphEvent);
return 0;
Die DShowPlayer::HandleGraphEvent
-Methode führt folgende Schritte aus:
- Ruft IMediaEvent::GetEvent in einer Schleife auf, um alle Ereignisse in der Warteschlange abzurufen.
- Ruft eine Rückruffunktion (pfnOnGraphEvent) auf.
- Ruft IMediaEvent::FreeEventParams auf, um die daten frei zu geben, die den einzelnen Ereignissen zugeordnet sind.
// 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;
}
Der folgende Code zeigt die Rückruffunktion, die an DShowPlayer::HandleGraphEvent
übergeben wird. Die Funktion verarbeitet die minimale Anzahl von Graphereignissen (EC_COMPLETE, EC_ERRORABORT und EC_USERABORT); Sie können die Funktion erweitern, um zusätzliche Ereignisse zu behandeln.
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;
}
}
Zugehörige Themen