Implementing the Asynchronous Callback
The following code shows the basic framework needed to implement the IMFAsyncCallback interface. In this example, the Invoke method is declared as a pure virtual method. The implementation of this method will depend on which asynchronous method you are calling. For more information, see Calling Asynchronous Methods.
#include <shlwapi.h> class CAsyncCallback : public IMFAsyncCallback { public: CAsyncCallback () : m_cRef(1) { } virtual ~CAsyncCallback() { } STDMETHODIMP QueryInterface(REFIID riid, void** ppv) { static const QITAB qit[] = { QITABENT(CAsyncCallback, IMFAsyncCallback), { 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; } return cRef; } STDMETHODIMP GetParameters(DWORD* pdwFlags, DWORD* pdwQueue) { // Implementation of this method is optional. return E_NOTIMPL; } STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult) = 0; // TODO: Implement this method. // Inside Invoke, IMFAsyncResult::GetStatus to get the status. // Then call the EndX method to complete the operation. private: long m_cRef; };
This following code shows an example implementation of a class that derives from CAsyncCallback:
class CMyCallback : public CAsyncCallback { HANDLE m_hEvent; IMFByteStream *m_pStream; HRESULT m_hrStatus; ULONG m_cbRead; public: CMyCallback(IMFByteStream *pStream, HRESULT *phr) : m_pStream(pStream), m_hrStatus(E_PENDING), m_cbRead(0) { *phr = S_OK; m_pStream->AddRef(); m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (m_hEvent == NULL) { *phr = HRESULT_FROM_WIN32(GetLastError()); } } ~CMyCallback() { m_pStream->Release(); CloseHandle(m_hEvent); } HRESULT WaitForCompletion(DWORD msec) { DWORD result = WaitForSingleObject(m_hEvent, msec); switch (result) { case WAIT_TIMEOUT: return E_PENDING; case WAIT_ABANDONED: case WAIT_OBJECT_0: return m_hrStatus; default: return HRESULT_FROM_WIN32(GetLastError()); } } ULONG GetBytesRead() const { return m_cbRead; } STDMETHODIMP Invoke(IMFAsyncResult* pResult) { m_hrStatus = m_pStream->EndRead(pResult, &m_cbRead); SetEvent(m_hEvent); return S_OK; } };
This example signals an event inside the Invoke method. For a discussion of the various options, see Calling Asynchronous Methods.
Related topics