IX1
class OuterCOMObj_ClassFactory : IClassFactory { ... HRESULT CreateInstance (IUnknown *po, REFIID riid, void **ppv) { BOOL bInit; HRESULT hr = E_FAIL; //Create the COM object OuterCOMObj *pcom = new OuterCOMObj(); if (!pcom) return E_OUTOFMEMORY; //Call the Init method. This is NOT a COM call. //It is simply an internal initialization call. bInit = pcom->Init(); if (bInit) hr = pcom->QueryInterface(riid, ppv); if (FAILED(hr) || !bInit) delete pcom; return hr; } ... Other Code ... };
class OuterCOMObj : IX1, IX2 { ULONG m_refcnt; IX1 *m_pInner_IX1; public: OuterCOMObj() : m_refcnt(0), pInner_IX1(NULL) { } ~OuterCOMObj { } //Called from IClassFactory::CreateInstance to perform internal initialization of the COM //object. This is where the outer COM object //creates an instance of the inner COM object //and gets an interface pointer into it. BOOL Init() { //Create an instance of the inner COM object //and get a pointer to its IX1 interface. //Place the inner COM object's IX1 pointer //in m_pInner_IX1. HRESULT hr = CoCreateInstance(CLSID_InnerCOMObj, NULL, CLSCTX_INPROC_SERVER, IID_IX1, (void **) &m_pInner_IX1); if (FAILED(hr)) return FALSE; return TRUE; } HRESULT QueryInterface(REFIID riid, void **ppv) { if (riid == IID_IX1) *ppv = (IX1 *) this; if (riid == IID_IX2) *ppv = (IX2 *) this; else return E_NOINTERFACE; ((IUnknown *) (*ppv))->AddRef(); return S_OK; } HRESULT AddRef() { return ++m_refcnt; } HRESULT Release() { if (--m_refcnt == 0) { delete this; return 0; } return m_refcnt; } //IX1 Functions HRESULT x1(int ix) { //Delegate to the inner object's IX1::x1 return m_pInner_IX1->x1(zz); } //x2 filters it delegation - calling into the //inner object every other time HRESULT x2() { static int even_odd = 1; HRESULT hr = S_OK; if (!(even_odd % 2)) { //Delegate to the inner object's IX1::X2 hr = m_pInner_IX1->x2(); } else { ... do stuff .. } ++even_odd; return hr; } //IX2 Functions Assume IX2 is an interface implemented by the outer COM object. For this exercise we are not concerned with its implementation. };