Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
Om du anropar mer än en asynkron metod kräver var och en separat implementering av IMFAsyncCallback::Invoke. Du kanske dock vill implementera återanropen i en enda C++-klass. Klassen kan bara ha en Anropa-metoden, så en lösning är att tillhandahålla en hjälpklass som delegerar Anropa anrop till en annan metod i en containerklass.
Följande kod visar en klassmall med namnet AsyncCallback, som visar den här metoden.
//////////////////////////////////////////////////////////////////////////
// AsyncCallback [template]
//
// Description:
// Helper class that routes IMFAsyncCallback::Invoke calls to a class
// method on the parent class.
//
// Usage:
// Add this class as a member variable. In the parent class constructor,
// initialize the AsyncCallback class like this:
// m_cb(this, &CYourClass::OnInvoke)
// where
// m_cb = AsyncCallback object
// CYourClass = parent class
// OnInvoke = Method in the parent class to receive Invoke calls.
//
// The parent's OnInvoke method (you can name it anything you like) must
// have a signature that matches the InvokeFn typedef below.
//////////////////////////////////////////////////////////////////////////
// T: Type of the parent object
template<class T>
class AsyncCallback : public IMFAsyncCallback
{
public:
typedef HRESULT (T::*InvokeFn)(IMFAsyncResult *pAsyncResult);
AsyncCallback(T *pParent, InvokeFn fn) : m_pParent(pParent), m_pInvokeFn(fn)
{
}
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] =
{
QITABENT(AsyncCallback, IMFAsyncCallback),
{ 0 }
};
return QISearch(this, qit, riid, ppv);
}
STDMETHODIMP_(ULONG) AddRef() {
// Delegate to parent class.
return m_pParent->AddRef();
}
STDMETHODIMP_(ULONG) Release() {
// Delegate to parent class.
return m_pParent->Release();
}
// IMFAsyncCallback methods
STDMETHODIMP GetParameters(DWORD*, DWORD*)
{
// Implementation of this method is optional.
return E_NOTIMPL;
}
STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult)
{
return (m_pParent->*m_pInvokeFn)(pAsyncResult);
}
T *m_pParent;
InvokeFn m_pInvokeFn;
};
Mallparametern är namnet på containerklassen. Konstruktorn AsyncCallback har två parametrar: en pekare till containerklassen och adressen till en återanropsmetod i containerklassen. Containerklassen kan ha flera instanser av AsyncCallback-klassen som medlemsvariabler, en för varje asynkron metod. När containerklassen anropar en asynkron metod använder den IMFAsyncCallback--gränssnittet för lämpligt AsyncCallback-objekt. När AsyncCallback-objektets Anropa-metoden anropas delegeras anropet till rätt metod i containerklassen.
AsyncCallback-objektet delegerar även AddRef-- och Release-anrop till containerklassen, så containerklassen hanterar livslängden för AsyncCallback-objektet. Detta garanterar att AsyncCallback-objektet inte tas bort förrän själva containerobjektet har tagits bort.
Följande kod visar hur du använder den här mallen:
#pragma warning( push )
#pragma warning( disable : 4355 ) // 'this' used in base member initializer list
class CMyObject : public IUnknown
{
public:
CMyObject() : m_CB(this, &CMyObject::OnInvoke)
{
// Other initialization here.
}
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
private:
AsyncCallback<CMyObject> m_CB;
HRESULT OnInvoke(IMFAsyncResult *pAsyncResult);
};
#pragma warning( pop )
I det här exemplet heter containerklassen CMyObject. Variabeln m_CB medlem är ett AsyncCallback objekt. I CMyObject-konstruktorn initieras m_CB medlemsvariabeln med adressen för metoden CMyObject::OnInvoke.
Relaterade ämnen