// Copyright (c) 1999 Microsoft Corporation. All rights reserved. // // Implementation of CAutBaseImp. // #include "dll.h" ////////////////////////////////////////////////////////////////////// // Creation template CAutBaseImp::CAutBaseImp( IUnknown* pUnknownOuter, const IID& iid, void** ppv, HRESULT *phr) : m_pITarget(NULL) { struct LocalFunc { static HRESULT CheckParams(IUnknown* pUnknownOuter, void** ppv) { V_INAME(CAutBaseImp::CAutBaseImp); V_INTERFACE(pUnknownOuter); V_PTR_WRITE(ppv, IUnknown *); return S_OK; } }; *phr = LocalFunc::CheckParams(pUnknownOuter, ppv); if (FAILED(*phr)) return; *ppv = NULL; // This class can only be created inside an aggregation. if (!pUnknownOuter || iid != IID_IUnknown) { Trace(1, "Error: The AutoImp objects are used by other DirectMusic objects, but are not designed to be instantiated on their own.\n"); *phr = E_INVALIDARG; return; } // The outer object must have the target interface. *phr = pUnknownOuter->QueryInterface(*T_piid, reinterpret_cast(&m_pITarget)); if (FAILED(*phr)) return; // Due to the aggregation contract, our object is wholely contained in the lifetime of // the outer object and we shouldn't hold any references to it. ULONG ulCheck = m_pITarget->Release(); assert(ulCheck); m_UnkControl.Init(this, this); LockModule(true); *phr = m_UnkControl.QueryInterface(iid, ppv); return; } ////////////////////////////////////////////////////////////////////// // IUnknown // Delegates to outer unknown. template STDMETHODIMP CAutBaseImp::QueryInterface(const IID &iid, void **ppv) { return m_pITarget->QueryInterface(iid, ppv); } template STDMETHODIMP_(ULONG) CAutBaseImp::AddRef() { return m_pITarget->AddRef(); } template STDMETHODIMP_(ULONG) CAutBaseImp::Release() { return m_pITarget->Release(); } ////////////////////////////////////////////////////////////////////// // Private Functions template void CAutBaseImp::Destroy() { LockModule(false); delete this; } ////////////////////////////////////////////////////////////////////// // IDispatch template STDMETHODIMP CAutBaseImp::GetTypeInfoCount(UINT *pctinfo) { V_INAME(CAutBaseImp::GetTypeInfoCount); V_PTR_WRITE(pctinfo, UINT); *pctinfo = 0; return S_OK; } template STDMETHODIMP CAutBaseImp::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo) { *ppTInfo = NULL; return E_NOTIMPL; } template STDMETHODIMP CAutBaseImp::GetIDsOfNames( REFIID riid, LPOLESTR __RPC_FAR *rgszNames, UINT cNames, LCID lcid, DISPID __RPC_FAR *rgDispId) { return AutDispatchGetIDsOfNames(T_derived::ms_Methods, riid, rgszNames, cNames, lcid, rgDispId); } template STDMETHODIMP CAutBaseImp::Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS __RPC_FAR *pDispParams, VARIANT __RPC_FAR *pVarResult, EXCEPINFO __RPC_FAR *pExcepInfo, UINT __RPC_FAR *puArgErr) { // Decode the parameters AutDispatchDecodedParams addp; HRESULT hr = AutDispatchInvokeDecode( T_derived::ms_Methods, &addp, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, puArgErr, T_derived::ms_wszClassName, m_pITarget); if (FAILED(hr)) return hr; // Call the handler for (const DispatchHandlerEntry *pdhe = T_derived::ms_Handlers; pdhe->dispid != DISPID_UNKNOWN && pdhe->dispid != dispIdMember; ++pdhe) { } if (pdhe->dispid == DISPID_UNKNOWN) { assert(false); return DISP_E_MEMBERNOTFOUND; } hr = ((static_cast(this))->*pdhe->pmfn)(&addp); // Clean up and return AutDispatchInvokeFree(T_derived::ms_Methods, &addp, dispIdMember, riid); return AutDispatchHrToException(T_derived::ms_Methods, dispIdMember, riid, hr, pExcepInfo); }