Author: tfaber
Date: Fri Apr 8 08:38:48 2016
New Revision: 71117
URL:
http://svn.reactos.org/svn/reactos?rev=71117&view=rev
Log:
[ATL]
- Add a basic implementation for IDispatchImpl. Patch by Mark Jansen.
CORE-11087
Modified:
trunk/reactos/lib/atl/atlbase.h
trunk/reactos/lib/atl/atlcom.h
Modified: trunk/reactos/lib/atl/atlbase.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atlbase.h?rev=7111…
==============================================================================
--- trunk/reactos/lib/atl/atlbase.h [iso-8859-1] (original)
+++ trunk/reactos/lib/atl/atlbase.h [iso-8859-1] Fri Apr 8 08:38:48 2016
@@ -395,9 +395,9 @@
class CAtlModule : public _ATL_MODULE
{
-protected:
+public:
static GUID m_libid;
-public:
+
CAtlModule()
{
ATLASSERT(_pAtlModule == NULL);
Modified: trunk/reactos/lib/atl/atlcom.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atlcom.h?rev=71117…
==============================================================================
--- trunk/reactos/lib/atl/atlcom.h [iso-8859-1] (original)
+++ trunk/reactos/lib/atl/atlcom.h [iso-8859-1] Fri Apr 8 08:38:48 2016
@@ -1434,4 +1434,91 @@
{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 T, const IID* piid /*= &__uuidof(T)*/, const GUID* plibid =
&CAtlModule::m_libid, WORD wMajor = 1, WORD wMinor = 0>
+class IDispatchImpl :
+ public T
+{
+private:
+ CComPtr<ITypeInfo> 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<ITypeLib> 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