From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 56 ++++++++++++++++++-------------------- dlls/mshtml/tests/events.c | 26 +++++++++++++++++- 2 files changed, 52 insertions(+), 30 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index c3267e1e4ca..0043fb79731 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3614,34 +3614,7 @@ static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { HTMLWindow *This = impl_from_IDispatchEx(iface); - HTMLInnerWindow *window = This->inner_window; - - TRACE("(%p)->(%lx %lx %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); - - switch(id) { - case DISPID_IHTMLWINDOW2_SETTIMEOUT: - case DISPID_IHTMLWINDOW3_SETTIMEOUT: { - VARIANT args[2]; - DISPPARAMS dp = {args, NULL, 2, 0}; - - /* - * setTimeout calls should use default value 0 for the second argument if only one is provided, - * but IDL file does not reflect that. We fixup arguments here instead. - */ - if(!(wFlags & DISPATCH_METHOD) || pdp->cArgs != 1 || pdp->cNamedArgs) - break; - - TRACE("Fixing args\n"); - - V_VT(args) = VT_I4; - V_I4(args) = 0; - args[1] = *pdp->rgvarg; - return IDispatchEx_InvokeEx(&window->event_target.dispex.IDispatchEx_iface, id, lcid, - wFlags, &dp, pvarRes, pei, pspCaller); - } - } - - return IDispatchEx_InvokeEx(&window->event_target.dispex.IDispatchEx_iface, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); + return IDispatchEx_InvokeEx(&This->inner_window->event_target.dispex.IDispatchEx_iface, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); }
static HRESULT WINAPI WindowDispEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex) @@ -3915,12 +3888,37 @@ static HRESULT IHTMLWindow2_location_hook(DispatchEx *dispex, WORD flags, DISPPA return hres; }
+static HRESULT IHTMLWindow3_setTimeout_hook(DispatchEx *dispex, WORD flags, DISPPARAMS *dp, VARIANT *res, + EXCEPINFO *ei, IServiceProvider *caller) +{ + VARIANT args[2]; + DISPPARAMS new_dp = { args, NULL, 2, 0 }; + + /* + * setTimeout calls should use default value 0 for the second argument if only one is provided, + * but IDL file does not reflect that. We fixup arguments here instead. + */ + if(!(flags & DISPATCH_METHOD) || dp->cArgs != 1 || dp->cNamedArgs) + return S_FALSE; + + TRACE("Fixing args\n"); + + V_VT(args) = VT_I4; + V_I4(args) = 0; + args[1] = dp->rgvarg[0]; + return dispex_call_builtin(dispex, DISPID_IHTMLWINDOW3_SETTIMEOUT, &new_dp, res, ei, caller); +} + static void HTMLWindow_init_dispex_info(dispex_data_t *info, compat_mode_t compat_mode) { static const dispex_hook_t window2_hooks[] = { {DISPID_IHTMLWINDOW2_LOCATION, IHTMLWindow2_location_hook}, {DISPID_UNKNOWN} }; + static const dispex_hook_t window3_hooks[] = { + {DISPID_IHTMLWINDOW3_SETTIMEOUT, IHTMLWindow3_setTimeout_hook}, + {DISPID_UNKNOWN} + };
if(compat_mode >= COMPAT_MODE_IE9) dispex_info_add_interface(info, IHTMLWindow7_tid, NULL); @@ -3930,7 +3928,7 @@ static void HTMLWindow_init_dispex_info(dispex_data_t *info, compat_mode_t compa dispex_info_add_interface(info, IWineHTMLWindowPrivate_tid, NULL);
dispex_info_add_interface(info, IHTMLWindow5_tid, NULL); - dispex_info_add_interface(info, IHTMLWindow3_tid, NULL); + dispex_info_add_interface(info, IHTMLWindow3_tid, window3_hooks); dispex_info_add_interface(info, IHTMLWindow2_tid, window2_hooks); EventTarget_init_dispex_info(info, compat_mode); } diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 95ed071bf78..c5210e721d2 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -2523,11 +2523,35 @@ static void test_submit(IHTMLDocument2 *doc)
static void test_timeout(IHTMLDocument2 *doc) { + VARIANT expr, var, args[2]; + DISPPARAMS dp = { args, NULL, 2, 0 }; IHTMLWindow3 *win3; - VARIANT expr, var; + IDispatch *disp; + UINT argerr; LONG id; HRESULT hres;
+ /* First try the IHTMLWindow2 DISPIDs via IDispatch, since they're not exposed */ + hres = IHTMLWindow2_QueryInterface(window, &IID_IDispatch, (void**)&disp); + ok(hres == S_OK, "Could not get IDispatch iface: %08lx\n", hres); + + V_VT(&args[1]) = VT_BSTR; + V_BSTR(&args[1]) = SysAllocString(L""); + V_VT(&args[0]) = VT_I4; + V_I4(&args[0]) = 1; + V_VT(&var) = VT_EMPTY; + hres = IDispatch_Invoke(disp, DISPID_IHTMLWINDOW2_SETINTERVAL, &IID_NULL, LOCALE_USER_DEFAULT, + DISPATCH_METHOD, &dp, &var, NULL, &argerr); + todo_wine + ok(hres == DISP_E_MEMBERNOTFOUND, "Invoke(DISPID_IHTMLWINDOW2_SETINTERVAL) returned: %08lx\n", hres); + + hres = IDispatch_Invoke(disp, DISPID_IHTMLWINDOW2_SETTIMEOUT, &IID_NULL, LOCALE_USER_DEFAULT, + DISPATCH_METHOD, &dp, &var, NULL, &argerr); + todo_wine + ok(hres == DISP_E_MEMBERNOTFOUND, "Invoke(DISPID_IHTMLWINDOW2_SETTIMEOUT) returned: %08lx\n", hres); + SysFreeString(V_BSTR(&args[1])); + IDispatch_Release(disp); + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow3, (void**)&win3); ok(hres == S_OK, "Could not get IHTMLWindow3 iface: %08lx\n", hres);