1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#pragma once
2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//////////////////////////////////////////////////////////////////////////
4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  AsyncCallback [template]
5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  Description:
7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  Helper class that routes IMFAsyncCallback::Invoke calls to a class
8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  method on the parent class.
9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  Usage:
11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  Add this class as a member variable. In the parent class constructor,
12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  initialize the AsyncCallback class like this:
13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  	m_cb(this, &CYourClass::OnInvoke)
14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  where
15793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//      m_cb       = AsyncCallback object
16793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//      CYourClass = parent class
17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//      OnInvoke   = Method in the parent class to receive Invoke calls.
18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  The parent's OnInvoke method (you can name it anything you like) must
20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  have a signature that matches the InvokeFn typedef below.
21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//////////////////////////////////////////////////////////////////////////
22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// T: Type of the parent object
24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslertemplate<class T>
25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerclass AsyncCallback : public IMFAsyncCallback
26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerpublic:
28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    typedef HRESULT (T::*InvokeFn)(IMFAsyncResult *pAsyncResult);
29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    AsyncCallback(T *pParent, InvokeFn fn) : m_pParent(pParent), m_pInvokeFn(fn)
31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // IUnknown
35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    STDMETHODIMP_(ULONG) AddRef() {
36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // Delegate to parent class.
37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return m_pParent->AddRef();
38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    STDMETHODIMP_(ULONG) Release() {
40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // Delegate to parent class.
41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return m_pParent->Release();
42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (!ppv)
46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return E_POINTER;
48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (iid == __uuidof(IUnknown))
50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *ppv = static_cast<IUnknown*>(static_cast<IMFAsyncCallback*>(this));
52793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
53793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else if (iid == __uuidof(IMFAsyncCallback))
54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *ppv = static_cast<IMFAsyncCallback*>(this);
56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else
58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *ppv = NULL;
60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return E_NOINTERFACE;
61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        AddRef();
63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return S_OK;
64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // IMFAsyncCallback methods
68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    STDMETHODIMP GetParameters(DWORD*, DWORD*)
69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // Implementation of this method is optional.
71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return E_NOTIMPL;
72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult)
75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
76793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (m_pParent->*m_pInvokeFn)(pAsyncResult);
77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    T *m_pParent;
80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    InvokeFn m_pInvokeFn;
81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler};
82