182 lines
4.4 KiB
C++
182 lines
4.4 KiB
C++
// Copyright (c) 1999 Microsoft Corporation. All rights reserved.
|
|
//
|
|
// Implementation of CAutBaseImp.
|
|
//
|
|
|
|
#include "dll.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Creation
|
|
|
|
template <class T_derived, class T_ITarget, const IID *T_piid>
|
|
CAutBaseImp<T_derived, T_ITarget, T_piid>::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<void**>(&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 <class T_derived, class T_ITarget, const IID *T_piid>
|
|
STDMETHODIMP
|
|
CAutBaseImp<T_derived, T_ITarget, T_piid>::QueryInterface(const IID &iid, void **ppv)
|
|
{
|
|
return m_pITarget->QueryInterface(iid, ppv);
|
|
}
|
|
|
|
template <class T_derived, class T_ITarget, const IID *T_piid>
|
|
STDMETHODIMP_(ULONG)
|
|
CAutBaseImp<T_derived, T_ITarget, T_piid>::AddRef()
|
|
{
|
|
return m_pITarget->AddRef();
|
|
}
|
|
|
|
template <class T_derived, class T_ITarget, const IID *T_piid>
|
|
STDMETHODIMP_(ULONG)
|
|
CAutBaseImp<T_derived, T_ITarget, T_piid>::Release()
|
|
{
|
|
return m_pITarget->Release();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Private Functions
|
|
|
|
template <class T_derived, class T_ITarget, const IID *T_piid>
|
|
void
|
|
CAutBaseImp<T_derived, T_ITarget, T_piid>::Destroy()
|
|
{
|
|
LockModule(false);
|
|
delete this;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// IDispatch
|
|
|
|
template <class T_derived, class T_ITarget, const IID *T_piid>
|
|
STDMETHODIMP
|
|
CAutBaseImp<T_derived, T_ITarget, T_piid>::GetTypeInfoCount(UINT *pctinfo)
|
|
{
|
|
V_INAME(CAutBaseImp::GetTypeInfoCount);
|
|
V_PTR_WRITE(pctinfo, UINT);
|
|
|
|
*pctinfo = 0;
|
|
return S_OK;
|
|
}
|
|
|
|
template <class T_derived, class T_ITarget, const IID *T_piid>
|
|
STDMETHODIMP
|
|
CAutBaseImp<T_derived, T_ITarget, T_piid>::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)
|
|
{
|
|
*ppTInfo = NULL;
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
template <class T_derived, class T_ITarget, const IID *T_piid>
|
|
STDMETHODIMP
|
|
CAutBaseImp<T_derived, T_ITarget, T_piid>::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 <class T_derived, class T_ITarget, const IID *T_piid>
|
|
STDMETHODIMP
|
|
CAutBaseImp<T_derived, T_ITarget, T_piid>::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<T_derived> *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<T_derived*>(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);
|
|
}
|