1#pragma once 2 3////////////////////////////////////////////////////////////////////////// 4// AsyncCallback [template] 5// 6// Description: 7// Helper class that routes IMFAsyncCallback::Invoke calls to a class 8// method on the parent class. 9// 10// Usage: 11// Add this class as a member variable. In the parent class constructor, 12// initialize the AsyncCallback class like this: 13// m_cb(this, &CYourClass::OnInvoke) 14// where 15// m_cb = AsyncCallback object 16// CYourClass = parent class 17// OnInvoke = Method in the parent class to receive Invoke calls. 18// 19// The parent's OnInvoke method (you can name it anything you like) must 20// have a signature that matches the InvokeFn typedef below. 21////////////////////////////////////////////////////////////////////////// 22 23// T: Type of the parent object 24template<class T> 25class AsyncCallback : public IMFAsyncCallback 26{ 27public: 28 typedef HRESULT (T::*InvokeFn)(IMFAsyncResult *pAsyncResult); 29 30 AsyncCallback(T *pParent, InvokeFn fn) : m_pParent(pParent), m_pInvokeFn(fn) 31 { 32 } 33 34 // IUnknown 35 STDMETHODIMP_(ULONG) AddRef() { 36 // Delegate to parent class. 37 return m_pParent->AddRef(); 38 } 39 STDMETHODIMP_(ULONG) Release() { 40 // Delegate to parent class. 41 return m_pParent->Release(); 42 } 43 STDMETHODIMP QueryInterface(REFIID iid, void** ppv) 44 { 45 if (!ppv) 46 { 47 return E_POINTER; 48 } 49 if (iid == __uuidof(IUnknown)) 50 { 51 *ppv = static_cast<IUnknown*>(static_cast<IMFAsyncCallback*>(this)); 52 } 53 else if (iid == __uuidof(IMFAsyncCallback)) 54 { 55 *ppv = static_cast<IMFAsyncCallback*>(this); 56 } 57 else 58 { 59 *ppv = NULL; 60 return E_NOINTERFACE; 61 } 62 AddRef(); 63 return S_OK; 64 } 65 66 67 // IMFAsyncCallback methods 68 STDMETHODIMP GetParameters(DWORD*, DWORD*) 69 { 70 // Implementation of this method is optional. 71 return E_NOTIMPL; 72 } 73 74 STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult) 75 { 76 return (m_pParent->*m_pInvokeFn)(pAsyncResult); 77 } 78 79 T *m_pParent; 80 InvokeFn m_pInvokeFn; 81}; 82