How to Get Events from the Network Source
Mit dem Quellre resolver kann eine Anwendung eine Netzwerkquelle erstellen und eine Verbindung mit einer bestimmten URL herstellen. Die Netzwerkquelle löst Ereignisse aus, um den Anfang und das Ende des asynchronen Vorgangs zum Öffnen einer Verbindung zu markieren. Eine Anwendung kann sich für diese Ereignisse registrieren, indem sie die BENUTZEROBERFLÄCHENQUELLEOpenMonitor verwendet.
Diese Schnittstelle macht die METHODE ASYNCHRONOUSSourceOpenMonitor::OnSourceEvent verfügbar, die die Netzwerkquelle direkt aufruft, wenn sie die URL asynchron öffnet. Die Netzwerkquelle benachrichtigt die Anwendung, wenn sie mit dem Öffnen der URL beginnt, indem sie das MEConnectStart-Ereignis ausdrängt. Die Netzwerkquelle löst dann das MEConnectEnd-Ereignis aus, wenn der Open-Vorgang abgeschlossen ist.
Hinweis
Um diese Ereignisse an die Anwendung zu senden, verwendet die Netzwerkquelle nicht die BENUTZEROBERFLÄCHEMEDIAEventGenerator-Schnittstelle, da diese Ereignisse ausgelöst werden, bevor die Netzwerkquelle erstellt wird. Die Anwendung kann alle anderen Netzwerkquellenereignisse mithilfe der MEDIAMediaEventGenerator-Schnittstelle der Media Session erhalten.
So erhalten Sie Ereignisse aus der Netzwerkquelle
- Implementieren Sie die SCHNITTSTELLE VERFSourceOpenMonitor. Gehen Sie in Ihrer Implementierung der METHODE DURCHSOURCEOpenMonitor::OnSourceEvent wie folgt vor:
- Rufen Sie den Ereignisstatus ab, indem Sie DENKMediaEvent::GetStatus aufrufen. Diese Methode gibt an, ob der Vorgang, der das Ereignis ausgelöst hat, z. B. ein Aufruf der Quellrelösermethode, erfolgreich war. Wenn der Vorgang nicht erfolgreich ist, ist der Status ein Fehlercode.
- Verarbeiten Sie das Ereignis basierend auf dem Ereignistyp: MEConnectStart oder MEConnectEnd,den die Anwendung durch Aufrufen von ZUEgeMediaEvent::GetType erhalten kann.
- Konfigurieren Sie ein Schlüssel-Wert-Paar in einem Eigenschaftsspeicherobjekt, um einen Zeiger auf die IN Schritt 1 beschriebene IMPLEMENTIERUNG VON DURCHSSOURCEOpenMonitor zu speichern.
- Erstellen Sie ein Eigenschaftenspeicherobjekt, indem Sie die PSCreateMemoryPropertyStore-Funktion aufrufen.
- Legen Sie die MFPKEY _ SourceOpenMonitor-Eigenschaft in einer PROPERTYKEY-Struktur fest.
- Geben Sie den VT UNKNOWN-Typdatenwert in einer PROPVARIANT-Struktur an, indem Sie den IUnknown-Zeiger auf die Anwendungsimplementierung der _ BESSOURCEOpenMonitor-Schnittstelle festlegen.
- Legen Sie das Schlüssel-Wert-Paar im Eigenschaftenspeicher fest, indem Sie IPropertyStore::SetValue aufrufen.
- Übergeben Sie den Eigenschaftsspeicherzeiger an die Methoden des Quellresolvers, die die Anwendung zum Erstellen der Netzwerkquelle verwendet, z. B. DURCHZEIGERQuelleResolver::CreateObjectFromURL und andere.
Beispiel
Das folgende Beispiel zeigt, wie sie die BENUTZEROBERFLÄCHESourceOpenMonitor-Schnittstelle implementiert, um Ereignisse aus der Netzwerkquelle zu erhalten.
class CSourceOpenMonitor : public IMFSourceOpenMonitor
{
public:
CSourceOpenMonitor () : m_cRef(1) { }
STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] =
{
QITABENT(CSourceOpenMonitor, IMFSourceOpenMonitor),
{ 0 }
};
return QISearch(this, qit, riid, ppv);
}
STDMETHODIMP_(ULONG) AddRef()
{
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) Release()
{
LONG cRef = InterlockedDecrement(&m_cRef);
if (cRef == 0)
{
delete this;
}
// For thread safety, return a temporary variable.
return cRef;
}
STDMETHODIMP OnSourceEvent(IMFMediaEvent* pEvent)
{
MediaEventType eventType = MEUnknown; // Event type
HRESULT hrStatus = S_OK; // Event status
// Get the event type.
HRESULT hr = pEvent->GetType(&eventType);
// Get the event status. If the operation that triggered the event
// did not succeed, the status is a failure code.
if (SUCCEEDED(hr))
{
hr = pEvent->GetStatus(&hrStatus);
}
if (FAILED(hrStatus))
{
hr = hrStatus;
}
if (SUCCEEDED(hr))
{
// Switch on the event type.
switch(eventType)
{
case MEConnectStart:
// The application does something. (Not shown.)
OutputDebugString(L"Connecting...\n");
break;
case MEConnectEnd:
// The application does something. (Not shown.)
OutputDebugString(L"Connect End.\n");
break;
}
}
else
{
// Event failed.
// The application handled a failure. (Not shown.)
}
return S_OK;
}
private:
long m_cRef;
};
Das folgende Beispiel zeigt, wie die MFPKEY _ SourceOpenMonitor-Eigenschaft für die Netzwerkquelle festgelegt wird, wenn Sie die URL öffnen:
HRESULT CreateMediaSourceWithSourceOpenMonitor(
PCWSTR pszURL,
IMFMediaSource **ppSource
)
{
IPropertyStore *pConfig = NULL;
CSourceOpenMonitor *pMonitor = new (std::nothrow) CSourceOpenMonitor();
if (pMonitor == NULL)
{
return E_OUTOFMEMORY;
}
// Configure the property store.
HRESULT hr = PSCreateMemoryPropertyStore(IID_PPV_ARGS(&pConfig));
if (SUCCEEDED(hr))
{
PROPVARIANT var;
var.vt = VT_UNKNOWN;
pMonitor->QueryInterface(IID_PPV_ARGS(&var.punkVal));
hr = pConfig->SetValue(MFPKEY_SourceOpenMonitor, var);
PropVariantClear(&var);
}
// Create the source media source.
if (SUCCEEDED(hr))
{
hr = CreateMediaSource(pszURL, pConfig, ppSource);
}
SafeRelease(&pConfig);
SafeRelease(&pMonitor);
return hr;
}