Gabriel Ivăncescu : mshtml: Implement window.setTimeout with a hook.
Alexandre Julliard
julliard at winehq.org
Sat Aug 13 14:19:16 CDT 2022
Module: wine
Branch: master
Commit: 8dbdded67366fce7e1e459570d99e90a72cf52cd
URL: https://gitlab.winehq.org/wine/wine/-/commit/8dbdded67366fce7e1e459570d99e90a72cf52cd
Author: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Date: Fri Aug 12 17:07:29 2022 +0300
mshtml: Implement window.setTimeout with a hook.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at 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);
More information about the wine-cvs
mailing list