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
24 template<class T>
25 class AsyncCallback : public IMFAsyncCallback
26 {
27 public:
28     typedef HRESULT (T::*InvokeFn)(IMFAsyncResult *pAsyncResult);
29 
AsyncCallback(T * pParent,InvokeFn fn)30     AsyncCallback(T *pParent, InvokeFn fn) : m_pParent(pParent), m_pInvokeFn(fn)
31     {
32     }
33 
34     // IUnknown
AddRef()35     STDMETHODIMP_(ULONG) AddRef() {
36         // Delegate to parent class.
37         return m_pParent->AddRef();
38     }
Release()39     STDMETHODIMP_(ULONG) Release() {
40         // Delegate to parent class.
41         return m_pParent->Release();
42     }
QueryInterface(REFIID iid,void ** ppv)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
GetParameters(DWORD *,DWORD *)68     STDMETHODIMP GetParameters(DWORD*, DWORD*)
69     {
70         // Implementation of this method is optional.
71         return E_NOTIMPL;
72     }
73 
Invoke(IMFAsyncResult * pAsyncResult)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