diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 3f39a4ece7d..ec856143715 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -400,4 +400,9 @@ End Class Call testDisp(new testClass) +Set obj = New TestClass + +Call ok(obj.publicFunction = 4, "obj.publicFunction = " & obj.publicFunction) +Call ok(obj.publicFunction() = 4, "obj.publicFunction() = " & obj.publicFunction()) + reportSuccess() diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index fb6302aba8d..d98cf383f4c 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -144,7 +144,11 @@ static BOOL is_english(void) static void test_disp(IDispatch *disp) { DISPID id, public_func_id, public_sub_id; + DISPID named_args[5] = {DISPID_PROPERTYPUT}; + VARIANT v, args[5]; + DISPPARAMS dp = {args, named_args}; IDispatchEx *dispex; + EXCEPINFO ei = {0}; BSTR str; HRESULT hres; @@ -163,6 +167,28 @@ static void test_disp(IDispatch *disp) ok(hres == S_OK, "GetDispID(publicSub) failed: %08x\n", hres); ok(public_sub_id != -1, "public_func_id = -1\n"); + dp.cArgs = dp.cNamedArgs = 0; + hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL); + ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v)); + ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v)); + + dp.cArgs = dp.cNamedArgs = 0; + hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL); + ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v)); + ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v)); + + dp.cArgs = dp.cNamedArgs = 0; + hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL); + ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v)); + + dp.cArgs = dp.cNamedArgs = 0; + hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL); + ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v)); + str = a2bstr("privateSub"); hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id); SysFreeString(str); diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c index 77837c63412..2b609269a42 100644 --- a/dlls/vbscript/vbdisp.c +++ b/dlls/vbscript/vbdisp.c @@ -22,6 +22,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(vbscript); +static inline BOOL is_func_id(vbdisp_t *This, DISPID id) +{ + return id < This->desc->func_cnt; +} + static BOOL get_func_id(vbdisp_t *This, const WCHAR *name, BOOL search_private, DISPID *id) { unsigned i; @@ -150,7 +155,35 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { vbdisp_t *This = impl_from_IDispatchEx(iface); - FIXME("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); + + TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); + + if(pvarRes) + V_VT(pvarRes) = VT_EMPTY; + + if(id < 0) + return DISP_E_MEMBERNOTFOUND; + + if(is_func_id(This, id)) { + function_t *func; + + switch(wFlags) { + case DISPATCH_METHOD: + case DISPATCH_METHOD|DISPATCH_PROPERTYGET: + func = This->desc->funcs[id].entries[VBDISP_CALLGET]; + if(!func) { + FIXME("no invoke/getter\n"); + return DISP_E_MEMBERNOTFOUND; + } + + return exec_script(This->desc->ctx, func, pdp, pvarRes); + default: + FIXME("flags %x\n", wFlags); + return DISP_E_MEMBERNOTFOUND; + } + } + + FIXME("not implemented for non-function ids\n"); return DISP_E_MEMBERNOTFOUND; }