Partager via


Étape 6 : Gérer les événements graph

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement au nouveau code d’utiliser MediaPlayer, IMFMediaEngine et La capture audio/vidéo dans Media Foundation au lieu de DirectShow, lorsque cela est possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]

Cette rubrique est l’étape 6 du tutoriel Lecture audio/vidéo dans DirectShow. Le code complet est illustré dans la rubrique Exemple de lecture DirectShow.

Lorsque l’application crée un instance du Gestionnaire de graphes de filtre, l’application appelle IMediaEventEx::SetNotifyWindow. Cette méthode inscrit la fenêtre d’application pour recevoir les événements du graphe de filtre.

    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;
    }

La valeur WM_GRAPH_EVENT est un message de fenêtre privée. Chaque fois que l’application reçoit ce message, elle appelle la DShowPlayer::HandleGraphEvent méthode .

    case WM_GRAPH_EVENT:
       g_pPlayer->HandleGraphEvent(OnGraphEvent);
       return 0;

La méthode DShowPlayer::HandleGraphEvent effectue les opérations suivantes :

  1. Appelle IMediaEvent::GetEvent dans une boucle pour obtenir tous les événements mis en file d’attente.
  2. Appelle une fonction de rappel (pfnOnGraphEvent).
  3. Appelle IMediaEvent::FreeEventParams pour libérer les données associées à chaque événement.
// 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, &param1, &param2, 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;
}

Le code suivant montre la fonction de rappel qui est passée à DShowPlayer::HandleGraphEvent. La fonction gère le nombre minimal d’événements de graphe (EC_COMPLETE, EC_ERRORABORT et EC_USERABORT) ; vous pouvez développer la fonction pour gérer des événements supplémentaires.

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;
    }
}

Lecture audio/vidéo dans DirectShow

Exemple de lecture DirectShow

Notification d’événement dans DirectShow

Réponse aux événements