[commit] r2636 - trunk/SDK/BON/Common

GMESRC Repository Notifications gme-commit at list.isis.vanderbilt.edu
Fri Jun 17 14:35:57 CDT 2016


Author: ksmyth
Date: Fri Jun 17 14:35:57 2016
New Revision: 2636

Log:
Add IDispatch to interpreters

Modified:
   trunk/SDK/BON/Common/ComponentObj.h

Modified: trunk/SDK/BON/Common/ComponentObj.h
==============================================================================
--- trunk/SDK/BON/Common/ComponentObj.h	Fri Jun 17 14:35:54 2016	(r2635)
+++ trunk/SDK/BON/Common/ComponentObj.h	Fri Jun 17 14:35:57 2016	(r2636)
@@ -24,14 +24,138 @@
 
 class CComponentObj;
 
+struct IDispatchTearOff : public IDispatch /* final */
+{
+	long refcount;
+	IUnknown* parent;
+	IDispatch* disp;
+
+	IDispatchTearOff(IDispatch* disp, IUnknown* parent) {
+		this->disp = disp;
+		this->parent = parent;
+		parent->AddRef();
+		refcount = 1;
+	}
+
+	HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) {
+		if (riid == __uuidof(IDispatch)) {
+			this->AddRef();
+			*ppvObject = static_cast<IDispatch*>(this);
+			return S_OK;
+		}
+		return this->parent->QueryInterface(riid, ppvObject);
+	}
+
+	ULONG STDMETHODCALLTYPE AddRef() {
+		return ++this->refcount;
+	}
+
+	ULONG STDMETHODCALLTYPE Release() {
+		long refcount = --(this->refcount);
+		if (refcount == 0) {
+			this->disp->Release();
+			this->parent->Release();
+			this->disp = NULL;
+			this->parent = NULL;
+			delete this;
+		}
+		return refcount;
+	}
+
+	virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(
+		/* [out] */ __RPC__out UINT *pctinfo) {
+		return disp->GetTypeInfoCount(pctinfo);
+	}
+
+	virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(
+		/* [in] */ UINT iTInfo,
+		/* [in] */ LCID lcid,
+		/* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo) {
+		return disp->GetTypeInfo(iTInfo, lcid, ppTInfo);
+	}
+
+	virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(
+		/* [in] */ __RPC__in REFIID riid,
+		/* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,
+		/* [range][in] */ __RPC__in_range(0, 16384) UINT cNames,
+		/* [in] */ LCID lcid,
+		/* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId) {
+		return disp->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgDispId);
+	}
+
+	virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke(
+		/* [annotation][in] */
+		_In_  DISPID dispIdMember,
+		/* [annotation][in] */
+		_In_  REFIID riid,
+		/* [annotation][in] */
+		_In_  LCID lcid,
+		/* [annotation][in] */
+		_In_  WORD wFlags,
+		/* [annotation][out][in] */
+		_In_  DISPPARAMS *pDispParams,
+		/* [annotation][out] */
+		_Out_opt_  VARIANT *pVarResult,
+		/* [annotation][out] */
+		_Out_opt_  EXCEPINFO *pExcepInfo,
+		/* [annotation][out] */
+		_Out_opt_  UINT *puArgErr) {
+		return disp->Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
+	}
+
+
+};
+
+
+struct __declspec(uuid("270b4f86-b17c-11d3-9ad1-00aa00b6fe26")) /* LIBID */ ___MGALib;
+
+static HRESULT WINAPI GetIDispatchComponentEx(IMgaComponentEx* this_, REFIID riid, LPVOID* ppv) {
+    // If your interface is defined in this project
+    // option 1:
+    // wchar_t typelibPath[MAX_PATH];
+    // GetModuleFileNameW(HINST_THISCOMPONENT, thisModuleFileName, sizeof(thisModuleFileName) / sizeof(thisModuleFileName[0]));
+    // option 2:
+    // HRESULT hr = QueryPathOfRegTypeLib(LIBID_MgaComponentLib, 1, 0, 0, typelibPath.GetAddress());
+    _bstr_t typelibPath;
+    HRESULT hr = QueryPathOfRegTypeLib(__uuidof(___MGALib), 1, 0, 0, typelibPath.GetAddress());
+    ASSERT(SUCCEEDED(hr));
+    if (FAILED(hr))
+        return hr;
+
+    ITypeLibPtr typeLib;
+    hr = LoadTypeLib(static_cast<const wchar_t*>(typelibPath), &typeLib);
+    ASSERT(SUCCEEDED(hr));
+    if (FAILED(hr))
+        return hr;
+
+    ITypeInfoPtr typeInfo;
+    hr = typeLib->GetTypeInfoOfGuid(__uuidof(IMgaComponentEx), &typeInfo);
+    ASSERT(SUCCEEDED(hr));
+    if (FAILED(hr))
+        return hr;
+
+    IUnknownPtr pUnk;
+    hr = CreateStdDispatch(NULL, this_, typeInfo, &pUnk);
+    ASSERT(SUCCEEDED(hr));
+    if (FAILED(hr))
+        return hr;
+
+    IDispatchPtr pDispatch;
+    hr = pUnk->QueryInterface(__uuidof(IDispatch), (void**)&pDispatch);
+    ASSERT(SUCCEEDED(hr));
+    if (FAILED(hr))
+        return hr;
+    // n.b. cannot return pDispatch directly, as pDispatch->QI(IID_IComponentEx) will not work
+    *ppv = new IDispatchTearOff(pDispatch.Detach(), this_);
+    return S_OK;
+}
+
 #ifdef GME_ADDON
 
 #ifndef RAWCOMPONENT_H
-// BY PAKA BEGIN
 #ifndef BON2Component_h
 #error GME AddOn-s must be built with the RAW Component interface or BON2 Component Interface
 #endif // BON2Component_h
-// BY PAKA END
 #endif // RAWCOMPONENT_H
 
 class CEventSink : public CCmdTarget {
@@ -100,6 +224,22 @@
 	virtual void OnFinalRelease();
 	//}}AFX_VIRTUAL
 
+	virtual LPUNKNOWN GetInterfaceHook(const void* riid)
+	{
+		if (*((const IID*)riid) == __uuidof(IDispatch))
+		{
+			CComPtr<IMgaComponentEx> pComp;
+			IID iidIMgaComponentEx = __uuidof(IMgaComponentEx);
+			HRESULT hr = __super::ExternalQueryInterface(&iidIMgaComponentEx, (void**)&pComp.p);
+			CComPtr<IUnknown> ret;
+			if (SUCCEEDED(GetIDispatchComponentEx(pComp, *((const IID*)riid), (void**)&ret.p)))
+			{
+				return ret.Detach();
+			}
+		}
+		return NULL;
+	}
+
 // Implementation
 protected:
 	virtual ~CComponentObj();


More information about the gme-commit mailing list