From ee729a69a3ea3b2f9b8b2fc302a0431f65dd8db4 Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Fri, 8 Apr 2016 08:38:48 +0000 Subject: [PATCH] [ATL] - Add a basic implementation for IDispatchImpl. Patch by Mark Jansen. CORE-11087 svn path=/trunk/; revision=71117 --- reactos/lib/atl/atlbase.h | 4 +- reactos/lib/atl/atlcom.h | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/reactos/lib/atl/atlbase.h b/reactos/lib/atl/atlbase.h index 152e048ad1f..2cb7a10e585 100644 --- a/reactos/lib/atl/atlbase.h +++ b/reactos/lib/atl/atlbase.h @@ -395,9 +395,9 @@ public: class CAtlModule : public _ATL_MODULE { -protected: - static GUID m_libid; public: + static GUID m_libid; + CAtlModule() { ATLASSERT(_pAtlModule == NULL); diff --git a/reactos/lib/atl/atlcom.h b/reactos/lib/atl/atlcom.h index 2a537d3bcc9..98d0ca08a88 100644 --- a/reactos/lib/atl/atlcom.h +++ b/reactos/lib/atl/atlcom.h @@ -1434,4 +1434,91 @@ public: {offsetofclass(ATL::_ICPLocator<&iid>, _atl_conn_classtype) - \ offsetofclass(ATL::IConnectionPointContainerImpl<_atl_conn_classtype>, _atl_conn_classtype)}, + + +/* TODO: + - IDispatchImpl contains a static member of type CComTypeInfoHolder that manages the type information for the dual interface. + If you have multiple objects that implement the same dual interface, only one instance of CComTypeInfoHolder is used. + - By default, the IDispatchImpl class looks up the type information for T in the registry. + To implement an unregistered interface, you can use the IDispatchImpl class without accessing the registry by using a predefined version number. + If you create an IDispatchImpl object that has 0xFFFF as the value for wMajor and 0xFFFF as the value for wMinor, + the IDispatchImpl class retrieves the type library from the .dll file instead of the registry. +*/ +template +class IDispatchImpl : + public T +{ +private: + CComPtr m_pTypeInfo; + + STDMETHOD(EnsureTILoaded)(LCID lcid) + { + HRESULT hr = S_OK; + if (m_pTypeInfo != NULL) + return hr; + + if (IsEqualCLSID(CLSID_NULL, *plibid)) + OutputDebugStringA("IDispatchImpl: plibid is CLSID_NULL!\r\n"); + + // Should we assert here? + if (wMajor == 0xffff && wMinor == 0xffff) + OutputDebugStringA("IDispatchImpl: not fully implemented, missing functionality to load TLB from file!\r\n"); + + CComPtr spTypeLib; + hr = LoadRegTypeLib(*plibid, wMajor, wMinor, lcid, &spTypeLib); + if (SUCCEEDED(hr)) + { + hr = spTypeLib->GetTypeInfoOfGuid(*piid, &m_pTypeInfo); + } + return hr; + } + +public: + IDispatchImpl() + { + } + + + // *** IDispatch methods *** + STDMETHOD(GetTypeInfoCount)(UINT *pctinfo) + { + if (pctinfo == NULL) + return E_POINTER; + + *pctinfo = 1; + return S_OK; + } + + STDMETHOD(GetTypeInfo)(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) + { + if (iTInfo != 0) + return DISP_E_BADINDEX; + if (ppTInfo == NULL) + return E_POINTER; + + HRESULT hr = EnsureTILoaded(lcid); + *ppTInfo = m_pTypeInfo; + if (*ppTInfo) + (*ppTInfo)->AddRef(); + + return hr; + } + + STDMETHOD(GetIDsOfNames)(REFIID /*riid*/, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) + { + HRESULT hr = EnsureTILoaded(lcid); + if (SUCCEEDED(hr)) + hr = m_pTypeInfo->GetIDsOfNames(rgszNames, cNames, rgDispId); + return hr; + } + + STDMETHOD(Invoke)(DISPID dispIdMember, REFIID /*riid*/, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) + { + HRESULT hr = EnsureTILoaded(lcid); + if (SUCCEEDED(hr)) + hr = m_pTypeInfo->Invoke(this, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + return hr; + } +}; + }; // namespace ATL -- 2.17.1