X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Flib%2Fatl%2Fatlcom.h;h=98d0ca08a88ebaacd063b5cdcaf8ab4fb23dbb9b;hp=2a537d3bcc98130620991ea6613179f33c5106fa;hb=ee729a69a3ea3b2f9b8b2fc302a0431f65dd8db4;hpb=78a727d095a6cedc195a54d9299ef5f685f33f31 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