From 089d54f1f4248d18bfce089aec90a1517b9a4b3c Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Sun, 24 Jan 2010 21:37:52 +0100 Subject: [PATCH] mshtml: Added support for pure IDispatch event handlers. --- dlls/mshtml/dispex.c | 17 +++++++------- dlls/mshtml/tests/events.c | 47 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 4019a3c54a0..ca093130542 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -400,18 +400,19 @@ HRESULT call_disp_func(IDispatch *disp, DISPPARAMS *dp) VARIANT res; HRESULT hres; - hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); - if(FAILED(hres)) { - FIXME("Could not get IDispatchEx interface: %08x\n", hres); - return hres; - } - VariantInit(&res); memset(&ei, 0, sizeof(ei)); - hres = IDispatchEx_InvokeEx(dispex, 0, GetUserDefaultLCID(), DISPATCH_METHOD, dp, &res, &ei, NULL); + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + if(SUCCEEDED(hres)) { + hres = IDispatchEx_InvokeEx(dispex, 0, GetUserDefaultLCID(), DISPATCH_METHOD, dp, &res, &ei, NULL); + IDispatchEx_Release(dispex); + }else { + TRACE("Could not get IDispatchEx interface: %08x\n", hres); + hres = IDispatch_Invoke(disp, 0, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, + dp, &res, &ei, NULL); + } - IDispatchEx_Release(dispex); VariantClear(&res); return hres; } diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 84bfae25347..81e7cab7fce 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -63,6 +63,7 @@ DEFINE_EXPECT(div_onclick); DEFINE_EXPECT(div_onclick_attached); DEFINE_EXPECT(timeout); DEFINE_EXPECT(doccp_onclick); +DEFINE_EXPECT(div_onclick_disp); DEFINE_EXPECT(iframe_onreadystatechange_loading); DEFINE_EXPECT(iframe_onreadystatechange_interactive); DEFINE_EXPECT(iframe_onreadystatechange_complete); @@ -690,6 +691,23 @@ static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, return S_OK; } +static HRESULT WINAPI Dispatch_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv) +{ + *ppv = NULL; + + if(IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDispatch)) { + *ppv = iface; + }else if(IsEqualGUID(riid, &IID_IDispatchEx)) { + return E_NOINTERFACE; + }else { + ok(0, "unexpected riid %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + return S_OK; +} + static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface) { return 2; @@ -1015,6 +1033,32 @@ static IDispatchExVtbl timeoutFuncVtbl = { static IDispatchEx timeoutFunc = { &timeoutFuncVtbl }; +static HRESULT WINAPI div_onclick_disp_Invoke(IDispatchEx *iface, DISPID id, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, UINT *puArgErr) +{ + CHECK_EXPECT(div_onclick_disp); + + test_attached_event_args(id, wFlags, pdp, pvarRes, pei); + + ok(IsEqualGUID(&IID_NULL, riid), "riid = %s\n", debugstr_guid(riid)); + ok(!puArgErr, "puArgErr = %p\n", puArgErr); + + return S_OK; +} + +static IDispatchExVtbl div_onclick_dispVtbl = { + Dispatch_QueryInterface, + DispatchEx_AddRef, + DispatchEx_Release, + DispatchEx_GetTypeInfoCount, + DispatchEx_GetTypeInfo, + DispatchEx_GetIDsOfNames, + div_onclick_disp_Invoke, +}; + +static IDispatchEx div_onclick_disp = { &div_onclick_dispVtbl }; + static void pump_msgs(BOOL *b) { MSG msg; @@ -1163,8 +1207,10 @@ static void test_onclick(IHTMLDocument2 *doc) CHECK_CALLED(document_onclick); cp_cookie = register_cp((IUnknown*)doc, &DIID_HTMLDocumentEvents, (IUnknown*)&doccp_obj); + elem_attach_event((IUnknown*)div, "onclick", (IDispatch*)&div_onclick_disp); SET_EXPECT(div_onclick); + SET_EXPECT(div_onclick_disp); SET_EXPECT(div_onclick_attached); SET_EXPECT(body_onclick); SET_EXPECT(document_onclick); @@ -1174,6 +1220,7 @@ static void test_onclick(IHTMLDocument2 *doc) ok(hres == S_OK, "click failed: %08x\n", hres); CHECK_CALLED(div_onclick); + CHECK_CALLED(div_onclick_disp); CHECK_CALLED(div_onclick_attached); CHECK_CALLED(body_onclick); CHECK_CALLED(document_onclick);