Passaggio 6: Gestire gli eventi del grafico
[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEnginee Acquisizione audio/video in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente di scrivere nuovo codice utilizzando MediaPlayer, IMFMediaEngine e Acquisizione audio/video in Media Foundation anziché DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.
Questo argomento è il passaggio 6 dell'esercitazione Riproduzione audio/video in DirectShow. Il codice completo è illustrato nell'argomento Esempio di riproduzione DirectShow.
Quando l'applicazione crea una nuova istanza di Filter Graph Manager, l'applicazione chiama IMediaEventEx::SetNotifyWindow. Questo metodo registra la finestra dell'applicazione per ricevere eventi dal grafico del filtro.
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;
}
Il valore WM_GRAPH_EVENT
è un messaggio di finestra privata. Ogni volta che l'applicazione riceve questo messaggio, chiama il metodo DShowPlayer::HandleGraphEvent
.
case WM_GRAPH_EVENT:
g_pPlayer->HandleGraphEvent(OnGraphEvent);
return 0;
Il metodo DShowPlayer::HandleGraphEvent
esegue le operazioni seguenti:
- Chiama IMediaEvent::GetEvent in un ciclo per ottenere tutti gli eventi in coda.
- Richiama una funzione di callback (pfnOnGraphEvent).
- Chiama IMediaEvent::FreeEventParams per liberare i dati associati a ogni evento.
// 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;
}
Il codice seguente illustra la funzione di callback passata a DShowPlayer::HandleGraphEvent
. La funzione gestisce il numero minimo di eventi del grafo (EC_COMPLETE, EC_ERRORABORTe EC_USERABORT); è possibile espandere la funzione per gestire eventi aggiuntivi.
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;
}
}
Argomenti correlati
-
Notifiche di eventi in DirectShow