2
/*#include "mscorlib.h"*/
6
const IID IID__Object = {0x65074F7F,0x63C0,0x304E,{0xAF,0x0A,0xD5,0x17,0x41,0xCB,0x4A,0x8D}};
17
void __declspec(dllexport) xcdotnet_fire_event(IDispatch *sender, IDispatch *target, IDispatch *event_args)
20
DISPPARAMS dispParams = { NULL, NULL, 0, 0 };
21
VARIANT retval, args[2];
22
XCDotNet *dotnet_sender = NULL, *dotnet_args = NULL;
24
args[1].vt = VT_DISPATCH;
25
dotnet_sender = make_XCDotNet(sender);
26
IDispatch_QueryInterface(&dotnet_sender->iface, &IID_IDispatch, (void**)&args[1].pdispVal);
27
args[0].vt = VT_DISPATCH;
28
dotnet_args = make_XCDotNet(event_args);
29
IDispatch_QueryInterface(&dotnet_args->iface, &IID_IDispatch, (void**)&args[0].pdispVal);
30
dispParams.rgvarg = args;
32
hres = IDispatch_Invoke(target, 0, &IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispParams, &retval, NULL, NULL);
33
IDispatch_Release(&dotnet_sender->iface);
34
IDispatch_Release(&dotnet_args->iface);
35
printf("Event result=%p\n", hres);
38
STDMETHODIMP xcdotnet_queryinterface(IDispatch *This, REFIID iid, void **ppvObject)
40
if (InlineIsEqualGUID(iid, &IID_IUnknown) ||
41
InlineIsEqualGUID(iid, &IID_IDispatch) ||
42
InlineIsEqualGUID(iid, &IID_IDispatchEx))
47
IDispatch_AddRef(This);
52
STDMETHODIMP_(ULONG) xcdotnet_addref(IDispatch *This)
54
((XCDotNet*)This)->m_refCount++;
58
STDMETHODIMP_(ULONG) xcdotnet_release(IDispatch *This)
60
XCDotNet *dotnet = (XCDotNet*)This;
61
if (--(dotnet->m_refCount) == 0) {
62
if (dotnet->m_objectproxy)
63
IDispatch_Release(dotnet->m_objectproxy);
69
STDMETHODIMP xcdotnet_gettypeinfocount(IDispatch *This, UINT *pctinfo)
74
STDMETHODIMP xcdotnet_gettypeinfo(IDispatch *This, UINT itinfo, LCID lcid, ITypeInfo **pptinfo)
76
return DISP_E_BADINDEX;
79
STDMETHODIMP xcdotnet_getidsofnames(IDispatch *This, REFIID iid, LPOLESTR *rgszNames, UINT cNames,
80
LCID lcid, DISPID *rgDispId)
83
return DISP_E_UNKNOWNNAME;
85
XCDotNet *dotnet = (XCDotNet*)This;
87
LPOLESTR memberName = L"GetMemberID";
88
DISPPARAMS dispParams = { NULL, NULL, 0, 0 };
90
BSTR argName = SysAllocString(rgszNames[0]);
93
hres = IDispatch_GetIDsOfNames(dotnet->m_objectproxy, &IID_NULL, &memberName, 1, lcid, &dispID);
95
arg.bstrVal = argName;
96
dispParams.rgvarg = &arg;
98
hres = IDispatch_Invoke(dotnet->m_objectproxy, dispID, &IID_NULL, lcid, DISPATCH_METHOD,
99
&dispParams, &retval, NULL, NULL);
100
if (retval.vt == VT_I4 && retval.lVal >= 0) {
101
*rgDispId = retval.lVal;
104
return DISP_E_UNKNOWNNAME;
108
STDMETHODIMP xcdotnet_invoke(IDispatch *This, DISPID dispIdMember, REFIID iid, LCID lcid, WORD wFlags,
109
DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
113
DISPPARAMS dispParams = { NULL, NULL, 0, 0 };
114
LPOLESTR memberName = L"InvokeProxy";
116
XCDotNet *dotnet = (XCDotNet*)This;
120
hres = IDispatch_GetIDsOfNames(dotnet->m_objectproxy, &IID_NULL, &memberName, 1, lcid, &dispID);
122
args[2].lVal = dispIdMember;
125
if (wFlags & DISPATCH_METHOD)
126
args[1].lVal |= InvokeMethod;
127
if (wFlags & DISPATCH_PROPERTYGET)
128
args[1].lVal |= (GetProperty | GetField);
129
if (wFlags & (DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
130
args[1].lVal |= (SetProperty | SetField);
131
if (wFlags & DISPATCH_CONSTRUCT)
132
args[1].lVal |= CreateInstance;
133
args[0].vt = VT_ARRAY;
134
argArray = SafeArrayCreateVector(VT_VARIANT, 0, pDispParams->cArgs);
135
for (i=0; i<pDispParams->cArgs; i++) {
136
if (pDispParams->rgvarg[i].vt == VT_DISPATCH &&
137
pDispParams->rgvarg[i].pdispVal->lpVtbl->Invoke == xcdotnet_invoke) {
138
pDispParams->rgvarg[i].pdispVal = ((XCDotNet*)pDispParams->rgvarg[i].pdispVal)->m_objectproxy;
140
SafeArrayPutElement(argArray, &i, &pDispParams->rgvarg[i]);
142
args[0].parray = argArray;
143
dispParams.rgvarg = args;
144
dispParams.cArgs = 3;
145
hres = IDispatch_Invoke(dotnet->m_objectproxy, dispID, &IID_NULL, lcid, DISPATCH_METHOD,
146
&dispParams, pVarResult, pExcepInfo, NULL);
147
if (pVarResult && (pVarResult->vt == VT_UNKNOWN || pVarResult->vt == VT_DISPATCH)) {
148
IDispatch *disp = NULL;
151
if (pVarResult->vt == VT_UNKNOWN) {
152
IUnknown_QueryInterface(pVarResult->punkVal, &IID__Object, &disp);
153
IUnknown_Release(pVarResult->punkVal);
155
disp = pVarResult->pdispVal;
156
dotnet = make_XCDotNet(disp);
157
pVarResult->vt = VT_DISPATCH;
158
IDispatch_QueryInterface(&dotnet->iface, &IID_IDispatch, (void**)&pVarResult->pdispVal);
164
STDMETHODIMP xcdotnet_getdispid(IDispatchEx *This, BSTR name, DWORD flags, DISPID *dispID)
166
return IDispatchEx_GetIDsOfNames(This, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, dispID);
169
STDMETHODIMP xcdotnet_invokeex(IDispatchEx *This, DISPID id, LCID lcid, WORD flags, DISPPARAMS *dispParams, VARIANT *retval, EXCEPINFO *einfo, IServiceProvider *spCaller)
171
printf("InvokeEx: %p\n", id);
172
return IDispatchEx_Invoke(This, id, &IID_NULL, lcid, flags, dispParams, retval, einfo, NULL);
175
STDMETHODIMP xcdotnet_deletememberbyname(IDispatchEx *This, BSTR name, DWORD flags)
180
STDMETHODIMP xcdotnet_deletememberbydispid(IDispatchEx *This, DISPID id)
185
STDMETHODIMP xcdotnet_getmemberproperties(IDispatchEx *This, DISPID id, DWORD flags, DWORD *pFlags)
190
STDMETHODIMP xcdotnet_getmembername(IDispatchEx *This, DISPID id, BSTR *pName)
195
STDMETHODIMP xcdotnet_getnextdispid(IDispatchEx *This, DWORD flags, DISPID id, DISPID *pid)
200
STDMETHODIMP xcdotnet_getnamespaceparent(IDispatchEx *This, IUnknown **punk)
205
static IDispatchExVtbl vtbl = {
206
xcdotnet_queryinterface,
209
xcdotnet_gettypeinfocount,
210
xcdotnet_gettypeinfo,
211
xcdotnet_getidsofnames,
215
xcdotnet_deletememberbyname,
216
xcdotnet_deletememberbydispid,
217
xcdotnet_getmemberproperties,
218
xcdotnet_getmembername,
219
xcdotnet_getnextdispid,
220
xcdotnet_getnamespaceparent
223
XCDotNet* make_XCDotNet(IDispatch *punk)
225
XCDotNet *dotnet = (XCDotNet*)LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT, sizeof(XCDotNet));
226
dotnet->iface.lpVtbl = (IDispatchVtbl*)&vtbl;
227
dotnet->m_objectproxy = punk;