windows-nt/Source/XPSP1/NT/multimedia/directx/dmusic/dmscript/autbaseimp.inl
2020-09-26 16:20:57 +08:00

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);
}