The last patch will be useful later when we have to use the dispex itself.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmldoc.c | 38 ++++++++++++++++++++----------------- dlls/mshtml/tests/htmldoc.c | 10 ++++++++++ 2 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 0cf19388481..3cbd229f19e 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -4912,20 +4912,8 @@ static HRESULT WINAPI DocDispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMemb TRACE("(%p)->(%ld %s %ld %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
- switch(dispIdMember) { - case DISPID_READYSTATE: - TRACE("DISPID_READYSTATE\n"); - - if(!(wFlags & DISPATCH_PROPERTYGET)) - return E_INVALIDARG; - - V_VT(pVarResult) = VT_I4; - V_I4(pVarResult) = This->window->readystate; - return S_OK; - } - - return IDispatchEx_Invoke(This->dispex, dispIdMember, riid, lcid, wFlags, pDispParams, - pVarResult, pExcepInfo, puArgErr); + return IDispatchEx_InvokeEx(&This->IDispatchEx_iface, dispIdMember, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, NULL); }
static HRESULT WINAPI DocDispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) @@ -4945,10 +4933,26 @@ static HRESULT WINAPI DocDispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID { HTMLDocument *This = impl_from_IDispatchEx(iface);
- if(This->window && id == DISPID_IHTMLDOCUMENT2_LOCATION && (wFlags & DISPATCH_PROPERTYPUT)) - return IDispatchEx_InvokeEx(&This->window->base.IDispatchEx_iface, DISPID_IHTMLWINDOW2_LOCATION, - lcid, wFlags, pdp, pvarRes, pei, pspCaller); + if(This->window) { + switch(id) { + case DISPID_READYSTATE: + TRACE("DISPID_READYSTATE\n"); + + if(!(wFlags & DISPATCH_PROPERTYGET)) + return E_INVALIDARG;
+ V_VT(pvarRes) = VT_I4; + V_I4(pvarRes) = This->window->readystate; + return S_OK; + case DISPID_IHTMLDOCUMENT2_LOCATION: + if(!(wFlags & DISPATCH_PROPERTYPUT)) + break; + return IDispatchEx_InvokeEx(&This->window->base.IDispatchEx_iface, DISPID_IHTMLWINDOW2_LOCATION, + lcid, wFlags, pdp, pvarRes, pei, pspCaller); + default: + break; + } + }
return IDispatchEx_InvokeEx(This->dispex, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); } diff --git a/dlls/mshtml/tests/htmldoc.c b/dlls/mshtml/tests/htmldoc.c index ff050863b6f..7764f256ab0 100644 --- a/dlls/mshtml/tests/htmldoc.c +++ b/dlls/mshtml/tests/htmldoc.c @@ -5364,6 +5364,7 @@ static void _test_readyState(unsigned line, IUnknown *unk) { IHTMLDocument2 *htmldoc; DISPPARAMS dispparams; + IDispatchEx *dispex; IHTMLElement *elem; BSTR state; VARIANT out; @@ -5437,6 +5438,15 @@ static void _test_readyState(unsigned line, IUnknown *unk) ok_(__FILE__,line) (V_VT(&out) == VT_I4, "V_VT(out)=%d\n", V_VT(&out)); ok_(__FILE__,line) (V_I4(&out) == load_state%5, "VT_I4(out)=%ld, expected %d\n", V_I4(&out), load_state%5);
+ hres = IHTMLDocument2_QueryInterface(htmldoc, &IID_IDispatchEx, (void**)&dispex); + ok(hres == S_OK, "QueryInterface(IID_IDispatchEx) failed: %08lx\n", hres); + hres = IDispatchEx_InvokeEx(dispex, DISPID_READYSTATE, 0, DISPATCH_PROPERTYGET, &dispparams, &out, NULL, NULL); + ok(hres == S_OK, "InvokeEx(DISPID_READYSTATE) failed: %08lx\n", hres); + IDispatchEx_Release(dispex); + + ok_(__FILE__,line) (V_VT(&out) == VT_I4, "V_VT(out)=%d\n", V_VT(&out)); + ok_(__FILE__,line) (V_I4(&out) == load_state%5, "VT_I4(out)=%ld, expected %d\n", V_I4(&out), load_state%5); + test_doscroll((IUnknown*)htmldoc);
IHTMLDocument2_Release(htmldoc);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 49 ++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 19 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 3ab42af0fa4..3cbc4a8f3ef 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3619,24 +3619,6 @@ static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID TRACE("(%p)->(%lx %lx %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
switch(id) { - case DISPID_IHTMLWINDOW2_LOCATION: { - HTMLLocation *location; - HRESULT hres; - - if(!(wFlags & DISPATCH_PROPERTYPUT)) - break; - - TRACE("forwarding to location.href\n"); - - hres = get_location(window, &location); - if(FAILED(hres)) - return hres; - - hres = IDispatchEx_InvokeEx(&location->dispex.IDispatchEx_iface, DISPID_VALUE, lcid, - wFlags, pdp, pvarRes, pei, pspCaller); - IHTMLLocation_Release(&location->IHTMLLocation_iface); - return hres; - } case DISPID_IHTMLWINDOW2_SETTIMEOUT: case DISPID_IHTMLWINDOW3_SETTIMEOUT: { VARIANT args[2]; @@ -3912,8 +3894,37 @@ static void HTMLWindow_bind_event(DispatchEx *dispex, eventid_t eid) ensure_doc_nsevent_handler(This->doc, NULL, eid); }
+static HRESULT IHTMLWindow2_location_hook(DispatchEx *dispex, WORD flags, DISPPARAMS *dp, VARIANT *res, + EXCEPINFO *ei, IServiceProvider *caller) +{ + HTMLInnerWindow *This = impl_from_DispatchEx(dispex); + HTMLLocation *location; + HRESULT hres; + + if(!(flags & DISPATCH_PROPERTYPUT)) + return S_FALSE; + + TRACE("forwarding to location.href\n"); + + hres = get_location(This, &location); + if(FAILED(hres)) + return hres; + + hres = IDispatchEx_InvokeEx(&location->dispex.IDispatchEx_iface, DISPID_VALUE, 0, flags, dp, res, ei, caller); + IHTMLLocation_Release(&location->IHTMLLocation_iface); + return hres; +} + 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}, + /* DispHTMLWindow2 uses these from IHTMLWindow3 */ + {DISPID_IHTMLWINDOW2_SETTIMEOUT}, + {DISPID_IHTMLWINDOW2_SETINTERVAL}, + {DISPID_UNKNOWN} + }; + if(compat_mode >= COMPAT_MODE_IE9) dispex_info_add_interface(info, IHTMLWindow7_tid, NULL); else @@ -3922,6 +3933,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, IHTMLWindow2_tid, window2_hooks); EventTarget_init_dispex_info(info, compat_mode); }
@@ -3948,7 +3960,6 @@ static const event_target_vtbl_t HTMLWindow_event_target_vtbl = { };
static const tid_t HTMLWindow_iface_tids[] = { - IHTMLWindow2_tid, IHTMLWindow3_tid, IHTMLWindow4_tid, IHTMLWindow6_tid,
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 3cbc4a8f3ef..b4c377d9c4d 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,6 +3888,27 @@ 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[] = { @@ -3924,6 +3918,10 @@ static void HTMLWindow_init_dispex_info(dispex_data_t *info, compat_mode_t compa {DISPID_IHTMLWINDOW2_SETINTERVAL}, {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); @@ -3934,6 +3932,7 @@ static void HTMLWindow_init_dispex_info(dispex_data_t *info, compat_mode_t compa
dispex_info_add_interface(info, IHTMLWindow5_tid, NULL); dispex_info_add_interface(info, IHTMLWindow2_tid, window2_hooks); + dispex_info_add_interface(info, IHTMLWindow3_tid, window3_hooks); EventTarget_init_dispex_info(info, compat_mode); }
@@ -3960,7 +3959,6 @@ static const event_target_vtbl_t HTMLWindow_event_target_vtbl = { };
static const tid_t HTMLWindow_iface_tids[] = { - IHTMLWindow3_tid, IHTMLWindow4_tid, IHTMLWindow6_tid, 0 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);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmldoc.c | 48 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 3cbd229f19e..350996f893e 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -1064,6 +1064,16 @@ static HRESULT WINAPI HTMLDocument_get_location(IHTMLDocument2 *iface, IHTMLLoca return IHTMLWindow2_get_location(&This->window->base.IHTMLWindow2_iface, p); }
+static HRESULT IHTMLDocument2_location_hook(HTMLDocument *doc, WORD flags, DISPPARAMS *dp, VARIANT *res, + EXCEPINFO *ei, IServiceProvider *caller) +{ + if(!(flags & DISPATCH_PROPERTYPUT) || !doc->window) + return S_FALSE; + + return IDispatchEx_InvokeEx(&doc->window->base.IDispatchEx_iface, DISPID_IHTMLWINDOW2_LOCATION, + 0, flags, dp, res, ei, caller); +} + static HRESULT WINAPI HTMLDocument_get_lastModified(IHTMLDocument2 *iface, BSTR *p) { HTMLDocument *This = impl_from_IHTMLDocument2(iface); @@ -4944,11 +4954,6 @@ static HRESULT WINAPI DocDispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID V_VT(pvarRes) = VT_I4; V_I4(pvarRes) = This->window->readystate; return S_OK; - case DISPID_IHTMLDOCUMENT2_LOCATION: - if(!(wFlags & DISPATCH_PROPERTYPUT)) - break; - return IDispatchEx_InvokeEx(&This->window->base.IDispatchEx_iface, DISPID_IHTMLWINDOW2_LOCATION, - lcid, wFlags, pdp, pvarRes, pei, pspCaller); default: break; } @@ -5905,6 +5910,12 @@ static IHTMLEventObj *HTMLDocumentNode_set_current_event(DispatchEx *dispex, IHT return default_set_current_event(This->window, event); }
+static HRESULT HTMLDocumentNode_location_hook(DispatchEx *dispex, WORD flags, DISPPARAMS *dp, VARIANT *res, + EXCEPINFO *ei, IServiceProvider *caller) +{ + return IHTMLDocument2_location_hook(&impl_from_DispatchEx(dispex)->basedoc, flags, dp, res, ei, caller); +} + static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = { { NULL, @@ -5932,7 +5943,6 @@ static const NodeImplVtbl HTMLDocumentFragmentImplVtbl = { static const tid_t HTMLDocumentNode_iface_tids[] = { IHTMLDOMNode_tid, IHTMLDOMNode2_tid, - IHTMLDocument2_tid, IHTMLDocument4_tid, IHTMLDocument5_tid, IDocumentSelector_tid, @@ -5941,6 +5951,11 @@ static const tid_t HTMLDocumentNode_iface_tids[] = {
static void HTMLDocumentNode_init_dispex_info(dispex_data_t *info, compat_mode_t mode) { + static const dispex_hook_t document2_hooks[] = { + {DISPID_IHTMLDOCUMENT2_LOCATION, HTMLDocumentNode_location_hook}, + {DISPID_UNKNOWN} + }; + HTMLDOMNode_init_dispex_info(info, mode);
if(mode >= COMPAT_MODE_IE9) { @@ -5957,6 +5972,7 @@ static void HTMLDocumentNode_init_dispex_info(dispex_data_t *info, compat_mode_t dispex_info_add_interface(info, IHTMLDocument6_tid, NULL); dispex_info_add_interface(info, IHTMLDocument3_tid, NULL); } + dispex_info_add_interface(info, IHTMLDocument2_tid, document2_hooks); }
static dispex_static_data_t HTMLDocumentNode_dispex = { @@ -6248,18 +6264,34 @@ static const ICustomDocVtbl CustomDocVtbl = { CustomDoc_SetUIHandler };
+static HRESULT HTMLDocumentObj_location_hook(DispatchEx *dispex, WORD flags, DISPPARAMS *dp, VARIANT *res, + EXCEPINFO *ei, IServiceProvider *caller) +{ + return IHTMLDocument2_location_hook(&CONTAINING_RECORD(dispex, HTMLDocumentObj, dispex)->basedoc, flags, dp, res, ei, caller); +} + static const tid_t HTMLDocumentObj_iface_tids[] = { - IHTMLDocument2_tid, IHTMLDocument3_tid, IHTMLDocument4_tid, IHTMLDocument5_tid, 0 }; + +static void HTMLDocumentObj_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t document2_hooks[] = { + {DISPID_IHTMLDOCUMENT2_LOCATION, HTMLDocumentObj_location_hook}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLDocument2_tid, document2_hooks); +} + static dispex_static_data_t HTMLDocumentObj_dispex = { L"HTMLDocumentObj", NULL, DispHTMLDocument_tid, - HTMLDocumentObj_iface_tids + HTMLDocumentObj_iface_tids, + HTMLDocumentObj_init_dispex_info };
static HRESULT create_document_object(BOOL is_mhtml, IUnknown *outer, REFIID riid, void **ppv)
From: Gabriel Ivăncescu gabrielopcode@gmail.com
DISP_E_UNKNOWNNAME is for when retrieving the DISPID itself.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 14 +++++++------- dlls/mshtml/htmldoc.c | 4 ++-- dlls/mshtml/htmlelem.c | 2 +- dlls/mshtml/htmlelemcol.c | 2 +- dlls/mshtml/tests/events.c | 2 -- 5 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 7ab1df49cc5..3f5d4bbce76 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1009,7 +1009,7 @@ static HRESULT get_builtin_func(dispex_data_t *data, DISPID id, func_info_t **re }
WARN("invalid id %lx\n", id); - return DISP_E_UNKNOWNNAME; + return DISP_E_MEMBERNOTFOUND; }
static HRESULT get_builtin_id(DispatchEx *This, BSTR name, DWORD grfdex, DISPID *ret) @@ -1366,7 +1366,7 @@ static HRESULT invoke_builtin_prop(DispatchEx *This, DISPID id, LCID lcid, WORD HRESULT hres;
hres = get_builtin_func(This->info, id, &func); - if(id == DISPID_VALUE && hres == DISP_E_UNKNOWNNAME) + if(id == DISPID_VALUE && hres == DISP_E_MEMBERNOTFOUND) return dispex_value(This, lcid, flags, dp, res, ei, caller); if(FAILED(hres)) return hres; @@ -1686,7 +1686,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc switch(get_dispid_type(id)) { case DISPEXPROP_CUSTOM: if(!This->info->desc->vtbl || !This->info->desc->vtbl->invoke) - return DISP_E_UNKNOWNNAME; + return DISP_E_MEMBERNOTFOUND; return This->info->desc->vtbl->invoke(This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
case DISPEXPROP_DYNAMIC: { @@ -1694,7 +1694,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc dynamic_prop_t *prop;
if(!get_dynamic_data(This) || This->dynamic_data->prop_cnt <= idx) - return DISP_E_UNKNOWNNAME; + return DISP_E_MEMBERNOTFOUND;
prop = This->dynamic_data->props+idx;
@@ -1712,7 +1712,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc return invoke_disp_value(This, V_DISPATCH(&prop->var), lcid, wFlags, pdp, pvarRes, pei, pspCaller); case DISPATCH_PROPERTYGET: if(prop->flags & DYNPROP_DELETED) - return DISP_E_UNKNOWNNAME; + return DISP_E_MEMBERNOTFOUND; V_VT(pvarRes) = VT_EMPTY; return variant_copy(pvarRes, &prop->var); case DISPATCH_PROPERTYPUT: @@ -1826,7 +1826,7 @@ static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BS DWORD idx = id - DISPID_DYNPROP_0;
if(!get_dynamic_data(This) || This->dynamic_data->prop_cnt <= idx) - return DISP_E_UNKNOWNNAME; + return DISP_E_MEMBERNOTFOUND;
*pbstrName = SysAllocString(This->dynamic_data->props[idx].name); if(!*pbstrName) @@ -1874,7 +1874,7 @@ static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DWORD idx = id - DISPID_DYNPROP_0;
if(!get_dynamic_data(This) || This->dynamic_data->prop_cnt <= idx) - return DISP_E_UNKNOWNNAME; + return DISP_E_MEMBERNOTFOUND;
return next_dynamic_id(This, idx+1, pid); } diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 350996f893e..e7074952983 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -5843,7 +5843,7 @@ static HRESULT HTMLDocumentNode_invoke(DispatchEx *dispex, DISPID id, LCID lcid, i = id - MSHTML_DISPID_CUSTOM_MIN;
if(!This->nsdoc || i >= This->elem_vars_cnt) - return DISP_E_UNKNOWNNAME; + return DISP_E_MEMBERNOTFOUND;
nsAString_InitDepend(&name_str, This->elem_vars[i]); nsres = nsIDOMHTMLDocument_GetElementsByName(This->nsdoc, &name_str, &node_list); @@ -5854,7 +5854,7 @@ static HRESULT HTMLDocumentNode_invoke(DispatchEx *dispex, DISPID id, LCID lcid, nsres = nsIDOMNodeList_Item(node_list, 0, &nsnode); nsIDOMNodeList_Release(node_list); if(NS_FAILED(nsres) || !nsnode) - return DISP_E_UNKNOWNNAME; + return DISP_E_MEMBERNOTFOUND;
hres = get_node(nsnode, TRUE, &node); if(FAILED(hres)) diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index f8fa285999e..d341623d4d5 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -1124,7 +1124,7 @@ static HRESULT HTMLRectCollection_invoke(DispatchEx *dispex, DISPID id, LCID lci nsres = nsIDOMClientRectList_Item(This->rect_list, id - MSHTML_DISPID_CUSTOM_MIN, &rect); if(NS_FAILED(nsres) || !rect) { WARN("Unknown item\n"); - return DISP_E_UNKNOWNNAME; + return DISP_E_MEMBERNOTFOUND; }
hres = create_html_rect(rect, dispex_compat_mode(&This->dispex), &html_rect); diff --git a/dlls/mshtml/htmlelemcol.c b/dlls/mshtml/htmlelemcol.c index 385bd9038b2..180f75d630b 100644 --- a/dlls/mshtml/htmlelemcol.c +++ b/dlls/mshtml/htmlelemcol.c @@ -591,7 +591,7 @@ static HRESULT HTMLElementCollection_invoke(DispatchEx *dispex, DISPID id, LCID
idx = id - DISPID_ELEMCOL_0; if(idx >= This->len) - return DISP_E_UNKNOWNNAME; + return DISP_E_MEMBERNOTFOUND;
switch(flags) { case DISPATCH_PROPERTYGET: diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index c5210e721d2..87151987f16 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -2542,12 +2542,10 @@ static void test_timeout(IHTMLDocument2 *doc) 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);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmldoc.c | 28 ++++++++++++++-------------- dlls/mshtml/mshtml_private.h | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index e7074952983..94ba6a76dd0 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -4893,7 +4893,7 @@ static HRESULT WINAPI DocDispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *p { HTMLDocument *This = impl_from_IDispatchEx(iface);
- return IDispatchEx_GetTypeInfoCount(This->dispex, pctinfo); + return IDispatchEx_GetTypeInfoCount(&This->dispex->IDispatchEx_iface, pctinfo); }
static HRESULT WINAPI DocDispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, @@ -4901,7 +4901,7 @@ static HRESULT WINAPI DocDispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, { HTMLDocument *This = impl_from_IDispatchEx(iface);
- return IDispatchEx_GetTypeInfo(This->dispex, iTInfo, lcid, ppTInfo); + return IDispatchEx_GetTypeInfo(&This->dispex->IDispatchEx_iface, iTInfo, lcid, ppTInfo); }
static HRESULT WINAPI DocDispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid, @@ -4910,7 +4910,7 @@ static HRESULT WINAPI DocDispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID rii { HTMLDocument *This = impl_from_IDispatchEx(iface);
- return IDispatchEx_GetIDsOfNames(This->dispex, riid, rgszNames, cNames, lcid, rgDispId); + return IDispatchEx_GetIDsOfNames(&This->dispex->IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); }
static HRESULT WINAPI DocDispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember, @@ -4931,7 +4931,7 @@ static HRESULT WINAPI DocDispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, HTMLDocument *This = impl_from_IDispatchEx(iface); HRESULT hres;
- hres = IDispatchEx_GetDispID(This->dispex, bstrName, grfdex, pid); + hres = IDispatchEx_GetDispID(&This->dispex->IDispatchEx_iface, bstrName, grfdex, pid); if(hres != DISP_E_UNKNOWNNAME) return hres;
@@ -4959,49 +4959,49 @@ static HRESULT WINAPI DocDispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID } }
- return IDispatchEx_InvokeEx(This->dispex, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); + return IDispatchEx_InvokeEx(&This->dispex->IDispatchEx_iface, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); }
static HRESULT WINAPI DocDispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex) { HTMLDocument *This = impl_from_IDispatchEx(iface);
- return IDispatchEx_DeleteMemberByName(This->dispex, bstrName, grfdex); + return IDispatchEx_DeleteMemberByName(&This->dispex->IDispatchEx_iface, bstrName, grfdex); }
static HRESULT WINAPI DocDispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id) { HTMLDocument *This = impl_from_IDispatchEx(iface);
- return IDispatchEx_DeleteMemberByDispID(This->dispex, id); + return IDispatchEx_DeleteMemberByDispID(&This->dispex->IDispatchEx_iface, id); }
static HRESULT WINAPI DocDispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex) { HTMLDocument *This = impl_from_IDispatchEx(iface);
- return IDispatchEx_GetMemberProperties(This->dispex, id, grfdexFetch, pgrfdex); + return IDispatchEx_GetMemberProperties(&This->dispex->IDispatchEx_iface, id, grfdexFetch, pgrfdex); }
static HRESULT WINAPI DocDispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName) { HTMLDocument *This = impl_from_IDispatchEx(iface);
- return IDispatchEx_GetMemberName(This->dispex, id, pbstrName); + return IDispatchEx_GetMemberName(&This->dispex->IDispatchEx_iface, id, pbstrName); }
static HRESULT WINAPI DocDispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid) { HTMLDocument *This = impl_from_IDispatchEx(iface);
- return IDispatchEx_GetNextDispID(This->dispex, grfdex, id, pid); + return IDispatchEx_GetNextDispID(&This->dispex->IDispatchEx_iface, grfdex, id, pid); }
static HRESULT WINAPI DocDispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk) { HTMLDocument *This = impl_from_IDispatchEx(iface);
- return IDispatchEx_GetNameSpaceParent(This->dispex, ppunk); + return IDispatchEx_GetNameSpaceParent(&This->dispex->IDispatchEx_iface, ppunk); }
static const IDispatchExVtbl DocDispatchExVtbl = { @@ -5647,7 +5647,7 @@ static const cpc_entry_t HTMLDocument_cpc[] = { {NULL} };
-static void init_doc(HTMLDocument *doc, IUnknown *outer, IDispatchEx *dispex) +static void init_doc(HTMLDocument *doc, IUnknown *outer, DispatchEx *dispex) { doc->IHTMLDocument2_iface.lpVtbl = &HTMLDocumentVtbl; doc->IHTMLDocument3_iface.lpVtbl = &HTMLDocument3Vtbl; @@ -5998,7 +5998,7 @@ static HTMLDocumentNode *alloc_doc_node(HTMLDocumentObj *doc_obj, HTMLInnerWindo doc->window = window;
init_doc(&doc->basedoc, (IUnknown*)&doc->node.IHTMLDOMNode_iface, - &doc->node.event_target.dispex.IDispatchEx_iface); + &doc->node.event_target.dispex); HTMLDocumentNode_SecMgr_Init(doc);
list_init(&doc->selection_list); @@ -6319,7 +6319,7 @@ static HRESULT create_document_object(BOOL is_mhtml, IUnknown *outer, REFIID rii doc->basedoc.doc_obj = doc;
init_dispatch(&doc->dispex, (IUnknown*)&doc->ICustomDoc_iface, &HTMLDocumentObj_dispex, COMPAT_MODE_QUIRKS); - init_doc(&doc->basedoc, outer ? outer : &doc->IUnknown_inner, &doc->dispex.IDispatchEx_iface); + init_doc(&doc->basedoc, outer ? outer : &doc->IUnknown_inner, &doc->dispex); TargetContainer_Init(doc); doc->is_mhtml = is_mhtml;
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 05b37c6b9db..c4215a409e3 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -665,7 +665,7 @@ struct HTMLDocument { IDocumentRange IDocumentRange_iface;
IUnknown *outer_unk; - IDispatchEx *dispex; + DispatchEx *dispex;
HTMLDocumentObj *doc_obj; HTMLDocumentNode *doc_node;
Jacek Caban (@jacek) commented about dlls/mshtml/htmlwindow.c:
- if(FAILED(hres))
return hres;
- hres = IDispatchEx_InvokeEx(&location->dispex.IDispatchEx_iface, DISPID_VALUE, 0, flags, dp, res, ei, caller);
- IHTMLLocation_Release(&location->IHTMLLocation_iface);
- return hres;
+}
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},
/* DispHTMLWindow2 uses these from IHTMLWindow3 */
{DISPID_IHTMLWINDOW2_SETTIMEOUT},
{DISPID_IHTMLWINDOW2_SETINTERVAL},
{DISPID_UNKNOWN}
You can achieve this by adding interfaces in the right order, there is no need for such weird constructs.
For location and setTimeout themselves, it also seems possible to use the private interface, but maybe that's for another day...
Jacek Caban (@jacek) commented about dlls/mshtml/mshtml_private.h:
IDocumentRange IDocumentRange_iface; IUnknown *outer_unk;
- IDispatchEx *dispex;
- DispatchEx *dispex;
I don't know why you need this, but general plan is to get rid of HTMLDocument struct and have HTMLDocumentNode and HTMLDocumentObj entirely separated. I did some work on this in the past, but I never had time to finish it. It's probably better to change whatever code needs this change to not use that pointer at all.
On Thu Aug 11 18:48:33 2022 +0000, Jacek Caban wrote:
You can achieve this by adding interfaces in the right order, there is no need for such weird constructs. For location and setTimeout themselves, it also seems possible to use the private interface, but maybe that's for another day...
Oh I see, I thought there was a reason they were in the given order, didn't want to mess something up.
As for the private interface, we don't currently expose a private interface for all compat modes, and this hook/behavior needs to apply to all modes.
On Thu Aug 11 18:57:06 2022 +0000, Jacek Caban wrote:
I don't know why you need this, but general plan is to get rid of HTMLDocument struct and have HTMLDocumentNode and HTMLDocumentObj entirely separated. I did some work on this in the past, but I never had time to finish it. It's probably better to change whatever code needs this change to not use that pointer at all.
I'll later need to access the dispex itself e.g. for jscript proxy forwarding, but won't be very soon, so I can drop this patch for now, and keep it for later if still needed.
I sent it now because I just thought it's more along the lines of "general improvement" to store the actual object pointer since we know it's always the same type in this case. But no problem dropping if you still don't want it.
(personally, when I read code, for me storing an interface is *usually* more akin to meaning something like "might have different types of objects implementing same interface").