[MSHTML_WINETEST]
[reactos.git] / rostests / winetests / mshtml / events.c
1 /*
2 * Copyright 2008-2011 Jacek Caban for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #define COBJMACROS
20 #define CONST_VTABLE
21
22 #include <wine/test.h>
23 //#include <stdarg.h>
24 #include <stdio.h>
25
26 //#include "windef.h"
27 //#include "winbase.h"
28 //#include "ole2.h"
29 #include <mshtml.h>
30 #include <mshtmdid.h>
31 #include <docobj.h>
32 #include <hlink.h>
33 //#include "dispex.h"
34
35 #define DEFINE_EXPECT(func) \
36 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
37
38 #define SET_EXPECT(func) \
39 do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
40
41 #define CHECK_EXPECT2(func) \
42 do { \
43 trace(#func "\n"); \
44 ok(expect_ ##func, "unexpected call " #func "\n"); \
45 called_ ## func = TRUE; \
46 }while(0)
47
48 #define CHECK_EXPECT(func) \
49 do { \
50 CHECK_EXPECT2(func); \
51 expect_ ## func = FALSE; \
52 }while(0)
53
54 #define CHECK_CALLED(func) \
55 do { \
56 ok(called_ ## func, "expected " #func "\n"); \
57 expect_ ## func = called_ ## func = FALSE; \
58 }while(0)
59
60 DEFINE_EXPECT(document_onclick);
61 DEFINE_EXPECT(body_onclick);
62 DEFINE_EXPECT(doc_onclick_attached);
63 DEFINE_EXPECT(div_onclick);
64 DEFINE_EXPECT(div_onclick_attached);
65 DEFINE_EXPECT(timeout);
66 DEFINE_EXPECT(doccp_onclick);
67 DEFINE_EXPECT(doccp_onclick_cancel);
68 DEFINE_EXPECT(div_onclick_disp);
69 DEFINE_EXPECT(invoke_onclick);
70 DEFINE_EXPECT(iframe_onreadystatechange_loading);
71 DEFINE_EXPECT(iframe_onreadystatechange_interactive);
72 DEFINE_EXPECT(iframe_onreadystatechange_complete);
73 DEFINE_EXPECT(iframedoc_onreadystatechange);
74 DEFINE_EXPECT(img_onload);
75 DEFINE_EXPECT(img_onerror);
76 DEFINE_EXPECT(input_onfocus);
77 DEFINE_EXPECT(input_onblur);
78 DEFINE_EXPECT(form_onsubmit);
79 DEFINE_EXPECT(form_onclick);
80 DEFINE_EXPECT(submit_onclick);
81 DEFINE_EXPECT(submit_onclick_cancel);
82 DEFINE_EXPECT(submit_onclick_attached);
83 DEFINE_EXPECT(submit_onclick_attached_check_cancel);
84 DEFINE_EXPECT(submit_onclick_setret);
85 DEFINE_EXPECT(elem2_cp_onclick);
86 DEFINE_EXPECT(iframe_onload);
87
88 static HWND container_hwnd = NULL;
89 static IHTMLWindow2 *window;
90 static IOleDocumentView *view;
91 static BOOL is_ie9plus;
92
93 typedef struct {
94 LONG x;
95 LONG y;
96 LONG offset_x;
97 LONG offset_y;
98 } xy_test_t;
99
100 static const xy_test_t no_xy = {-10,-10,-10,-10};
101 static const xy_test_t zero_xy = {0,0,0,0};
102
103 static const char empty_doc_str[] =
104 "<html></html>";
105
106 static const char click_doc_str[] =
107 "<html><body>"
108 "<div id=\"clickdiv\" style=\"text-align: center; background: red; font-size: 32\">click here</div>"
109 "</body></html>";
110
111 static const char readystate_doc_str[] =
112 "<html><body><iframe id=\"iframe\"></iframe></body></html>";
113
114 static const char img_doc_str[] =
115 "<html><body><img id=\"imgid\"></img></body></html>";
116
117 static const char input_doc_str[] =
118 "<html><body><input id=\"inputid\"></input></body></html>";
119
120 static const char iframe_doc_str[] =
121 "<html><body><iframe id=\"ifr\">Testing</iframe></body></html>";
122
123 static const char form_doc_str[] =
124 "<html><body><form id=\"formid\" method=\"post\" action=\"about:blank\">"
125 "<input type=\"text\" value=\"test\" name=\"i\"/>"
126 "<input type=\"submit\" id=\"submitid\" />"
127 "</form></body></html>";
128
129 static int strcmp_wa(LPCWSTR strw, const char *stra)
130 {
131 CHAR buf[512];
132 WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
133 return lstrcmpA(stra, buf);
134 }
135
136 static BSTR a2bstr(const char *str)
137 {
138 BSTR ret;
139 int len;
140
141 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
142 ret = SysAllocStringLen(NULL, len-1);
143 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
144
145 return ret;
146 }
147
148 static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2)
149 {
150 IUnknown *unk1, *unk2;
151
152 if(iface1 == iface2)
153 return TRUE;
154
155 IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk1);
156 IUnknown_Release(unk1);
157 IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk2);
158 IUnknown_Release(unk2);
159
160 return unk1 == unk2;
161 }
162
163 #define test_disp(u,id) _test_disp(__LINE__,u,id)
164 static void _test_disp(unsigned line, IUnknown *unk, const IID *diid)
165 {
166 IDispatchEx *dispex;
167 ITypeInfo *typeinfo;
168 UINT ticnt;
169 HRESULT hres;
170
171 hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
172 ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatch: %08x\n", hres);
173 if(FAILED(hres))
174 return;
175
176 ticnt = 0xdeadbeef;
177 hres = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
178 ok_(__FILE__,line) (hres == S_OK, "GetTypeInfoCount failed: %08x\n", hres);
179 ok_(__FILE__,line) (ticnt == 1, "ticnt=%u\n", ticnt);
180
181 hres = IDispatchEx_GetTypeInfo(dispex, 0, 0, &typeinfo);
182 ok_(__FILE__,line) (hres == S_OK, "GetTypeInfo failed: %08x\n", hres);
183
184 if(SUCCEEDED(hres)) {
185 TYPEATTR *type_attr;
186
187 hres = ITypeInfo_GetTypeAttr(typeinfo, &type_attr);
188 ok_(__FILE__,line) (hres == S_OK, "GetTypeAttr failed: %08x\n", hres);
189 ok_(__FILE__,line) (IsEqualGUID(&type_attr->guid, diid), "unexpected guid %s\n",
190 wine_dbgstr_guid(&type_attr->guid));
191
192 ITypeInfo_ReleaseTypeAttr(typeinfo, type_attr);
193 ITypeInfo_Release(typeinfo);
194 }
195
196 IDispatchEx_Release(dispex);
197 }
198
199 #define get_doc3_iface(u) _get_doc3_iface(__LINE__,u)
200 static IHTMLDocument3 *_get_doc3_iface(unsigned line, IUnknown *unk)
201 {
202 IHTMLDocument3 *doc3;
203 HRESULT hres;
204
205 hres = IUnknown_QueryInterface(unk, &IID_IHTMLDocument3, (void**)&doc3);
206 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
207
208 return doc3;
209 }
210
211 #define get_elem_iface(u) _get_elem_iface(__LINE__,u)
212 static IHTMLElement *_get_elem_iface(unsigned line, IUnknown *unk)
213 {
214 IHTMLElement *elem;
215 HRESULT hres;
216
217 hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement, (void**)&elem);
218 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement iface: %08x\n", hres);
219
220 return elem;
221 }
222
223 #define get_elem2_iface(u) _get_elem2_iface(__LINE__,u)
224 static IHTMLElement2 *_get_elem2_iface(unsigned line, IUnknown *unk)
225 {
226 IHTMLElement2 *elem2;
227 HRESULT hres;
228
229 hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement2, (void**)&elem2);
230 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement2 iface: %08x\n", hres);
231
232 return elem2;
233 }
234
235 #define get_elem3_iface(u) _get_elem3_iface(__LINE__,u)
236 static IHTMLElement3 *_get_elem3_iface(unsigned line, IUnknown *unk)
237 {
238 IHTMLElement3 *elem3;
239 HRESULT hres;
240
241 hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement3, (void**)&elem3);
242 ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement3 iface: %08x\n", hres);
243
244 return elem3;
245 }
246
247 #define get_iframe_iface(u) _get_iframe_iface(__LINE__,u)
248 static IHTMLIFrameElement *_get_iframe_iface(unsigned line, IUnknown *unk)
249 {
250 IHTMLIFrameElement *iframe;
251 HRESULT hres;
252
253 hres = IUnknown_QueryInterface(unk, &IID_IHTMLIFrameElement, (void**)&iframe);
254 ok_(__FILE__,line)(hres == S_OK, "QueryInterface(IID_IHTMLIFrameElement) failed: %08x\n", hres);
255
256 return iframe;
257 }
258
259 #define doc_get_body(d) _doc_get_body(__LINE__,d)
260 static IHTMLElement *_doc_get_body(unsigned line, IHTMLDocument2 *doc)
261 {
262 IHTMLElement *body = NULL;
263 HRESULT hres;
264
265 hres = IHTMLDocument2_get_body(doc, &body);
266 ok_(__FILE__,line) (hres == S_OK, "get_body failed: %08x\n", hres);
267 ok_(__FILE__,line) (body != NULL, "body == NULL\n");
268
269 return body;
270 }
271
272 #define get_elem_id(d,i) _get_elem_id(__LINE__,d,i)
273 static IHTMLElement *_get_elem_id(unsigned line, IHTMLDocument2 *doc, const char *id)
274 {
275 IHTMLDocument3 *doc3 = _get_doc3_iface(line, (IUnknown*)doc);
276 IHTMLElement *elem;
277 BSTR str;
278 HRESULT hres;
279
280 str = a2bstr(id);
281 hres = IHTMLDocument3_getElementById(doc3, str, &elem);
282 SysFreeString(str);
283 IHTMLDocument3_Release(doc3);
284 ok_(__FILE__,line) (hres == S_OK, "getElementById failed: %08x\n", hres);
285
286 return elem;
287 }
288
289 #define test_elem_tag(u,n) _test_elem_tag(__LINE__,u,n)
290 static void _test_elem_tag(unsigned line, IUnknown *unk, const char *extag)
291 {
292 IHTMLElement *elem = _get_elem_iface(line, unk);
293 BSTR tag;
294 HRESULT hres;
295
296 hres = IHTMLElement_get_tagName(elem, &tag);
297 IHTMLElement_Release(elem);
298 ok_(__FILE__, line) (hres == S_OK, "get_tagName failed: %08x\n", hres);
299 ok_(__FILE__, line) (!strcmp_wa(tag, extag), "got tag: %s, expected %s\n", wine_dbgstr_w(tag), extag);
300
301 SysFreeString(tag);
302 }
303
304 #define get_event_obj() _get_event_obj(__LINE__)
305 static IHTMLEventObj *_get_event_obj(unsigned line)
306 {
307 IHTMLEventObj *event = NULL;
308 HRESULT hres;
309
310 hres = IHTMLWindow2_get_event(window, &event);
311 ok_(__FILE__,line) (hres == S_OK, "get_event failed: %08x\n", hres);
312 ok_(__FILE__,line) (event != NULL, "event = NULL\n");
313 _test_disp(line, (IUnknown*)event, &DIID_DispCEventObj);
314
315 return event;
316 }
317
318 #define elem_fire_event(a,b,c) _elem_fire_event(__LINE__,a,b,c)
319 static void _elem_fire_event(unsigned line, IUnknown *unk, const char *event, VARIANT *evobj)
320 {
321 IHTMLElement3 *elem3 = _get_elem3_iface(line, unk);
322 VARIANT_BOOL b;
323 BSTR str;
324 HRESULT hres;
325
326 b = 100;
327 str = a2bstr(event);
328 hres = IHTMLElement3_fireEvent(elem3, str, evobj, &b);
329 SysFreeString(str);
330 ok_(__FILE__,line)(hres == S_OK, "fireEvent failed: %08x\n", hres);
331 ok_(__FILE__,line)(b == VARIANT_TRUE, "fireEvent returned %x\n", b);
332 }
333
334 #define test_event_args(a,b,c,d,e,f,g) _test_event_args(__LINE__,a,b,c,d,e,f,g)
335 static void _test_event_args(unsigned line, const IID *dispiid, DISPID id, WORD wFlags, DISPPARAMS *pdp,
336 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
337 {
338 ok_(__FILE__,line) (id == DISPID_VALUE, "id = %d\n", id);
339 ok_(__FILE__,line) (wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
340 ok_(__FILE__,line) (pdp != NULL, "pdp == NULL\n");
341 ok_(__FILE__,line) (pdp->cArgs == 1, "pdp->cArgs = %d\n", pdp->cArgs);
342 ok_(__FILE__,line) (pdp->cNamedArgs == 1, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
343 ok_(__FILE__,line) (pdp->rgdispidNamedArgs[0] == DISPID_THIS, "pdp->rgdispidNamedArgs[0] = %d\n",
344 pdp->rgdispidNamedArgs[0]);
345 ok_(__FILE__,line) (V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg));
346 ok_(__FILE__,line) (pvarRes != NULL, "pvarRes == NULL\n");
347 ok_(__FILE__,line) (pei != NULL, "pei == NULL");
348 ok_(__FILE__,line) (!pspCaller, "pspCaller != NULL\n");
349
350 if(dispiid)
351 _test_disp(line, (IUnknown*)V_DISPATCH(pdp->rgvarg), dispiid);
352 }
353
354 #define test_attached_event_args(a,b,c,d,e) _test_attached_event_args(__LINE__,a,b,c,d,e)
355 static void _test_attached_event_args(unsigned line, DISPID id, WORD wFlags, DISPPARAMS *pdp,
356 VARIANT *pvarRes, EXCEPINFO *pei)
357 {
358 IHTMLEventObj *event;
359
360 ok(id == DISPID_VALUE, "id = %d\n", id);
361 ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
362 ok(pdp != NULL, "pDispParams == NULL\n");
363 ok(pdp->cArgs == 1, "pdp->cArgs = %d\n", pdp->cArgs);
364 ok(!pdp->cNamedArgs, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
365 ok(!pdp->rgdispidNamedArgs, "pdp->rgdispidNamedArgs = %p\n", pdp->rgdispidNamedArgs);
366 ok(pdp->rgvarg != NULL, "rgvarg = NULL\n");
367 ok(pvarRes != NULL, "pvarRes = NULL\n");
368 ok(pei != NULL, "pei = NULL\n");
369 ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pVarRes) = %d\n", V_VT(pvarRes));
370 ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
371 ok(V_DISPATCH(pdp->rgvarg) != NULL, "V_DISPATCH(pdp->rgvarg) = %p\n", V_DISPATCH(pdp->rgvarg));
372
373 event = _get_event_obj(line);
374 ok(iface_cmp((IUnknown*)event, (IUnknown*)V_DISPATCH(pdp->rgvarg)), "event != arg0\n");
375 IHTMLEventObj_Release(event);
376 }
377
378 #define get_event_src() _get_event_src(__LINE__)
379 static IHTMLElement *_get_event_src(unsigned line)
380 {
381 IHTMLEventObj *event = _get_event_obj(line);
382 IHTMLElement *src_elem = NULL;
383 HRESULT hres;
384
385 hres = IHTMLEventObj_get_srcElement(event, &src_elem);
386 IHTMLEventObj_Release(event);
387 ok_(__FILE__,line) (hres == S_OK, "get_srcElement failed: %08x\n", hres);
388
389 return src_elem;
390 }
391
392 #define test_event_src(t) _test_event_src(__LINE__,t)
393 static void _test_event_src(unsigned line, const char *src_tag)
394 {
395 IHTMLElement *src_elem = _get_event_src(line);
396
397 if(src_tag) {
398 ok_(__FILE__,line) (src_elem != NULL, "src_elem = NULL\n");
399 _test_elem_tag(line, (IUnknown*)src_elem, src_tag);
400 IHTMLElement_Release(src_elem);
401 }else {
402 ok_(__FILE__,line) (!src_elem, "src_elem != NULL\n");
403 }
404 }
405
406 static void _test_event_altkey(unsigned line, IHTMLEventObj *event, VARIANT_BOOL exval)
407 {
408 VARIANT_BOOL b;
409 HRESULT hres;
410
411 hres = IHTMLEventObj_get_altKey(event, &b);
412 ok_(__FILE__,line)(hres == S_OK, "get_altKey failed: %08x\n", hres);
413 ok_(__FILE__,line)(b == exval, "altKey = %x, expected %x\n", b, exval);
414 }
415
416 static void _test_event_ctrlkey(unsigned line, IHTMLEventObj *event, VARIANT_BOOL exval)
417 {
418 VARIANT_BOOL b;
419 HRESULT hres;
420
421 hres = IHTMLEventObj_get_ctrlKey(event, &b);
422 ok_(__FILE__,line)(hres == S_OK, "get_ctrlKey failed: %08x\n", hres);
423 ok_(__FILE__,line)(b == exval, "ctrlKey = %x, expected %x\n", b, exval);
424 }
425
426 static void _test_event_shiftkey(unsigned line, IHTMLEventObj *event, VARIANT_BOOL exval)
427 {
428 VARIANT_BOOL b;
429 HRESULT hres;
430
431 hres = IHTMLEventObj_get_shiftKey(event, &b);
432 ok_(__FILE__,line)(hres == S_OK, "get_shiftKey failed: %08x\n", hres);
433 ok_(__FILE__,line)(b == exval, "shiftKey = %x, expected %x\n", b, exval);
434 }
435
436 #define test_event_cancelbubble(a,b) _test_event_cancelbubble(__LINE__,a,b)
437 static void _test_event_cancelbubble(unsigned line, IHTMLEventObj *event, VARIANT_BOOL exval)
438 {
439 VARIANT_BOOL b;
440 HRESULT hres;
441
442 hres = IHTMLEventObj_get_cancelBubble(event, &b);
443 ok_(__FILE__,line)(hres == S_OK, "get_cancelBubble failed: %08x\n", hres);
444 ok_(__FILE__,line)(b == exval, "cancelBubble = %x, expected %x\n", b, exval);
445 }
446
447 static void _test_event_fromelem(unsigned line, IHTMLEventObj *event, const char *from_tag)
448 {
449 IHTMLElement *elem;
450 HRESULT hres;
451
452 hres = IHTMLEventObj_get_fromElement(event, &elem);
453 ok_(__FILE__,line)(hres == S_OK, "get_fromElement failed: %08x\n", hres);
454 if(from_tag)
455 _test_elem_tag(line, (IUnknown*)elem, from_tag);
456 else
457 ok_(__FILE__,line)(elem == NULL, "fromElement != NULL\n");
458 if(elem)
459 IHTMLElement_Release(elem);
460 }
461
462 static void _test_event_toelem(unsigned line, IHTMLEventObj *event, const char *to_tag)
463 {
464 IHTMLElement *elem;
465 HRESULT hres;
466
467 hres = IHTMLEventObj_get_toElement(event, &elem);
468 ok_(__FILE__,line)(hres == S_OK, "get_toElement failed: %08x\n", hres);
469 if(to_tag)
470 _test_elem_tag(line, (IUnknown*)elem, to_tag);
471 else
472 ok_(__FILE__,line)(elem == NULL, "toElement != NULL\n");
473 if(elem)
474 IHTMLElement_Release(elem);
475 }
476
477 static void _test_event_keycode(unsigned line, IHTMLEventObj *event, LONG exl)
478 {
479 LONG l;
480 HRESULT hres;
481
482 hres = IHTMLEventObj_get_keyCode(event, &l);
483 ok_(__FILE__,line)(hres == S_OK, "get_keyCode failed: %08x\n", hres);
484 ok_(__FILE__,line)(l == exl, "keyCode = %x, expected %x\n", l, exl);
485 }
486
487 static void _test_event_button(unsigned line, IHTMLEventObj *event, LONG exl)
488 {
489 LONG l;
490 HRESULT hres;
491
492 hres = IHTMLEventObj_get_button(event, &l);
493 ok_(__FILE__,line)(hres == S_OK, "get_button failed: %08x\n", hres);
494 ok_(__FILE__,line)(l == exl, "button = %x, expected %x\n", l, exl);
495 }
496
497 static void _test_event_reason(unsigned line, IHTMLEventObj *event, LONG exl)
498 {
499 LONG l;
500 HRESULT hres;
501
502 hres = IHTMLEventObj_get_reason(event, &l);
503 ok_(__FILE__,line)(hres == S_OK, "get_reason failed: %08x\n", hres);
504 ok_(__FILE__,line)(l == exl, "reason = %x, expected %x\n", l, exl);
505 }
506
507 static void _test_event_x(unsigned line, IHTMLEventObj *event, LONG exl)
508 {
509 LONG l;
510 HRESULT hres;
511
512 hres = IHTMLEventObj_get_x(event, &l);
513 ok_(__FILE__,line)(hres == S_OK, "get_x failed: %08x\n", hres);
514 if(exl != -10) /* don't test the exact value */
515 ok_(__FILE__,line)(l == exl, "x = %d, expected %d\n", l, exl);
516 }
517
518 static void _test_event_y(unsigned line, IHTMLEventObj *event, LONG exl)
519 {
520 LONG l;
521 HRESULT hres;
522
523 hres = IHTMLEventObj_get_y(event, &l);
524 ok_(__FILE__,line)(hres == S_OK, "get_y failed: %08x\n", hres);
525 if(exl != -10) /* don't test the exact value */
526 ok_(__FILE__,line)(l == exl, "y = %d, expected %d\n", l, exl);
527 }
528
529 static void _test_event_clientx(unsigned line, IHTMLEventObj *event, LONG exl)
530 {
531 LONG l;
532 HRESULT hres;
533
534 hres = IHTMLEventObj_get_clientX(event, &l);
535 ok_(__FILE__,line)(hres == S_OK, "get_clientX failed: %08x\n", hres);
536 if(exl != -10) /* don't test the exact value */
537 ok_(__FILE__,line)(l == exl, "clientX = %d, expected %d\n", l, exl);
538 }
539
540 static void _test_event_clienty(unsigned line, IHTMLEventObj *event, LONG exl)
541 {
542 LONG l;
543 HRESULT hres;
544
545 hres = IHTMLEventObj_get_clientY(event, &l);
546 ok_(__FILE__,line)(hres == S_OK, "get_clientY failed: %08x\n", hres);
547 if(exl != -10) /* don't test the exact value */
548 ok_(__FILE__,line)(l == exl, "clientY = %d, expected %d\n", l, exl);
549 }
550
551 static void _test_event_offsetx(unsigned line, IHTMLEventObj *event, LONG exl)
552 {
553 LONG l;
554 HRESULT hres;
555
556 hres = IHTMLEventObj_get_offsetX(event, &l);
557 ok_(__FILE__,line)(hres == S_OK, "get_offsetX failed: %08x\n", hres);
558 if(exl != -10) /* don't test the exact value */
559 ok_(__FILE__,line)(l == exl, "offsetX = %d, expected %d\n", l, exl);
560 }
561
562 static void _test_event_offsety(unsigned line, IHTMLEventObj *event, LONG exl)
563 {
564 LONG l;
565 HRESULT hres;
566
567 hres = IHTMLEventObj_get_offsetY(event, &l);
568 ok_(__FILE__,line)(hres == S_OK, "get_offsetY failed: %08x\n", hres);
569 if(exl != -10) /* don't test the exact value */
570 ok_(__FILE__,line)(l == exl, "offsetY = %d, expected %d\n", l, exl);
571 }
572
573 static void _test_event_screenx(unsigned line, IHTMLEventObj *event, LONG exl)
574 {
575 LONG l;
576 HRESULT hres;
577
578 hres = IHTMLEventObj_get_screenX(event, &l);
579 ok_(__FILE__,line)(hres == S_OK, "get_screenX failed: %08x\n", hres);
580 if(exl != -10) /* don't test the exact value */
581 ok_(__FILE__,line)(l == exl, "screenX = %d, expected %d\n", l, exl);
582 }
583
584 static void _test_event_screeny(unsigned line, IHTMLEventObj *event, LONG exl)
585 {
586 LONG l;
587 HRESULT hres;
588
589 hres = IHTMLEventObj_get_screenY(event, &l);
590 ok_(__FILE__,line)(hres == S_OK, "get_screenY failed: %08x\n", hres);
591 if(exl != -10) /* don't test the exact value for -10 */
592 ok_(__FILE__,line)(l == exl, "screenY = %d, expected %d\n", l, exl);
593 }
594
595 static void _test_event_type(unsigned line, IHTMLEventObj *event, const char *exstr)
596 {
597 BSTR str;
598 HRESULT hres;
599
600 hres = IHTMLEventObj_get_type(event, &str);
601 ok_(__FILE__,line)(hres == S_OK, "get_type failed: %08x\n", hres);
602 ok_(__FILE__,line)(!strcmp_wa(str, exstr), "type = %s, expected %s\n", wine_dbgstr_w(str), exstr);
603 }
604
605 static void _test_event_qualifier(unsigned line, IHTMLEventObj *event, const char *exstr)
606 {
607 BSTR str;
608 HRESULT hres;
609
610 hres = IHTMLEventObj_get_qualifier(event, &str);
611 ok_(__FILE__,line)(hres == S_OK, "get_qualifier failed: %08x\n", hres);
612 if(exstr)
613 ok_(__FILE__,line)(!strcmp_wa(str, exstr), "qualifier = %s, expected %s\n", wine_dbgstr_w(str), exstr);
614 else
615 ok_(__FILE__,line)(!str, "qualifier != NULL\n");
616 }
617
618 static void _test_event_srcfilter(unsigned line, IHTMLEventObj *event)
619 {
620 IDispatch *disp;
621 HRESULT hres;
622
623 hres = IHTMLEventObj_get_srcFilter(event, &disp);
624 ok_(__FILE__,line)(hres == S_OK, "get_srcFilter failed: %08x\n", hres);
625 ok_(__FILE__,line)(!disp, "srcFilter != NULL\n");
626 }
627
628 #define test_event_obj(t,x) _test_event_obj(__LINE__,t,x)
629 static void _test_event_obj(unsigned line, const char *type, const xy_test_t *xy)
630 {
631 IHTMLEventObj *event = _get_event_obj(line);
632 VARIANT v;
633 HRESULT hres;
634
635 _test_event_altkey(line, event, VARIANT_FALSE);
636 _test_event_ctrlkey(line, event, VARIANT_FALSE);
637 _test_event_shiftkey(line, event, VARIANT_FALSE);
638 _test_event_cancelbubble(line, event, VARIANT_FALSE);
639 _test_event_fromelem(line, event, NULL);
640 _test_event_toelem(line, event, NULL);
641 _test_event_keycode(line, event, 0);
642 _test_event_button(line, event, 0);
643 _test_event_type(line, event, type);
644 _test_event_qualifier(line, event, NULL);
645 _test_event_reason(line, event, 0);
646 _test_event_srcfilter(line, event);
647 _test_event_x(line, event, xy->x);
648 _test_event_y(line, event, xy->y);
649 _test_event_clientx(line, event, -10);
650 _test_event_clienty(line, event, -10);
651 _test_event_offsetx(line, event, xy->offset_x);
652 _test_event_offsety(line, event, xy->offset_y);
653 _test_event_screenx(line, event, -10);
654 _test_event_screeny(line, event, -10);
655
656 V_VT(&v) = VT_NULL;
657 hres = IHTMLEventObj_get_returnValue(event, &v);
658 ok_(__FILE__,line)(hres == S_OK, "get_returnValue failed: %08x\n", hres);
659 ok_(__FILE__,line)(V_VT(&v) == VT_EMPTY, "V_VT(returnValue) = %d\n", V_VT(&v));
660
661 IHTMLEventObj_Release(event);
662 }
663
664 #define elem_attach_event(a,b,c) _elem_attach_event(__LINE__,a,b,c)
665 static void _elem_attach_event(unsigned line, IUnknown *unk, const char *namea, IDispatch *disp)
666 {
667 IHTMLElement2 *elem = _get_elem2_iface(line, unk);
668 VARIANT_BOOL res;
669 BSTR name;
670 HRESULT hres;
671
672 name = a2bstr(namea);
673 hres = IHTMLElement2_attachEvent(elem, name, disp, &res);
674 IHTMLElement2_Release(elem);
675 SysFreeString(name);
676 ok_(__FILE__,line)(hres == S_OK, "attachEvent failed: %08x\n", hres);
677 ok_(__FILE__,line)(res == VARIANT_TRUE, "attachEvent returned %x\n", res);
678 }
679
680 #define elem_detach_event(a,b,c) _elem_detach_event(__LINE__,a,b,c)
681 static void _elem_detach_event(unsigned line, IUnknown *unk, const char *namea, IDispatch *disp)
682 {
683 IHTMLElement2 *elem = _get_elem2_iface(line, unk);
684 BSTR name;
685 HRESULT hres;
686
687 name = a2bstr(namea);
688 hres = IHTMLElement2_detachEvent(elem, name, disp);
689 IHTMLElement2_Release(elem);
690 SysFreeString(name);
691 ok_(__FILE__,line)(hres == S_OK, "detachEvent failed: %08x\n", hres);
692 }
693
694 #define doc_attach_event(a,b,c) _doc_attach_event(__LINE__,a,b,c)
695 static void _doc_attach_event(unsigned line, IHTMLDocument2 *doc, const char *namea, IDispatch *disp)
696 {
697 IHTMLDocument3 *doc3 = _get_doc3_iface(line, (IUnknown*)doc);
698 VARIANT_BOOL res;
699 BSTR name;
700 HRESULT hres;
701
702 name = a2bstr(namea);
703 hres = IHTMLDocument3_attachEvent(doc3, name, disp, &res);
704 IHTMLDocument3_Release(doc3);
705 SysFreeString(name);
706 ok_(__FILE__,line)(hres == S_OK, "attachEvent failed: %08x\n", hres);
707 ok_(__FILE__,line)(res == VARIANT_TRUE, "attachEvent returned %x\n", res);
708 }
709
710 #define doc_detach_event(a,b,c) _doc_detach_event(__LINE__,a,b,c)
711 static void _doc_detach_event(unsigned line, IHTMLDocument2 *doc, const char *namea, IDispatch *disp)
712 {
713 IHTMLDocument3 *doc3 = _get_doc3_iface(line, (IUnknown*)doc);
714 BSTR name;
715 HRESULT hres;
716
717 name = a2bstr(namea);
718 hres = IHTMLDocument3_detachEvent(doc3, name, disp);
719 IHTMLDocument3_Release(doc3);
720 SysFreeString(name);
721 ok_(__FILE__,line)(hres == S_OK, "detachEvent failed: %08x\n", hres);
722 }
723
724 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
725 {
726 *ppv = NULL;
727
728 if(IsEqualGUID(riid, &IID_IUnknown)
729 || IsEqualGUID(riid, &IID_IDispatch)
730 || IsEqualGUID(riid, &IID_IDispatchEx))
731 *ppv = iface;
732 else {
733 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
734 return E_NOINTERFACE;
735 }
736
737 return S_OK;
738 }
739
740 static HRESULT WINAPI Dispatch_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
741 {
742 *ppv = NULL;
743
744 if(IsEqualGUID(riid, &IID_IUnknown)
745 || IsEqualGUID(riid, &IID_IDispatch)) {
746 *ppv = iface;
747 }else if(IsEqualGUID(riid, &IID_IDispatchEx)) {
748 return E_NOINTERFACE;
749 }else {
750 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
751 return E_NOINTERFACE;
752 }
753
754 return S_OK;
755 }
756
757 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
758 {
759 return 2;
760 }
761
762 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
763 {
764 return 1;
765 }
766
767 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
768 {
769 ok(0, "unexpected call\n");
770 return E_NOTIMPL;
771 }
772
773 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
774 LCID lcid, ITypeInfo **ppTInfo)
775 {
776 ok(0, "unexpected call\n");
777 return E_NOTIMPL;
778 }
779
780 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
781 LPOLESTR *rgszNames, UINT cNames,
782 LCID lcid, DISPID *rgDispId)
783 {
784 ok(0, "unexpected call\n");
785 return E_NOTIMPL;
786 }
787
788 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
789 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
790 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
791 {
792 ok(0, "unexpected call\n");
793 return E_NOTIMPL;
794 }
795
796 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
797 {
798 ok(0, "unexpected call\n");
799 return E_NOTIMPL;
800 }
801
802 static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
803 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
804 {
805 ok(0, "unexpected call\n");
806 return E_NOTIMPL;
807 }
808
809 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
810 {
811 ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
812 return E_NOTIMPL;
813 }
814
815 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
816 {
817 ok(0, "unexpected call\n");
818 return E_NOTIMPL;
819 }
820
821 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
822 {
823 ok(0, "unexpected call\n");
824 return E_NOTIMPL;
825 }
826
827 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
828 {
829 ok(0, "unexpected call\n");
830 return E_NOTIMPL;
831 }
832
833 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
834 {
835 ok(0, "unexpected call\n");
836 return E_NOTIMPL;
837 }
838
839 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
840 {
841 ok(0, "unexpected call\n");
842 return E_NOTIMPL;
843 }
844
845 #define EVENT_HANDLER_FUNC_OBJ(event) \
846 static IDispatchExVtbl event ## FuncVtbl = { \
847 DispatchEx_QueryInterface, \
848 DispatchEx_AddRef, \
849 DispatchEx_Release, \
850 DispatchEx_GetTypeInfoCount, \
851 DispatchEx_GetTypeInfo, \
852 DispatchEx_GetIDsOfNames, \
853 DispatchEx_Invoke, \
854 DispatchEx_GetDispID, \
855 event, \
856 DispatchEx_DeleteMemberByName, \
857 DispatchEx_DeleteMemberByDispID, \
858 DispatchEx_GetMemberProperties, \
859 DispatchEx_GetMemberName, \
860 DispatchEx_GetNextDispID, \
861 DispatchEx_GetNameSpaceParent \
862 }; \
863 static IDispatchEx event ## _obj = { &event ## FuncVtbl };
864
865 static HRESULT WINAPI document_onclick(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
866 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
867 {
868 IHTMLDocument3 *doc3;
869 CHECK_EXPECT(document_onclick);
870 test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller);
871 doc3 = get_doc3_iface((IUnknown*)V_DISPATCH(pdp->rgvarg));
872 IHTMLDocument3_Release(doc3);
873 test_event_src("DIV");
874 test_event_obj("click", &no_xy);
875 return S_OK;
876 }
877
878 EVENT_HANDLER_FUNC_OBJ(document_onclick);
879
880 static HRESULT WINAPI div_onclick(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
881 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
882 {
883 CHECK_EXPECT(div_onclick);
884 test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller);
885 test_event_src("DIV");
886 return S_OK;
887 }
888
889 EVENT_HANDLER_FUNC_OBJ(div_onclick);
890
891 static HRESULT WINAPI div_onclick_attached(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
892 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
893 {
894 CHECK_EXPECT(div_onclick_attached);
895
896 test_attached_event_args(id, wFlags, pdp, pvarRes, pei);
897 test_event_src("DIV");
898 return S_OK;
899 }
900
901 EVENT_HANDLER_FUNC_OBJ(div_onclick_attached);
902
903 static HRESULT WINAPI doc_onclick_attached(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
904 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
905 {
906 CHECK_EXPECT(doc_onclick_attached);
907
908 test_attached_event_args(id, wFlags, pdp, pvarRes, pei);
909 test_event_src("DIV");
910 return S_OK;
911 }
912
913 EVENT_HANDLER_FUNC_OBJ(doc_onclick_attached);
914
915 static HRESULT WINAPI body_onclick(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
916 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
917 {
918 CHECK_EXPECT(body_onclick);
919 test_event_args(&DIID_DispHTMLBody, id, wFlags, pdp, pvarRes, pei, pspCaller);
920 test_event_src("DIV");
921 return S_OK;
922 }
923
924 EVENT_HANDLER_FUNC_OBJ(body_onclick);
925
926 static HRESULT WINAPI img_onload(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
927 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
928 {
929 CHECK_EXPECT(img_onload);
930 test_event_args(&DIID_DispHTMLImg, id, wFlags, pdp, pvarRes, pei, pspCaller);
931 test_event_src("IMG");
932 return S_OK;
933 }
934
935 EVENT_HANDLER_FUNC_OBJ(img_onload);
936
937 static HRESULT WINAPI img_onerror(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
938 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
939 {
940 CHECK_EXPECT(img_onerror);
941 test_event_args(&DIID_DispHTMLImg, id, wFlags, pdp, pvarRes, pei, pspCaller);
942 test_event_src("IMG");
943 return S_OK;
944 }
945
946 EVENT_HANDLER_FUNC_OBJ(img_onerror);
947
948 static HRESULT WINAPI input_onfocus(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
949 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
950 {
951 CHECK_EXPECT(input_onfocus);
952 test_event_args(&DIID_DispHTMLInputElement, id, wFlags, pdp, pvarRes, pei, pspCaller);
953 test_event_src("INPUT");
954 return S_OK;
955 }
956
957 EVENT_HANDLER_FUNC_OBJ(input_onfocus);
958
959 static HRESULT WINAPI input_onblur(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
960 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
961 {
962 CHECK_EXPECT(input_onblur);
963 test_event_args(&DIID_DispHTMLInputElement, id, wFlags, pdp, pvarRes, pei, pspCaller);
964 test_event_src("INPUT");
965 return S_OK;
966 }
967
968 EVENT_HANDLER_FUNC_OBJ(input_onblur);
969
970 static HRESULT WINAPI form_onsubmit(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
971 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
972 {
973 CHECK_EXPECT(form_onsubmit);
974 test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller);
975 test_event_src("FORM");
976
977 V_VT(pvarRes) = VT_BOOL;
978 V_BOOL(pvarRes) = VARIANT_FALSE;
979 return S_OK;
980 }
981
982 EVENT_HANDLER_FUNC_OBJ(form_onsubmit);
983
984 static HRESULT WINAPI form_onclick(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
985 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
986 {
987 CHECK_EXPECT(form_onclick);
988 test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller);
989
990 return S_OK;
991 }
992
993 EVENT_HANDLER_FUNC_OBJ(form_onclick);
994
995 static HRESULT WINAPI submit_onclick(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
996 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
997 {
998 CHECK_EXPECT(submit_onclick);
999 test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller);
1000 test_event_src("INPUT");
1001
1002 V_VT(pvarRes) = VT_BOOL;
1003 V_BOOL(pvarRes) = VARIANT_FALSE;
1004 return S_OK;
1005 }
1006
1007 EVENT_HANDLER_FUNC_OBJ(submit_onclick);
1008
1009 static HRESULT WINAPI iframe_onload(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1010 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1011 {
1012 CHECK_EXPECT(iframe_onload);
1013 test_event_args(&DIID_DispHTMLIFrame, id, wFlags, pdp, pvarRes, pei, pspCaller);
1014 test_event_src("IFRAME");
1015 return S_OK;
1016 }
1017
1018 EVENT_HANDLER_FUNC_OBJ(iframe_onload);
1019
1020 static HRESULT WINAPI submit_onclick_attached(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1021 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1022 {
1023 CHECK_EXPECT(submit_onclick_attached);
1024 test_attached_event_args(id, wFlags, pdp, pvarRes, pei);
1025 test_event_src("INPUT");
1026
1027 V_VT(pvarRes) = VT_BOOL;
1028 V_BOOL(pvarRes) = VARIANT_FALSE;
1029 return S_OK;
1030 }
1031
1032 EVENT_HANDLER_FUNC_OBJ(submit_onclick_attached);
1033
1034 static HRESULT WINAPI submit_onclick_attached_check_cancel(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1035 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1036 {
1037 IHTMLEventObj *event;
1038 HRESULT hres;
1039
1040 CHECK_EXPECT(submit_onclick_attached_check_cancel);
1041 test_attached_event_args(id, wFlags, pdp, pvarRes, pei);
1042 test_event_src("INPUT");
1043
1044 event = NULL;
1045 hres = IHTMLWindow2_get_event(window, &event);
1046 ok(hres == S_OK, "get_event failed: %08x\n", hres);
1047 ok(event != NULL, "event == NULL\n");
1048
1049 test_event_cancelbubble(event, VARIANT_TRUE);
1050 return S_OK;
1051 }
1052
1053 EVENT_HANDLER_FUNC_OBJ(submit_onclick_attached_check_cancel);
1054
1055 static VARIANT onclick_retval, onclick_event_retval;
1056
1057 static HRESULT WINAPI submit_onclick_setret(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1058 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1059 {
1060 IHTMLEventObj *event;
1061 HRESULT hres;
1062
1063 CHECK_EXPECT(submit_onclick_setret);
1064 test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller);
1065 test_event_src("INPUT");
1066
1067 event = NULL;
1068 hres = IHTMLWindow2_get_event(window, &event);
1069 ok(hres == S_OK, "get_event failed: %08x\n", hres);
1070 ok(event != NULL, "event == NULL\n");
1071
1072 hres = IHTMLEventObj_put_returnValue(event, onclick_event_retval);
1073 ok(hres == S_OK, "put_returnValue failed: %08x\n", hres);
1074 IHTMLEventObj_Release(event);
1075
1076 *pvarRes = onclick_retval;
1077 return S_OK;
1078 }
1079
1080 EVENT_HANDLER_FUNC_OBJ(submit_onclick_setret);
1081
1082 static HRESULT WINAPI submit_onclick_cancel(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1083 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1084 {
1085 IHTMLEventObj *event;
1086 HRESULT hres;
1087
1088 CHECK_EXPECT(submit_onclick_cancel);
1089 test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller);
1090 test_event_src("INPUT");
1091
1092 event = NULL;
1093 hres = IHTMLWindow2_get_event(window, &event);
1094 ok(hres == S_OK, "get_event failed: %08x\n", hres);
1095 ok(event != NULL, "event == NULL\n");
1096
1097 test_event_cancelbubble(event, VARIANT_FALSE);
1098
1099 hres = IHTMLEventObj_put_cancelBubble(event, VARIANT_TRUE);
1100 ok(hres == S_OK, "put_returnValue failed: %08x\n", hres);
1101 IHTMLEventObj_Release(event);
1102
1103 test_event_cancelbubble(event, VARIANT_TRUE);
1104 return S_OK;
1105 }
1106
1107 EVENT_HANDLER_FUNC_OBJ(submit_onclick_cancel);
1108
1109 static HRESULT WINAPI iframedoc_onreadystatechange(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1110 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1111 {
1112 IHTMLEventObj *event = NULL;
1113 HRESULT hres;
1114
1115 CHECK_EXPECT2(iframedoc_onreadystatechange);
1116 test_event_args(&DIID_DispHTMLDocument, id, wFlags, pdp, pvarRes, pei, pspCaller);
1117
1118 event = (void*)0xdeadbeef;
1119 hres = IHTMLWindow2_get_event(window, &event);
1120 ok(hres == S_OK, "get_event failed: %08x\n", hres);
1121 ok(!event, "event = %p\n", event);
1122
1123 return S_OK;
1124 }
1125
1126 EVENT_HANDLER_FUNC_OBJ(iframedoc_onreadystatechange);
1127
1128 static HRESULT WINAPI iframe_onreadystatechange(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1129 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1130 {
1131 IHTMLWindow2 *iframe_window;
1132 IHTMLDocument2 *iframe_doc;
1133 IHTMLFrameBase2 *iframe;
1134 IHTMLElement2 *elem2;
1135 IHTMLElement *elem;
1136 VARIANT v;
1137 BSTR str, str2;
1138 HRESULT hres;
1139
1140 test_event_args(&DIID_DispHTMLIFrame, id, wFlags, pdp, pvarRes, pei, pspCaller);
1141 test_event_src("IFRAME");
1142
1143 elem = get_event_src();
1144 elem2 = get_elem2_iface((IUnknown*)elem);
1145 IHTMLElement_Release(elem);
1146
1147 V_VT(&v) = VT_EMPTY;
1148 hres = IHTMLElement2_get_readyState(elem2, &v);
1149 ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
1150 ok(V_VT(&v) == VT_BSTR, "V_VT(readyState) = %d\n", V_VT(&v));
1151
1152 hres = IHTMLElement2_QueryInterface(elem2, &IID_IHTMLFrameBase2, (void**)&iframe);
1153 IHTMLElement2_Release(elem2);
1154 ok(hres == S_OK, "Could not get IHTMLFrameBase2 iface: %08x\n", hres);
1155
1156 str = NULL;
1157 hres = IHTMLFrameBase2_get_readyState(iframe, &str);
1158 ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
1159 ok(str != NULL, "readyState == NULL\n");
1160 ok(!lstrcmpW(str, V_BSTR(&v)), "ready states differ\n");
1161 VariantClear(&v);
1162
1163 hres = IHTMLFrameBase2_get_contentWindow(iframe, &iframe_window);
1164 ok(hres == S_OK, "get_contentDocument failed: %08x\n", hres);
1165
1166 hres = IHTMLWindow2_get_document(iframe_window, &iframe_doc);
1167 IHTMLWindow2_Release(iframe_window);
1168 ok(hres == S_OK, "get_document failed: %08x\n", hres);
1169
1170 hres = IHTMLDocument2_get_readyState(iframe_doc, &str2);
1171 ok(hres == S_OK, "get_document failed: %08x\n", hres);
1172 ok(!lstrcmpW(str, str2), "unexpected document readyState %s\n", wine_dbgstr_w(str2));
1173 SysFreeString(str2);
1174
1175 if(!strcmp_wa(str, "loading")) {
1176 CHECK_EXPECT(iframe_onreadystatechange_loading);
1177
1178 V_VT(&v) = VT_DISPATCH;
1179 V_DISPATCH(&v) = (IDispatch*)&iframedoc_onreadystatechange_obj;
1180 hres = IHTMLDocument2_put_onreadystatechange(iframe_doc, v);
1181 ok(hres == S_OK, "put_onreadystatechange: %08x\n", hres);
1182 }else if(!strcmp_wa(str, "interactive"))
1183 CHECK_EXPECT(iframe_onreadystatechange_interactive);
1184 else if(!strcmp_wa(str, "complete"))
1185 CHECK_EXPECT(iframe_onreadystatechange_complete);
1186 else
1187 ok(0, "unexpected state %s\n", wine_dbgstr_w(str));
1188
1189 SysFreeString(str);
1190 IHTMLDocument2_Release(iframe_doc);
1191 IHTMLFrameBase2_Release(iframe);
1192 return S_OK;
1193 }
1194
1195 EVENT_HANDLER_FUNC_OBJ(iframe_onreadystatechange);
1196
1197 static HRESULT WINAPI nocall(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1198 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1199 {
1200 ok(0, "unexpected call\n");
1201 return S_OK;
1202 }
1203
1204 EVENT_HANDLER_FUNC_OBJ(nocall);
1205
1206 #define CONNECTION_POINT_OBJ(cpname, diid) \
1207 static HRESULT WINAPI cpname ## _QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv) \
1208 { \
1209 *ppv = NULL; \
1210 if(IsEqualGUID(riid, &IID_IUnknown) \
1211 || IsEqualGUID(riid, &IID_IDispatch) \
1212 || IsEqualGUID(riid, &diid)) \
1213 *ppv = iface; \
1214 else { \
1215 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid)); \
1216 return E_NOINTERFACE; \
1217 } \
1218 return S_OK; \
1219 } \
1220 static IDispatchExVtbl cpname ## Vtbl = { \
1221 cpname ## _QueryInterface, \
1222 DispatchEx_AddRef, \
1223 DispatchEx_Release, \
1224 DispatchEx_GetTypeInfoCount, \
1225 DispatchEx_GetTypeInfo, \
1226 DispatchEx_GetIDsOfNames, \
1227 cpname, \
1228 DispatchEx_GetDispID, \
1229 DispatchEx_InvokeEx, \
1230 DispatchEx_DeleteMemberByName, \
1231 DispatchEx_DeleteMemberByDispID, \
1232 DispatchEx_GetMemberProperties, \
1233 DispatchEx_GetMemberName, \
1234 DispatchEx_GetNextDispID, \
1235 DispatchEx_GetNameSpaceParent \
1236 }; \
1237 static IDispatchEx cpname ## _obj = { &cpname ## Vtbl }
1238
1239 #define test_cp_args(a,b,c,d,e,f) _test_cp_args(__LINE__,a,b,c,d,e,f)
1240 static void _test_cp_args(unsigned line, REFIID riid, WORD flags, DISPPARAMS *dp, VARIANT *vres, EXCEPINFO *ei, UINT *argerr)
1241 {
1242 ok_(__FILE__,line)(IsEqualGUID(&IID_NULL, riid), "riid = %s\n", wine_dbgstr_guid(riid));
1243 ok_(__FILE__,line)(flags == DISPATCH_METHOD, "flags = %x\n", flags);
1244 ok_(__FILE__,line)(dp != NULL, "dp == NULL\n");
1245 ok_(__FILE__,line)(!dp->cArgs, "dp->cArgs = %d\n", dp->cArgs);
1246 ok_(__FILE__,line)(!dp->rgvarg, "dp->rgvarg = %p\n", dp->rgvarg);
1247 ok_(__FILE__,line)(!dp->cNamedArgs, "dp->cNamedArgs = %d\n", dp->cNamedArgs);
1248 ok_(__FILE__,line)(!dp->rgdispidNamedArgs, "dp->rgdispidNamedArgs = %p\n", dp->rgdispidNamedArgs);
1249 ok_(__FILE__,line)(vres != NULL, "vres == NULL\n");
1250 ok_(__FILE__,line)(V_VT(vres) == VT_EMPTY, "V_VT(vres) = %d\n", V_VT(vres));
1251 ok_(__FILE__,line)(ei != NULL, "ei == NULL\n");
1252 ok_(__FILE__,line)(argerr != NULL, "argerr == NULL\n");
1253 }
1254
1255 #define test_cp_eventarg(a,b,c,d,e,f) _test_cp_eventarg(__LINE__,a,b,c,d,e,f)
1256 static void _test_cp_eventarg(unsigned line, REFIID riid, WORD flags, DISPPARAMS *dp, VARIANT *vres, EXCEPINFO *ei, UINT *argerr)
1257 {
1258 IHTMLEventObj *event;
1259
1260 ok_(__FILE__,line)(IsEqualGUID(&IID_NULL, riid), "riid = %s\n", wine_dbgstr_guid(riid));
1261 ok_(__FILE__,line)(flags == DISPATCH_METHOD, "flags = %x\n", flags);
1262 ok_(__FILE__,line)(dp != NULL, "dp == NULL\n");
1263 ok_(__FILE__,line)(dp->cArgs == 1, "dp->cArgs = %d\n", dp->cArgs);
1264 ok_(__FILE__,line)(dp->rgvarg != NULL, "dp->rgvarg = %p\n", dp->rgvarg);
1265 ok_(__FILE__,line)(!dp->cNamedArgs, "dp->cNamedArgs = %d\n", dp->cNamedArgs);
1266 ok_(__FILE__,line)(!dp->rgdispidNamedArgs, "dp->rgdispidNamedArgs = %p\n", dp->rgdispidNamedArgs);
1267 ok_(__FILE__,line)(vres != NULL, "vres == NULL\n");
1268 ok_(__FILE__,line)(V_VT(vres) == VT_EMPTY, "V_VT(vres) = %d\n", V_VT(vres));
1269 ok_(__FILE__,line)(ei != NULL, "ei == NULL\n");
1270 ok_(__FILE__,line)(argerr != NULL, "argerr == NULL\n");
1271
1272 ok(V_VT(dp->rgvarg) == VT_DISPATCH, "V_VT(dp->rgvarg) = %d\n", V_VT(dp->rgvarg));
1273 ok(V_DISPATCH(dp->rgvarg) != NULL, "V_DISPATCH(dp->rgvarg) = %p\n", V_DISPATCH(dp->rgvarg));
1274
1275 event = _get_event_obj(line);
1276 ok(iface_cmp((IUnknown*)event, (IUnknown*)V_DISPATCH(dp->rgvarg)), "event != arg0\n");
1277 IHTMLEventObj_Release(event);
1278 }
1279
1280 static HRESULT WINAPI doccp(IDispatchEx *iface, DISPID dispIdMember,
1281 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1282 VARIANT *pVarResult, EXCEPINFO *pei, UINT *puArgErr)
1283 {
1284 switch(dispIdMember) {
1285 case DISPID_HTMLDOCUMENTEVENTS_ONCLICK:
1286 CHECK_EXPECT(doccp_onclick);
1287 test_cp_args(riid, wFlags, pdp, pVarResult, pei, puArgErr);
1288 break;
1289 default:
1290 ok(0, "unexpected call %d\n", dispIdMember);
1291 return E_NOTIMPL;
1292 }
1293
1294 return S_OK;
1295 }
1296
1297 CONNECTION_POINT_OBJ(doccp, DIID_HTMLDocumentEvents);
1298
1299 static HRESULT WINAPI doccp_onclick_cancel(IDispatchEx *iface, DISPID dispIdMember,
1300 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pVarResult, EXCEPINFO *pei, UINT *puArgErr)
1301 {
1302 switch(dispIdMember) {
1303 case DISPID_HTMLDOCUMENTEVENTS_ONCLICK:
1304 CHECK_EXPECT(doccp_onclick_cancel);
1305 test_cp_args(riid, wFlags, pdp, pVarResult, pei, puArgErr);
1306 V_VT(pVarResult) = VT_BOOL;
1307 V_BOOL(pVarResult) = VARIANT_FALSE;
1308 break;
1309 default:
1310 ok(0, "unexpected call %d\n", dispIdMember);
1311 return E_NOTIMPL;
1312 }
1313
1314 return S_OK;
1315 }
1316
1317 CONNECTION_POINT_OBJ(doccp_onclick_cancel, DIID_HTMLDocumentEvents);
1318
1319 static HRESULT WINAPI elem2_cp(IDispatchEx *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1320 WORD wFlags, DISPPARAMS *pdp, VARIANT *pVarResult, EXCEPINFO *pei, UINT *puArgErr)
1321 {
1322 switch(dispIdMember) {
1323 case DISPID_HTMLDOCUMENTEVENTS_ONCLICK:
1324 CHECK_EXPECT(elem2_cp_onclick);
1325 test_cp_eventarg(riid, wFlags, pdp, pVarResult, pei, puArgErr);
1326 break;
1327 default:
1328 ok(0, "unexpected call %d\n", dispIdMember);
1329 return E_NOTIMPL;
1330 }
1331
1332 return S_OK;
1333 }
1334
1335 CONNECTION_POINT_OBJ(elem2_cp, DIID_HTMLElementEvents2);
1336
1337 static HRESULT WINAPI timeoutFunc_Invoke(IDispatchEx *iface, DISPID dispIdMember,
1338 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1339 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1340 {
1341 CHECK_EXPECT(timeout);
1342
1343 ok(dispIdMember == DISPID_VALUE, "dispIdMember = %d\n", dispIdMember);
1344 ok(IsEqualGUID(&IID_NULL, riid), "riid = %s\n", wine_dbgstr_guid(riid));
1345 ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
1346 ok(!lcid, "lcid = %x\n", lcid);
1347 ok(pDispParams != NULL, "pDispParams == NULL\n");
1348 ok(!pDispParams->cArgs, "pdp->cArgs = %d\n", pDispParams->cArgs);
1349 ok(!pDispParams->cNamedArgs, "pdp->cNamedArgs = %d\n", pDispParams->cNamedArgs);
1350 ok(!pDispParams->rgdispidNamedArgs, "pdp->rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
1351 ok(!pDispParams->rgvarg, "rgvarg = %p\n", pDispParams->rgvarg);
1352 ok(pVarResult != NULL, "pVarResult = NULL\n");
1353 ok(pExcepInfo != NULL, "pExcepInfo = NULL\n");
1354 ok(!puArgErr, "puArgErr = %p\n", puArgErr);
1355 ok(V_VT(pVarResult) == VT_EMPTY, "V_VT(pVarResult) = %d\n", V_VT(pVarResult));
1356
1357 return S_OK;
1358 }
1359
1360 static const IDispatchExVtbl timeoutFuncVtbl = {
1361 DispatchEx_QueryInterface,
1362 DispatchEx_AddRef,
1363 DispatchEx_Release,
1364 DispatchEx_GetTypeInfoCount,
1365 DispatchEx_GetTypeInfo,
1366 DispatchEx_GetIDsOfNames,
1367 timeoutFunc_Invoke,
1368 DispatchEx_GetDispID,
1369 DispatchEx_InvokeEx,
1370 DispatchEx_DeleteMemberByName,
1371 DispatchEx_DeleteMemberByDispID,
1372 DispatchEx_GetMemberProperties,
1373 DispatchEx_GetMemberName,
1374 DispatchEx_GetNextDispID,
1375 DispatchEx_GetNameSpaceParent
1376 };
1377
1378 static IDispatchEx timeoutFunc = { &timeoutFuncVtbl };
1379
1380 static HRESULT WINAPI div_onclick_disp_Invoke(IDispatchEx *iface, DISPID id,
1381 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1382 VARIANT *pvarRes, EXCEPINFO *pei, UINT *puArgErr)
1383 {
1384 CHECK_EXPECT(div_onclick_disp);
1385
1386 test_attached_event_args(id, wFlags, pdp, pvarRes, pei);
1387
1388 ok(IsEqualGUID(&IID_NULL, riid), "riid = %s\n", wine_dbgstr_guid(riid));
1389 ok(!puArgErr, "puArgErr = %p\n", puArgErr);
1390
1391 return S_OK;
1392 }
1393
1394 static const IDispatchExVtbl div_onclick_dispVtbl = {
1395 Dispatch_QueryInterface,
1396 DispatchEx_AddRef,
1397 DispatchEx_Release,
1398 DispatchEx_GetTypeInfoCount,
1399 DispatchEx_GetTypeInfo,
1400 DispatchEx_GetIDsOfNames,
1401 div_onclick_disp_Invoke,
1402 };
1403
1404 static IDispatchEx div_onclick_disp = { &div_onclick_dispVtbl };
1405
1406 static void pump_msgs(BOOL *b)
1407 {
1408 MSG msg;
1409
1410 if(b) {
1411 while(!*b && GetMessageW(&msg, NULL, 0, 0)) {
1412 TranslateMessage(&msg);
1413 DispatchMessageW(&msg);
1414 }
1415 }else {
1416 while(!b && PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
1417 TranslateMessage(&msg);
1418 DispatchMessageW(&msg);
1419 }
1420 }
1421 }
1422
1423 static IConnectionPoint *get_cp(IUnknown *unk, REFIID riid)
1424 {
1425 IConnectionPointContainer *cp_container;
1426 IConnectionPoint *cp;
1427 HRESULT hres;
1428
1429 hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&cp_container);
1430 ok(hres == S_OK, "Could not get IConnectionPointContainer: %08x\n", hres);
1431
1432 hres = IConnectionPointContainer_FindConnectionPoint(cp_container, riid, &cp);
1433 IConnectionPointContainer_Release(cp_container);
1434 ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
1435
1436 return cp;
1437 }
1438
1439 static DWORD register_cp(IUnknown *unk, REFIID riid, IUnknown *sink)
1440 {
1441 IConnectionPoint *cp;
1442 DWORD cookie;
1443 HRESULT hres;
1444
1445 cp = get_cp(unk, riid);
1446 hres = IConnectionPoint_Advise(cp, sink, &cookie);
1447 IConnectionPoint_Release(cp);
1448 ok(hres == S_OK, "Advise failed: %08x\n", hres);
1449
1450 return cookie;
1451 }
1452
1453 static void unregister_cp(IUnknown *unk, REFIID riid, DWORD cookie)
1454 {
1455 IConnectionPoint *cp;
1456 HRESULT hres;
1457
1458 cp = get_cp(unk, riid);
1459 hres = IConnectionPoint_Unadvise(cp, cookie);
1460 IConnectionPoint_Release(cp);
1461 ok(hres == S_OK, "Unadvise failed: %08x\n", hres);
1462 }
1463
1464 static HRESULT WINAPI EventDispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
1465 {
1466 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IDispatch, riid)) {
1467 *ppv = iface;
1468 return S_OK;
1469 }
1470
1471 ok(0, "Unexpected call\n");
1472 return E_NOINTERFACE;
1473 }
1474
1475 static DWORD WINAPI EventDispatch_AddRef(IDispatch *iface)
1476 {
1477 return 2;
1478 }
1479
1480 static DWORD WINAPI EventDispatch_Release(IDispatch *iface)
1481 {
1482 return 1;
1483 }
1484
1485 static HRESULT WINAPI EventDispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
1486 {
1487 ok(0, "Unexpected call\n");
1488 return E_NOTIMPL;
1489 }
1490
1491 static HRESULT WINAPI EventDispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1492 {
1493 ok(0, "Unexpected call\n");
1494 return E_NOTIMPL;
1495 }
1496
1497 static HRESULT WINAPI EventDispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
1498 UINT cNames, LCID lcid, DISPID *rgDispId)
1499 {
1500 ok(0, "Unexpected call\n");
1501 return E_NOTIMPL;
1502 }
1503
1504 static HRESULT WINAPI EventDispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid,
1505 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
1506 EXCEPINFO *pExcepInfo, UINT *puArgErr)
1507 {
1508 ok(IsEqualGUID(&IID_NULL, riid), "riid = %s\n", wine_dbgstr_guid(riid));
1509 ok(pDispParams != NULL, "pDispParams == NULL\n");
1510 ok(pExcepInfo != NULL, "pExcepInfo == NULL\n");
1511 ok(puArgErr != NULL, "puArgErr == NULL\n");
1512 ok(V_VT(pVarResult) == 0, "V_VT(pVarResult) = %d\n", V_VT(pVarResult));
1513 ok(wFlags == DISPATCH_METHOD, "wFlags = %d\n", wFlags);
1514
1515 switch(dispIdMember) {
1516 case DISPID_HTMLDOCUMENTEVENTS_ONCLICK:
1517 CHECK_EXPECT2(invoke_onclick);
1518 break;
1519 case DISPID_HTMLDOCUMENTEVENTS2_ONPROPERTYCHANGE:
1520 case DISPID_HTMLDOCUMENTEVENTS2_ONREADYSTATECHANGE:
1521 case 1027:
1522 case 1034:
1523 case 1037:
1524 case 1044:
1525 case 1045:
1526 case 1047:
1527 case 1048:
1528 case 1049:
1529 break; /* TODO */
1530 default:
1531 ok(0, "Unexpected call: %d\n", dispIdMember);
1532 }
1533
1534 return S_OK;
1535 }
1536
1537 static const IDispatchVtbl EventDispatchVtbl = {
1538 EventDispatch_QueryInterface,
1539 EventDispatch_AddRef,
1540 EventDispatch_Release,
1541 EventDispatch_GetTypeInfoCount,
1542 EventDispatch_GetTypeInfo,
1543 EventDispatch_GetIDsOfNames,
1544 EventDispatch_Invoke
1545 };
1546
1547 static IDispatch EventDispatch = { &EventDispatchVtbl };
1548
1549 static void test_onclick(IHTMLDocument2 *doc)
1550 {
1551 DWORD cp_cookie, elem2_cp_cookie;
1552 IHTMLElement *div, *body;
1553 VARIANT v;
1554 HRESULT hres;
1555
1556 register_cp((IUnknown*)doc, &IID_IDispatch, (IUnknown*)&EventDispatch);
1557
1558 div = get_elem_id(doc, "clickdiv");
1559
1560 elem_attach_event((IUnknown*)div, "abcde", (IDispatch*)&nocall_obj);
1561 elem_attach_event((IUnknown*)div, "onclick", (IDispatch*)&div_onclick_attached_obj);
1562
1563 V_VT(&v) = VT_EMPTY;
1564 hres = IHTMLElement_get_onclick(div, &v);
1565 ok(hres == S_OK, "get_onclick failed: %08x\n", hres);
1566 ok(V_VT(&v) == VT_NULL, "V_VT(onclick) = %d\n", V_VT(&v));
1567
1568 V_VT(&v) = VT_EMPTY;
1569 hres = IHTMLElement_put_onclick(div, v);
1570 ok(hres == E_NOTIMPL, "put_onclick failed: %08x\n", hres);
1571
1572 V_VT(&v) = VT_BSTR;
1573 V_BSTR(&v) = a2bstr("function();");
1574 hres = IHTMLElement_put_onclick(div, v);
1575 todo_wine ok(hres == S_OK, "put_onclick failed: %08x\n", hres);
1576
1577 if(hres == S_OK) {
1578 V_VT(&v) = VT_EMPTY;
1579 hres = IHTMLElement_get_onclick(div, &v);
1580 ok(hres == S_OK, "get_onclick failed: %08x\n", hres);
1581 ok(V_VT(&v) == VT_BSTR, "V_VT(onclick) = %d\n", V_VT(&v));
1582 ok(!strcmp_wa(V_BSTR(&v), "function();"), "V_BSTR(onclick) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
1583 }
1584 VariantClear(&v);
1585
1586 V_VT(&v) = VT_DISPATCH;
1587 V_DISPATCH(&v) = (IDispatch*)&div_onclick_obj;
1588 hres = IHTMLElement_put_onclick(div, v);
1589 ok(hres == S_OK, "put_onclick failed: %08x\n", hres);
1590
1591 V_VT(&v) = VT_NULL;
1592 hres = IHTMLElement_put_ondblclick(div, v);
1593 ok(hres == S_OK, "put_ondblclick failed: %08x\n", hres);
1594
1595 V_VT(&v) = VT_EMPTY;
1596 hres = IHTMLElement_get_onclick(div, &v);
1597 ok(hres == S_OK, "get_onclick failed: %08x\n", hres);
1598 ok(V_VT(&v) == VT_DISPATCH, "V_VT(onclick) = %d\n", V_VT(&v));
1599 ok(V_DISPATCH(&v) == (IDispatch*)&div_onclick_obj, "V_DISPATCH(onclick) != onclickFunc\n");
1600 VariantClear(&v);
1601
1602 V_VT(&v) = VT_EMPTY;
1603 hres = IHTMLDocument2_get_onclick(doc, &v);
1604 ok(hres == S_OK, "get_onclick failed: %08x\n", hres);
1605 ok(V_VT(&v) == VT_NULL, "V_VT(onclick) = %d\n", V_VT(&v));
1606
1607 V_VT(&v) = VT_DISPATCH;
1608 V_DISPATCH(&v) = (IDispatch*)&document_onclick_obj;
1609 hres = IHTMLDocument2_put_onclick(doc, v);
1610 ok(hres == S_OK, "put_onclick failed: %08x\n", hres);
1611
1612 V_VT(&v) = VT_EMPTY;
1613 hres = IHTMLDocument2_get_onclick(doc, &v);
1614 ok(hres == S_OK, "get_onclick failed: %08x\n", hres);
1615 ok(V_VT(&v) == VT_DISPATCH, "V_VT(onclick) = %d\n", V_VT(&v));
1616 ok(V_DISPATCH(&v) == (IDispatch*)&document_onclick_obj, "V_DISPATCH(onclick) != onclickFunc\n");
1617 VariantClear(&v);
1618
1619 body = doc_get_body(doc);
1620
1621 V_VT(&v) = VT_DISPATCH;
1622 V_DISPATCH(&v) = (IDispatch*)&body_onclick_obj;
1623 hres = IHTMLElement_put_onclick(body, v);
1624 ok(hres == S_OK, "put_onclick failed: %08x\n", hres);
1625
1626 if(winetest_interactive) {
1627 SET_EXPECT(div_onclick);
1628 SET_EXPECT(div_onclick_attached);
1629 SET_EXPECT(body_onclick);
1630 SET_EXPECT(document_onclick);
1631 SET_EXPECT(invoke_onclick);
1632 pump_msgs(&called_document_onclick);
1633 CHECK_CALLED(div_onclick);
1634 CHECK_CALLED(div_onclick_attached);
1635 CHECK_CALLED(body_onclick);
1636 CHECK_CALLED(document_onclick);
1637 CHECK_CALLED(invoke_onclick);
1638 }
1639
1640 SET_EXPECT(div_onclick);
1641 SET_EXPECT(div_onclick_attached);
1642 SET_EXPECT(body_onclick);
1643 SET_EXPECT(document_onclick);
1644 SET_EXPECT(invoke_onclick);
1645
1646 hres = IHTMLElement_click(div);
1647 ok(hres == S_OK, "click failed: %08x\n", hres);
1648
1649 CHECK_CALLED(div_onclick);
1650 CHECK_CALLED(div_onclick_attached);
1651 CHECK_CALLED(body_onclick);
1652 CHECK_CALLED(document_onclick);
1653 CHECK_CALLED(invoke_onclick);
1654
1655 SET_EXPECT(div_onclick);
1656 SET_EXPECT(div_onclick_attached);
1657 SET_EXPECT(body_onclick);
1658 SET_EXPECT(document_onclick);
1659 SET_EXPECT(invoke_onclick);
1660
1661 V_VT(&v) = VT_EMPTY;
1662 elem_fire_event((IUnknown*)div, "onclick", &v);
1663
1664 CHECK_CALLED(div_onclick);
1665 CHECK_CALLED(div_onclick_attached);
1666 CHECK_CALLED(body_onclick);
1667 CHECK_CALLED(document_onclick);
1668 CHECK_CALLED(invoke_onclick);
1669
1670 cp_cookie = register_cp((IUnknown*)doc, &DIID_HTMLDocumentEvents, (IUnknown*)&doccp_obj);
1671 elem_attach_event((IUnknown*)div, "onclick", (IDispatch*)&div_onclick_disp);
1672 doc_attach_event(doc, "onclick", (IDispatch*)&doc_onclick_attached_obj);
1673
1674 SET_EXPECT(div_onclick);
1675 SET_EXPECT(div_onclick_disp);
1676 SET_EXPECT(div_onclick_attached);
1677 SET_EXPECT(body_onclick);
1678 SET_EXPECT(document_onclick);
1679 SET_EXPECT(doc_onclick_attached);
1680 SET_EXPECT(doccp_onclick);
1681 SET_EXPECT(invoke_onclick);
1682
1683 hres = IHTMLElement_click(div);
1684 ok(hres == S_OK, "click failed: %08x\n", hres);
1685
1686 CHECK_CALLED(div_onclick);
1687 CHECK_CALLED(div_onclick_disp);
1688 CHECK_CALLED(div_onclick_attached);
1689 CHECK_CALLED(body_onclick);
1690 CHECK_CALLED(document_onclick);
1691 CHECK_CALLED(doc_onclick_attached);
1692 CHECK_CALLED(doccp_onclick);
1693 CHECK_CALLED(invoke_onclick);
1694
1695 elem2_cp_cookie = register_cp((IUnknown*)div, &DIID_HTMLElementEvents2, (IUnknown*)&elem2_cp_obj);
1696
1697 SET_EXPECT(div_onclick);
1698 SET_EXPECT(div_onclick_disp);
1699 SET_EXPECT(div_onclick_attached);
1700 SET_EXPECT(elem2_cp_onclick);
1701 SET_EXPECT(body_onclick);
1702 SET_EXPECT(document_onclick);
1703 SET_EXPECT(doc_onclick_attached);
1704 SET_EXPECT(doccp_onclick);
1705 SET_EXPECT(invoke_onclick);
1706
1707 trace("click >>>\n");
1708 hres = IHTMLElement_click(div);
1709 ok(hres == S_OK, "click failed: %08x\n", hres);
1710 trace("click <<<\n");
1711
1712 CHECK_CALLED(div_onclick);
1713 CHECK_CALLED(div_onclick_disp);
1714 CHECK_CALLED(div_onclick_attached);
1715 CHECK_CALLED(elem2_cp_onclick);
1716 CHECK_CALLED(body_onclick);
1717 CHECK_CALLED(document_onclick);
1718 CHECK_CALLED(doc_onclick_attached);
1719 CHECK_CALLED(doccp_onclick);
1720 CHECK_CALLED(invoke_onclick);
1721
1722 unregister_cp((IUnknown*)div, &DIID_HTMLElementEvents2, elem2_cp_cookie);
1723 unregister_cp((IUnknown*)doc, &DIID_HTMLDocumentEvents, cp_cookie);
1724
1725 V_VT(&v) = VT_NULL;
1726 hres = IHTMLElement_put_onclick(div, v);
1727 ok(hres == S_OK, "put_onclick failed: %08x\n", hres);
1728
1729 hres = IHTMLElement_get_onclick(div, &v);
1730 ok(hres == S_OK, "get_onclick failed: %08x\n", hres);
1731 ok(V_VT(&v) == VT_NULL, "get_onclick returned vt %d\n", V_VT(&v));
1732
1733 elem_detach_event((IUnknown*)div, "onclick", (IDispatch*)&div_onclick_disp);
1734 elem_detach_event((IUnknown*)div, "onclick", (IDispatch*)&div_onclick_disp);
1735 elem_detach_event((IUnknown*)div, "test", (IDispatch*)&div_onclick_disp);
1736 doc_detach_event(doc, "onclick", (IDispatch*)&doc_onclick_attached_obj);
1737
1738 SET_EXPECT(div_onclick_attached);
1739 SET_EXPECT(body_onclick);
1740 SET_EXPECT(document_onclick);
1741 SET_EXPECT(invoke_onclick);
1742
1743 hres = IHTMLElement_click(div);
1744 ok(hres == S_OK, "click failed: %08x\n", hres);
1745
1746 CHECK_CALLED(div_onclick_attached);
1747 CHECK_CALLED(body_onclick);
1748 CHECK_CALLED(document_onclick);
1749 CHECK_CALLED(invoke_onclick);
1750
1751 IHTMLElement_Release(div);
1752 IHTMLElement_Release(body);
1753 }
1754
1755 static void test_onreadystatechange(IHTMLDocument2 *doc)
1756 {
1757 IHTMLFrameBase *iframe;
1758 IHTMLElement2 *elem2;
1759 IHTMLElement *elem;
1760 VARIANT v;
1761 BSTR str;
1762 HRESULT hres;
1763
1764 elem = get_elem_id(doc, "iframe");
1765 elem2 = get_elem2_iface((IUnknown*)elem);
1766 IHTMLElement_Release(elem);
1767
1768 V_VT(&v) = VT_EMPTY;
1769 hres = IHTMLElement2_get_onreadystatechange(elem2, &v);
1770 ok(hres == S_OK, "get_onreadystatechange failed: %08x\n", hres);
1771 ok(V_VT(&v) == VT_NULL, "V_VT(onreadystatechange) = %d\n", V_VT(&v));
1772
1773 V_VT(&v) = VT_DISPATCH;
1774 V_DISPATCH(&v) = (IDispatch*)&iframe_onreadystatechange_obj;
1775 hres = IHTMLElement2_put_onreadystatechange(elem2, v);
1776 ok(hres == S_OK, "put_onreadystatechange failed: %08x\n", hres);
1777
1778 V_VT(&v) = VT_EMPTY;
1779 hres = IHTMLElement2_get_onreadystatechange(elem2, &v);
1780 ok(hres == S_OK, "get_onreadystatechange failed: %08x\n", hres);
1781 ok(V_VT(&v) == VT_DISPATCH, "V_VT(onreadystatechange) = %d\n", V_VT(&v));
1782 ok(V_DISPATCH(&v) == (IDispatch*)&iframe_onreadystatechange_obj, "unexpected onreadystatechange value\n");
1783
1784 hres = IHTMLElement2_QueryInterface(elem2, &IID_IHTMLFrameBase, (void**)&iframe);
1785 IHTMLElement2_Release(elem2);
1786 ok(hres == S_OK, "Could not get IHTMLFrameBase iface: %08x\n", hres);
1787
1788 hres = IHTMLFrameBase_put_src(iframe, (str = a2bstr("about:blank")));
1789 SysFreeString(str);
1790 ok(hres == S_OK, "put_src failed: %08x\n", hres);
1791
1792 SET_EXPECT(iframe_onreadystatechange_loading);
1793 SET_EXPECT(iframedoc_onreadystatechange);
1794 SET_EXPECT(iframe_onreadystatechange_interactive);
1795 SET_EXPECT(iframe_onreadystatechange_complete);
1796 pump_msgs(&called_iframe_onreadystatechange_complete);
1797 CHECK_CALLED(iframe_onreadystatechange_loading);
1798 CHECK_CALLED(iframedoc_onreadystatechange);
1799 CHECK_CALLED(iframe_onreadystatechange_interactive);
1800 CHECK_CALLED(iframe_onreadystatechange_complete);
1801
1802 IHTMLFrameBase_Release(iframe);
1803 }
1804
1805 static void test_imgload(IHTMLDocument2 *doc)
1806 {
1807 IHTMLImgElement *img;
1808 IHTMLElement *elem;
1809 VARIANT v;
1810 BSTR str;
1811 HRESULT hres;
1812
1813 elem = get_elem_id(doc, "imgid");
1814 hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLImgElement, (void**)&img);
1815 IHTMLElement_Release(elem);
1816 ok(hres == S_OK, "Could not get IHTMLImgElement iface: %08x\n", hres);
1817
1818 V_VT(&v) = VT_EMPTY;
1819 hres = IHTMLImgElement_get_onload(img, &v);
1820 ok(hres == S_OK, "get_onload failed: %08x\n", hres);
1821 ok(V_VT(&v) == VT_NULL, "V_VT(onload) = %d\n", V_VT(&v));
1822
1823 V_VT(&v) = VT_DISPATCH;
1824 V_DISPATCH(&v) = (IDispatch*)&img_onload_obj;
1825 hres = IHTMLImgElement_put_onload(img, v);
1826 ok(hres == S_OK, "put_onload failed: %08x\n", hres);
1827
1828 V_VT(&v) = VT_EMPTY;
1829 hres = IHTMLImgElement_get_onload(img, &v);
1830 ok(hres == S_OK, "get_onload failed: %08x\n", hres);
1831 ok(V_VT(&v) == VT_DISPATCH, "V_VT(onload) = %d\n", V_VT(&v));
1832 ok(V_DISPATCH(&v) == (IDispatch*)&img_onload_obj, "V_DISPATCH(onload) != onloadkFunc\n");
1833 VariantClear(&v);
1834
1835 V_VT(&v) = VT_DISPATCH;
1836 V_DISPATCH(&v) = (IDispatch*)&img_onerror_obj;
1837 hres = IHTMLImgElement_put_onerror(img, v);
1838 ok(hres == S_OK, "put_onerror failed: %08x\n", hres);
1839
1840 V_VT(&v) = VT_EMPTY;
1841 hres = IHTMLImgElement_get_onerror(img, &v);
1842 ok(hres == S_OK, "get_onerror failed: %08x\n", hres);
1843 ok(V_VT(&v) == VT_DISPATCH, "V_VT(onerror) = %d\n", V_VT(&v));
1844 ok(V_DISPATCH(&v) == (IDispatch*)&img_onerror_obj, "V_DISPATCH(onerror) != onerrorFunc\n");
1845 VariantClear(&v);
1846
1847 str = a2bstr("https://www.winehq.org/images/winehq_logo_text.png");
1848 hres = IHTMLImgElement_put_src(img, str);
1849 ok(hres == S_OK, "put_src failed: %08x\n", hres);
1850 SysFreeString(str);
1851
1852 SET_EXPECT(img_onload);
1853 pump_msgs(&called_img_onload);
1854 CHECK_CALLED(img_onload);
1855
1856 SET_EXPECT(img_onerror);
1857
1858 str = a2bstr("about:blank");
1859 hres = IHTMLImgElement_put_src(img, str);
1860 ok(hres == S_OK, "put_src failed: %08x\n", hres);
1861 SysFreeString(str);
1862
1863 pump_msgs(&called_img_onerror); /* FIXME: should not be needed */
1864
1865 CHECK_CALLED(img_onerror);
1866
1867 IHTMLImgElement_Release(img);
1868 }
1869
1870 static void test_focus(IHTMLDocument2 *doc)
1871 {
1872 IHTMLElement2 *elem2;
1873 IHTMLElement *elem;
1874 VARIANT v;
1875 HRESULT hres;
1876
1877 elem = get_elem_id(doc, "inputid");
1878 elem2 = get_elem2_iface((IUnknown*)elem);
1879 IHTMLElement_Release(elem);
1880
1881 V_VT(&v) = VT_EMPTY;
1882 hres = IHTMLElement2_get_onfocus(elem2, &v);
1883 ok(hres == S_OK, "get_onfocus failed: %08x\n", hres);
1884 ok(V_VT(&v) == VT_NULL, "V_VT(onfocus) = %d\n", V_VT(&v));
1885
1886 V_VT(&v) = VT_DISPATCH;
1887 V_DISPATCH(&v) = (IDispatch*)&input_onfocus_obj;
1888 hres = IHTMLElement2_put_onfocus(elem2, v);
1889 ok(hres == S_OK, "put_onfocus failed: %08x\n", hres);
1890
1891 V_VT(&v) = VT_EMPTY;
1892 hres = IHTMLElement2_get_onfocus(elem2, &v);
1893 ok(hres == S_OK, "get_onfocus failed: %08x\n", hres);
1894 ok(V_VT(&v) == VT_DISPATCH, "V_VT(onfocus) = %d\n", V_VT(&v));
1895 ok(V_DISPATCH(&v) == (IDispatch*)&input_onfocus_obj, "V_DISPATCH(onfocus) != onfocusFunc\n");
1896 VariantClear(&v);
1897
1898 if(!winetest_interactive)
1899 ShowWindow(container_hwnd, SW_SHOW);
1900
1901 SetFocus(NULL);
1902 ok(!IsChild(container_hwnd, GetFocus()), "focus belongs to document window\n");
1903
1904 hres = IHTMLWindow2_focus(window);
1905 ok(hres == S_OK, "focus failed: %08x\n", hres);
1906
1907 ok(IsChild(container_hwnd, GetFocus()), "focus does not belong to document window\n");
1908 pump_msgs(NULL);
1909
1910 SET_EXPECT(input_onfocus);
1911 hres = IHTMLElement2_focus(elem2);
1912 pump_msgs(NULL);
1913 CHECK_CALLED(input_onfocus);
1914 ok(hres == S_OK, "focus failed: %08x\n", hres);
1915
1916 V_VT(&v) = VT_DISPATCH;
1917 V_DISPATCH(&v) = (IDispatch*)&input_onblur_obj;
1918 hres = IHTMLElement2_put_onblur(elem2, v);
1919 ok(hres == S_OK, "put_onblur failed: %08x\n", hres);
1920
1921 SET_EXPECT(input_onblur);
1922 hres = IHTMLElement2_blur(elem2);
1923 pump_msgs(NULL);
1924 CHECK_CALLED(input_onblur);
1925 ok(hres == S_OK, "blur failed: %08x\n", hres);
1926
1927 if(!winetest_interactive)
1928 ShowWindow(container_hwnd, SW_HIDE);
1929
1930 IHTMLElement2_Release(elem2);
1931 }
1932
1933 static void test_submit(IHTMLDocument2 *doc)
1934 {
1935 IHTMLElement *elem, *submit;
1936 IHTMLFormElement *form;
1937 VARIANT v;
1938 DWORD cp_cookie;
1939 HRESULT hres;
1940
1941 elem = get_elem_id(doc, "formid");
1942
1943 V_VT(&v) = VT_DISPATCH;
1944 V_DISPATCH(&v) = (IDispatch*)&form_onclick_obj;
1945 hres = IHTMLElement_put_onclick(elem, v);
1946 ok(hres == S_OK, "put_onclick failed: %08x\n", hres);
1947
1948 hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFormElement, (void**)&form);
1949 IHTMLElement_Release(elem);
1950 ok(hres == S_OK, "Could not get IHTMLFormElement iface: %08x\n", hres);
1951
1952 V_VT(&v) = VT_DISPATCH;
1953 V_DISPATCH(&v) = (IDispatch*)&form_onsubmit_obj;
1954 hres = IHTMLFormElement_put_onsubmit(form, v);
1955 ok(hres == S_OK, "put_onsubmit failed: %08x\n", hres);
1956
1957 IHTMLFormElement_Release(form);
1958
1959 submit = get_elem_id(doc, "submitid");
1960
1961 SET_EXPECT(form_onclick);
1962 SET_EXPECT(form_onsubmit);
1963 hres = IHTMLElement_click(submit);
1964 ok(hres == S_OK, "click failed: %08x\n", hres);
1965 CHECK_CALLED(form_onclick);
1966 CHECK_CALLED(form_onsubmit);
1967
1968 V_VT(&v) = VT_DISPATCH;
1969 V_DISPATCH(&v) = (IDispatch*)&submit_onclick_obj;
1970 hres = IHTMLElement_put_onclick(submit, v);
1971 ok(hres == S_OK, "put_onclick failed: %08x\n", hres);
1972
1973 SET_EXPECT(form_onclick);
1974 SET_EXPECT(submit_onclick);
1975 hres = IHTMLElement_click(submit);
1976 ok(hres == S_OK, "click failed: %08x\n", hres);
1977 CHECK_CALLED(form_onclick);
1978 CHECK_CALLED(submit_onclick);
1979
1980 elem_attach_event((IUnknown*)submit, "onclick", (IDispatch*)&submit_onclick_attached_obj);
1981
1982 SET_EXPECT(form_onclick);
1983 SET_EXPECT(submit_onclick);
1984 SET_EXPECT(submit_onclick_attached);
1985 hres = IHTMLElement_click(submit);
1986 ok(hres == S_OK, "click failed: %08x\n", hres);
1987 CHECK_CALLED(form_onclick);
1988 CHECK_CALLED(submit_onclick);
1989 CHECK_CALLED(submit_onclick_attached);
1990
1991 V_VT(&v) = VT_NULL;
1992 hres = IHTMLElement_put_onclick(submit, v);
1993 ok(hres == S_OK, "put_onclick failed: %08x\n", hres);
1994
1995 SET_EXPECT(form_onclick);
1996 SET_EXPECT(submit_onclick_attached);
1997 hres = IHTMLElement_click(submit);
1998 ok(hres == S_OK, "click failed: %08x\n", hres);
1999 CHECK_CALLED(form_onclick);
2000 CHECK_CALLED(submit_onclick_attached);
2001
2002 elem_detach_event((IUnknown*)submit, "onclick", (IDispatch*)&submit_onclick_attached_obj);
2003
2004 cp_cookie = register_cp((IUnknown*)doc, &DIID_HTMLDocumentEvents, (IUnknown*)&doccp_onclick_cancel_obj);
2005
2006 SET_EXPECT(form_onclick);
2007 SET_EXPECT(doccp_onclick_cancel);
2008 hres = IHTMLElement_click(submit);
2009 ok(hres == S_OK, "click failed: %08x\n", hres);
2010 CHECK_CALLED(form_onclick);
2011 CHECK_CALLED(doccp_onclick_cancel);
2012
2013 unregister_cp((IUnknown*)doc, &DIID_HTMLDocumentEvents, cp_cookie);
2014
2015 V_VT(&v) = VT_DISPATCH;
2016 V_DISPATCH(&v) = (IDispatch*)&submit_onclick_setret_obj;
2017 hres = IHTMLElement_put_onclick(submit, v);
2018 ok(hres == S_OK, "put_onclick failed: %08x\n", hres);
2019
2020 V_VT(&onclick_retval) = VT_BOOL;
2021 V_BOOL(&onclick_retval) = VARIANT_TRUE;
2022 V_VT(&onclick_event_retval) = VT_BOOL;
2023 V_BOOL(&onclick_event_retval) = VARIANT_TRUE;
2024
2025 SET_EXPECT(submit_onclick_setret);
2026 SET_EXPECT(form_onclick);
2027 SET_EXPECT(form_onsubmit);
2028 hres = IHTMLElement_click(submit);
2029 ok(hres == S_OK, "click failed: %08x\n", hres);
2030 CHECK_CALLED(submit_onclick_setret);
2031 CHECK_CALLED(form_onclick);
2032 CHECK_CALLED(form_onsubmit);
2033
2034 V_VT(&onclick_event_retval) = VT_BOOL;
2035 V_BOOL(&onclick_event_retval) = VARIANT_FALSE;
2036
2037 SET_EXPECT(submit_onclick_setret);
2038 SET_EXPECT(form_onclick);
2039 hres = IHTMLElement_click(submit);
2040 ok(hres == S_OK, "click failed: %08x\n", hres);
2041 CHECK_CALLED(submit_onclick_setret);
2042 CHECK_CALLED(form_onclick);
2043
2044 V_VT(&onclick_retval) = VT_BOOL;
2045 V_BOOL(&onclick_retval) = VARIANT_FALSE;
2046 V_VT(&onclick_event_retval) = VT_BOOL;
2047 V_BOOL(&onclick_event_retval) = VARIANT_TRUE;
2048
2049 SET_EXPECT(submit_onclick_setret);
2050 SET_EXPECT(form_onclick);
2051 hres = IHTMLElement_click(submit);
2052 ok(hres == S_OK, "click failed: %08x\n", hres);
2053 CHECK_CALLED(submit_onclick_setret);
2054 CHECK_CALLED(form_onclick);
2055
2056 V_VT(&onclick_event_retval) = VT_BOOL;
2057 V_BOOL(&onclick_event_retval) = VARIANT_FALSE;
2058
2059 SET_EXPECT(submit_onclick_setret);
2060 SET_EXPECT(form_onclick);
2061 hres = IHTMLElement_click(submit);
2062 ok(hres == S_OK, "click failed: %08x\n", hres);
2063 CHECK_CALLED(submit_onclick_setret);
2064 CHECK_CALLED(form_onclick);
2065
2066 elem_attach_event((IUnknown*)submit, "onclick", (IDispatch*)&submit_onclick_attached_obj);
2067 elem_attach_event((IUnknown*)submit, "onclick", (IDispatch*)&submit_onclick_attached_check_cancel_obj);
2068
2069 V_VT(&v) = VT_DISPATCH;
2070 V_DISPATCH(&v) = (IDispatch*)&submit_onclick_cancel_obj;
2071 hres = IHTMLElement_put_onclick(submit, v);
2072 ok(hres == S_OK, "put_onclick failed: %08x\n", hres);
2073
2074 SET_EXPECT(submit_onclick_cancel);
2075 SET_EXPECT(submit_onclick_attached_check_cancel);
2076 SET_EXPECT(submit_onclick_attached);
2077 hres = IHTMLElement_click(submit);
2078 ok(hres == S_OK, "click failed: %08x\n", hres);
2079 CHECK_CALLED(submit_onclick_cancel);
2080 CHECK_CALLED(submit_onclick_attached_check_cancel);
2081 CHECK_CALLED(submit_onclick_attached);
2082
2083 if(1)pump_msgs(NULL);
2084
2085 IHTMLElement_Release(submit);
2086 }
2087
2088 static void test_timeout(IHTMLDocument2 *doc)
2089 {
2090 IHTMLWindow3 *win3;
2091 VARIANT expr, var;
2092 LONG id;
2093 HRESULT hres;
2094
2095 hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow3, (void**)&win3);
2096 ok(hres == S_OK, "Could not get IHTMLWindow3 iface: %08x\n", hres);
2097
2098 V_VT(&expr) = VT_DISPATCH;
2099 V_DISPATCH(&expr) = (IDispatch*)&timeoutFunc;
2100 V_VT(&var) = VT_EMPTY;
2101 id = 0;
2102 hres = IHTMLWindow3_setTimeout(win3, &expr, 0, &var, &id);
2103 ok(hres == S_OK, "setTimeout failed: %08x\n", hres);
2104 ok(id, "id = 0\n");
2105
2106 SET_EXPECT(timeout);
2107 pump_msgs(&called_timeout);
2108 CHECK_CALLED(timeout);
2109
2110 V_VT(&expr) = VT_DISPATCH;
2111 V_DISPATCH(&expr) = (IDispatch*)&timeoutFunc;
2112 V_VT(&var) = VT_EMPTY;
2113 id = 0;
2114 hres = IHTMLWindow3_setTimeout(win3, &expr, 0, &var, &id);
2115 ok(hres == S_OK, "setTimeout failed: %08x\n", hres);
2116 ok(id, "id = 0\n");
2117
2118 hres = IHTMLWindow2_clearTimeout(window, id);
2119 ok(hres == S_OK, "clearTimeout failed: %08x\n", hres);
2120
2121 IHTMLWindow3_Release(win3);
2122 }
2123
2124 static IHTMLElement* find_element_by_id(IHTMLDocument2 *doc, const char *id)
2125 {
2126 HRESULT hres;
2127 IHTMLDocument3 *doc3;
2128 IHTMLElement *result;
2129 BSTR idW = a2bstr(id);
2130
2131 hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
2132 ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08x\n", hres);
2133
2134 hres = IHTMLDocument3_getElementById(doc3, idW, &result);
2135 ok(hres == S_OK, "getElementById failed: %08x\n", hres);
2136 ok(result != NULL, "result == NULL\n");
2137 SysFreeString(idW);
2138
2139 IHTMLDocument3_Release(doc3);
2140 return result;
2141 }
2142
2143 static IHTMLDocument2* get_iframe_doc(IHTMLIFrameElement *iframe)
2144 {
2145 HRESULT hres;
2146 IHTMLFrameBase2 *base;
2147 IHTMLDocument2 *result = NULL;
2148
2149 hres = IHTMLIFrameElement_QueryInterface(iframe, &IID_IHTMLFrameBase2, (void**)&base);
2150 ok(hres == S_OK, "QueryInterface(IID_IHTMLFrameBase2) failed: %08x\n", hres);
2151 if(hres == S_OK) {
2152 IHTMLWindow2 *window;
2153
2154 hres = IHTMLFrameBase2_get_contentWindow(base, &window);
2155 ok(hres == S_OK, "get_contentWindow failed: %08x\n", hres);
2156 ok(window != NULL, "window == NULL\n");
2157 if(window) {
2158 hres = IHTMLWindow2_get_document(window, &result);
2159 ok(hres == S_OK, "get_document failed: %08x\n", hres);
2160 ok(result != NULL, "result == NULL\n");
2161 IHTMLWindow2_Release(window);
2162 }
2163 }
2164 if(base) IHTMLFrameBase2_Release(base);
2165
2166 return result;
2167 }
2168
2169 static void test_iframe_connections(IHTMLDocument2 *doc)
2170 {
2171 IHTMLIFrameElement *iframe;
2172 IHTMLDocument2 *iframes_doc;
2173 DWORD cookie;
2174 IConnectionPoint *cp;
2175 IHTMLElement *element;
2176 BSTR str;
2177 HRESULT hres;
2178
2179 trace("iframe tests...\n");
2180
2181 element = find_element_by_id(doc, "ifr");
2182 iframe = get_iframe_iface((IUnknown*)element);
2183 IHTMLElement_Release(element);
2184
2185 iframes_doc = get_iframe_doc(iframe);
2186 IHTMLIFrameElement_Release(iframe);
2187
2188 cookie = register_cp((IUnknown*)iframes_doc, &IID_IDispatch, (IUnknown*)&div_onclick_disp);
2189
2190 cp = get_cp((IUnknown*)doc, &IID_IDispatch);
2191 hres = IConnectionPoint_Unadvise(cp, cookie);
2192 IConnectionPoint_Release(cp);
2193 ok(hres == CONNECT_E_NOCONNECTION, "Unadvise returned %08x, expected CONNECT_E_NOCONNECTION\n", hres);
2194
2195 unregister_cp((IUnknown*)iframes_doc, &IID_IDispatch, cookie);
2196
2197 if(is_ie9plus) {
2198 IHTMLFrameBase2 *frame_base2;
2199 VARIANT v;
2200
2201 hres = IHTMLIFrameElement_QueryInterface(iframe, &IID_IHTMLFrameBase2, (void**)&frame_base2);
2202 ok(hres == S_OK, "Could not get IHTMLFrameBase2 iface: %08x\n", hres);
2203
2204 V_VT(&v) = VT_DISPATCH;
2205 V_DISPATCH(&v) = (IDispatch*)&iframe_onload_obj;
2206 hres = IHTMLFrameBase2_put_onload(frame_base2, v);
2207 ok(hres == S_OK, "put_onload failed: %08x\n", hres);
2208
2209 IHTMLFrameBase2_Release(frame_base2);
2210
2211 str = a2bstr("about:blank");
2212 hres = IHTMLDocument2_put_URL(iframes_doc, str);
2213 ok(hres == S_OK, "put_URL failed: %08x\n", hres);
2214 SysFreeString(str);
2215
2216 SET_EXPECT(iframe_onload);
2217 pump_msgs(&called_iframe_onload);
2218 CHECK_CALLED(iframe_onload);
2219
2220 str = a2bstr("about:test");
2221 hres = IHTMLDocument2_put_URL(iframes_doc, str);
2222 ok(hres == S_OK, "put_URL failed: %08x\n", hres);
2223 SysFreeString(str);
2224
2225 SET_EXPECT(iframe_onload);
2226 pump_msgs(&called_iframe_onload);
2227 CHECK_CALLED(iframe_onload);
2228 }else {
2229 win_skip("Skipping iframe onload tests on IE older than 9.\n");
2230 }
2231
2232 IHTMLDocument2_Release(iframes_doc);
2233 }
2234
2235 static HRESULT QueryInterface(REFIID,void**);
2236
2237 static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv)
2238 {
2239 return E_NOINTERFACE;
2240 }
2241
2242 static ULONG WINAPI InPlaceFrame_AddRef(IOleInPlaceFrame *iface)
2243 {
2244 return 2;
2245 }
2246
2247 static ULONG WINAPI InPlaceFrame_Release(IOleInPlaceFrame *iface)
2248 {
2249 return 1;
2250 }
2251
2252 static HRESULT WINAPI InPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd)
2253 {
2254 return E_NOTIMPL;
2255 }
2256
2257 static HRESULT WINAPI InPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode)
2258 {
2259 return E_NOTIMPL;
2260 }
2261
2262 static HRESULT WINAPI InPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder)
2263 {
2264 return E_NOTIMPL;
2265 }
2266
2267 static HRESULT WINAPI InPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface,
2268 LPCBORDERWIDTHS pborderwidths)
2269 {
2270 return E_NOTIMPL;
2271 }
2272
2273 static HRESULT WINAPI InPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface,
2274 LPCBORDERWIDTHS pborderwidths)
2275 {
2276 return S_OK;
2277 }
2278
2279 static HRESULT WINAPI InPlaceUIWindow_SetActiveObject(IOleInPlaceFrame *iface,
2280 IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
2281 {
2282 return S_OK;
2283 }
2284
2285 static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface,
2286 IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
2287 {
2288 return S_OK;
2289 }
2290
2291 static HRESULT WINAPI InPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared,
2292 LPOLEMENUGROUPWIDTHS lpMenuWidths)
2293 {
2294 return E_NOTIMPL;
2295 }
2296
2297 static HRESULT WINAPI InPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared,
2298 HOLEMENU holemenu, HWND hwndActiveObject)
2299 {
2300 ok(0, "unexpected call\n");
2301 return E_NOTIMPL;
2302 }
2303
2304 static HRESULT WINAPI InPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared)
2305 {
2306 ok(0, "unexpected call\n");
2307 return E_NOTIMPL;
2308 }
2309
2310 static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText)
2311 {
2312 return S_OK;
2313 }
2314
2315 static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
2316 {
2317 return E_NOTIMPL;
2318 }
2319
2320 static HRESULT WINAPI InPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID)
2321 {
2322 ok(0, "unexpected call\n");
2323 return E_NOTIMPL;
2324 }
2325
2326 static const IOleInPlaceFrameVtbl InPlaceFrameVtbl = {
2327 InPlaceFrame_QueryInterface,
2328 InPlaceFrame_AddRef,
2329 InPlaceFrame_Release,
2330 InPlaceFrame_GetWindow,
2331 InPlaceFrame_ContextSensitiveHelp,
2332 InPlaceFrame_GetBorder,
2333 InPlaceFrame_RequestBorderSpace,
2334 InPlaceFrame_SetBorderSpace,
2335 InPlaceFrame_SetActiveObject,
2336 InPlaceFrame_InsertMenus,
2337 InPlaceFrame_SetMenu,
2338 InPlaceFrame_RemoveMenus,
2339 InPlaceFrame_SetStatusText,
2340 InPlaceFrame_EnableModeless,
2341 InPlaceFrame_TranslateAccelerator
2342 };
2343
2344 static IOleInPlaceFrame InPlaceFrame = { &InPlaceFrameVtbl };
2345
2346 static const IOleInPlaceFrameVtbl InPlaceUIWindowVtbl = {
2347 InPlaceFrame_QueryInterface,
2348 InPlaceFrame_AddRef,
2349 InPlaceFrame_Release,
2350 InPlaceFrame_GetWindow,
2351 InPlaceFrame_ContextSensitiveHelp,
2352 InPlaceFrame_GetBorder,
2353 InPlaceFrame_RequestBorderSpace,
2354 InPlaceFrame_SetBorderSpace,
2355 InPlaceUIWindow_SetActiveObject,
2356 };
2357
2358 static IOleInPlaceFrame InPlaceUIWindow = { &InPlaceUIWindowVtbl };
2359
2360 static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppv)
2361 {
2362 return QueryInterface(riid, ppv);
2363 }
2364
2365 static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSite *iface)
2366 {
2367 return 2;
2368 }
2369
2370 static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSite *iface)
2371 {
2372 return 1;
2373 }
2374
2375 static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSite *iface, HWND *phwnd)
2376 {
2377 *phwnd = container_hwnd;
2378 return S_OK;
2379 }
2380
2381 static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
2382 {
2383 ok(0, "unexpected call\n");
2384 return E_NOTIMPL;
2385 }
2386
2387 static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSite *iface)
2388 {
2389 return S_OK;
2390 }
2391
2392 static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSite *iface)
2393 {
2394 return S_OK;
2395 }
2396
2397 static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSite *iface)
2398 {
2399 return S_OK;
2400 }
2401
2402 static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSite *iface,
2403 IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
2404 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
2405 {
2406 static const RECT rect = {0,0,300,300};
2407
2408 *ppFrame = &InPlaceFrame;
2409 *ppDoc = (IOleInPlaceUIWindow*)&InPlaceUIWindow;
2410 *lprcPosRect = rect;
2411 *lprcClipRect = rect;
2412
2413 ok(lpFrameInfo->cb == sizeof(*lpFrameInfo), "lpFrameInfo->cb = %u, expected %u\n", lpFrameInfo->cb, (unsigned)sizeof(*lpFrameInfo));
2414 lpFrameInfo->fMDIApp = FALSE;
2415 lpFrameInfo->hwndFrame = container_hwnd;
2416 lpFrameInfo->haccel = NULL;
2417 lpFrameInfo->cAccelEntries = 0;
2418
2419 return S_OK;
2420 }
2421
2422 static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSite *iface, SIZE scrollExtant)
2423 {
2424 return E_NOTIMPL;
2425 }
2426
2427 static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
2428 {
2429 return S_OK;
2430 }
2431
2432 static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSite *iface)
2433 {
2434 return S_OK;
2435 }
2436
2437 static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSite *iface)
2438 {
2439 return E_NOTIMPL;
2440 }
2441
2442 static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSite *iface)
2443 {
2444 return E_NOTIMPL;
2445 }
2446
2447 static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
2448 {
2449 return E_NOTIMPL;
2450 }
2451
2452 static const IOleInPlaceSiteVtbl InPlaceSiteVtbl = {
2453 InPlaceSite_QueryInterface,
2454 InPlaceSite_AddRef,
2455 InPlaceSite_Release,
2456 InPlaceSite_GetWindow,
2457 InPlaceSite_ContextSensitiveHelp,
2458 InPlaceSite_CanInPlaceActivate,
2459 InPlaceSite_OnInPlaceActivate,
2460 InPlaceSite_OnUIActivate,
2461 InPlaceSite_GetWindowContext,
2462 InPlaceSite_Scroll,
2463 InPlaceSite_OnUIDeactivate,
2464 InPlaceSite_OnInPlaceDeactivate,
2465 InPlaceSite_DiscardUndoState,
2466 InPlaceSite_DeactivateAndUndo,
2467 InPlaceSite_OnPosRectChange,
2468 };
2469
2470 static IOleInPlaceSite InPlaceSite = { &InPlaceSiteVtbl };
2471
2472 static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
2473 {
2474 return QueryInterface(riid, ppv);
2475 }
2476
2477 static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface)
2478 {
2479 return 2;
2480 }
2481
2482 static ULONG WINAPI ClientSite_Release(IOleClientSite *iface)
2483 {
2484 return 1;
2485 }
2486
2487 static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface)
2488 {
2489 ok(0, "unexpected call\n");
2490 return E_NOTIMPL;
2491 }
2492
2493 static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker,
2494 IMoniker **ppmon)
2495 {
2496 ok(0, "unexpected call\n");
2497 return E_NOTIMPL;
2498 }
2499
2500 static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
2501 {
2502 return E_NOTIMPL;
2503 }
2504
2505 static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface)
2506 {
2507 ok(0, "unexpected call\n");
2508 return E_NOTIMPL;
2509 }
2510
2511 static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
2512 {
2513 ok(0, "unexpected call\n");
2514 return E_NOTIMPL;
2515 }
2516
2517 static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface)
2518 {
2519 ok(0, "unexpected call\n");
2520 return E_NOTIMPL;
2521 }
2522
2523 static const IOleClientSiteVtbl ClientSiteVtbl = {
2524 ClientSite_QueryInterface,
2525 ClientSite_AddRef,
2526 ClientSite_Release,
2527 ClientSite_SaveObject,
2528 ClientSite_GetMoniker,
2529 ClientSite_GetContainer,
2530 ClientSite_ShowObject,
2531 ClientSite_OnShowWindow,
2532 ClientSite_RequestNewObjectLayout
2533 };
2534
2535 static IOleClientSite ClientSite = { &ClientSiteVtbl };
2536
2537 static HRESULT WINAPI DocumentSite_QueryInterface(IOleDocumentSite *iface, REFIID riid, void **ppv)
2538 {
2539 return QueryInterface(riid, ppv);
2540 }
2541
2542 static ULONG WINAPI DocumentSite_AddRef(IOleDocumentSite *iface)
2543 {
2544 return 2;
2545 }
2546
2547 static ULONG WINAPI DocumentSite_Release(IOleDocumentSite *iface)
2548 {
2549 return 1;
2550 }
2551
2552 static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocumentView *pViewToActivate)
2553 {
2554 RECT rect = {0,0,300,300};
2555 IOleDocument *document;
2556 HRESULT hres;
2557
2558 hres = IOleDocumentView_QueryInterface(pViewToActivate, &IID_IOleDocument, (void**)&document);
2559 ok(hres == S_OK, "could not get IOleDocument: %08x\n", hres);
2560
2561 hres = IOleDocument_CreateView(document, &InPlaceSite, NULL, 0, &view);
2562 IOleDocument_Release(document);
2563 ok(hres == S_OK, "CreateView failed: %08x\n", hres);
2564
2565 hres = IOleDocumentView_SetInPlaceSite(view, &InPlaceSite);
2566 ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
2567
2568 hres = IOleDocumentView_UIActivate(view, TRUE);
2569 ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
2570
2571 hres = IOleDocumentView_SetRect(view, &rect);
2572 ok(hres == S_OK, "SetRect failed: %08x\n", hres);
2573
2574 hres = IOleDocumentView_Show(view, TRUE);
2575 ok(hres == S_OK, "Show failed: %08x\n", hres);
2576
2577 return S_OK;
2578 }
2579
2580 static const IOleDocumentSiteVtbl DocumentSiteVtbl = {
2581 DocumentSite_QueryInterface,
2582 DocumentSite_AddRef,
2583 DocumentSite_Release,
2584 DocumentSite_ActivateMe
2585 };
2586
2587 static IOleDocumentSite DocumentSite = { &DocumentSiteVtbl };
2588
2589 static HRESULT QueryInterface(REFIID riid, void **ppv)
2590 {
2591 *ppv = NULL;
2592
2593 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IOleClientSite, riid))
2594 *ppv = &ClientSite;
2595 else if(IsEqualGUID(&IID_IOleDocumentSite, riid))
2596 *ppv = &DocumentSite;
2597 else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid))
2598 *ppv = &InPlaceSite;
2599
2600 return *ppv ? S_OK : E_NOINTERFACE;
2601 }
2602
2603 static IHTMLDocument2 *notif_doc;
2604 static BOOL doc_complete;
2605
2606 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
2607 REFIID riid, void**ppv)
2608 {
2609 if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
2610 *ppv = iface;
2611 return S_OK;
2612 }
2613
2614 ok(0, "unexpected call\n");
2615 return E_NOINTERFACE;
2616 }
2617
2618 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
2619 {
2620 return 2;
2621 }
2622
2623 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
2624 {
2625 return 1;
2626 }
2627
2628 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
2629 {
2630 if(dispID == DISPID_READYSTATE){
2631 BSTR state;
2632 HRESULT hres;
2633
2634 hres = IHTMLDocument2_get_readyState(notif_doc, &state);
2635 ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
2636
2637 if(!strcmp_wa(state, "complete"))
2638 doc_complete = TRUE;
2639
2640 SysFreeString(state);
2641 }
2642
2643 return S_OK;
2644 }
2645
2646 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
2647 {
2648 ok(0, "unexpected call\n");
2649 return E_NOTIMPL;
2650 }
2651
2652 static const IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
2653 PropertyNotifySink_QueryInterface,
2654 PropertyNotifySink_AddRef,
2655 PropertyNotifySink_Release,
2656 PropertyNotifySink_OnChanged,
2657 PropertyNotifySink_OnRequestEdit
2658 };
2659
2660 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
2661
2662 static void doc_load_string(IHTMLDocument2 *doc, const char *str)
2663 {
2664 IPersistStreamInit *init;
2665 IStream *stream;
2666 HGLOBAL mem;
2667 SIZE_T len;
2668
2669 notif_doc = doc;
2670
2671 doc_complete = FALSE;
2672 len = strlen(str);
2673 mem = GlobalAlloc(0, len);
2674 memcpy(mem, str, len);
2675 CreateStreamOnHGlobal(mem, TRUE, &stream);
2676
2677 IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init);
2678
2679 IPersistStreamInit_Load(init, stream);
2680 IPersistStreamInit_Release(init);
2681 IStream_Release(stream);
2682 }
2683
2684 static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise)
2685 {
2686 IConnectionPointContainer *container;
2687 IConnectionPoint *cp;
2688 DWORD cookie;
2689 HRESULT hres;
2690
2691 hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
2692 ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
2693
2694 hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
2695 IConnectionPointContainer_Release(container);
2696 ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
2697
2698 hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
2699 IConnectionPoint_Release(cp);
2700 ok(hres == S_OK, "Advise failed: %08x\n", hres);
2701 }
2702
2703 static void set_client_site(IHTMLDocument2 *doc, BOOL set)
2704 {
2705 IOleObject *oleobj;
2706 HRESULT hres;
2707
2708 if(!set && view) {
2709 IOleDocumentView_Show(view, FALSE);
2710 IOleDocumentView_CloseView(view, 0);
2711 IOleDocumentView_SetInPlaceSite(view, NULL);
2712 IOleDocumentView_Release(view);
2713 view = NULL;
2714 }
2715
2716 hres = IHTMLDocument2_QueryInterface(doc, &IID_IOleObject, (void**)&oleobj);
2717 ok(hres == S_OK, "Could not et IOleObject: %08x\n", hres);
2718
2719 hres = IOleObject_SetClientSite(oleobj, set ? &ClientSite : NULL);
2720 ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
2721
2722 if(set) {
2723 IHlinkTarget *hlink;
2724
2725 hres = IOleObject_QueryInterface(oleobj, &IID_IHlinkTarget, (void**)&hlink);
2726 ok(hres == S_OK, "Could not get IHlinkTarget iface: %08x\n", hres);
2727
2728 hres = IHlinkTarget_Navigate(hlink, 0, NULL);
2729 ok(hres == S_OK, "Navgate failed: %08x\n", hres);
2730
2731 IHlinkTarget_Release(hlink);
2732 }
2733
2734 IOleObject_Release(oleobj);
2735 }
2736 static IHTMLDocument2 *create_document(void)
2737 {
2738 IHTMLDocument2 *doc;
2739 HRESULT hres;
2740
2741 hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2742 &IID_IHTMLDocument2, (void**)&doc);
2743 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2744 return SUCCEEDED(hres) ? doc : NULL;
2745 }
2746
2747
2748 typedef void (*testfunc_t)(IHTMLDocument2*);
2749
2750 static void run_test(const char *str, testfunc_t test)
2751 {
2752 IHTMLDocument2 *doc;
2753 IHTMLElement *body = NULL;
2754 MSG msg;
2755 HRESULT hres;
2756
2757 doc = create_document();
2758 if (!doc)
2759 return;
2760 set_client_site(doc, TRUE);
2761 doc_load_string(doc, str);
2762 do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
2763
2764 while(!doc_complete && GetMessageA(&msg, NULL, 0, 0)) {
2765 TranslateMessage(&msg);
2766 DispatchMessageA(&msg);
2767 }
2768
2769 hres = IHTMLDocument2_get_body(doc, &body);
2770 ok(hres == S_OK, "get_body failed: %08x\n", hres);
2771
2772 if(body) {
2773 IHTMLElement_Release(body);
2774
2775 hres = IHTMLDocument2_get_parentWindow(doc, &window);
2776 ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
2777 ok(window != NULL, "window == NULL\n");
2778
2779 test(doc);
2780
2781 IHTMLWindow2_Release(window);
2782 window = NULL;
2783 }else {
2784 skip("Could not get document body. Assuming no Gecko installed.\n");
2785 }
2786
2787 set_client_site(doc, FALSE);
2788 IHTMLDocument2_Release(doc);
2789 }
2790
2791 static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2792 {
2793 return DefWindowProcA(hwnd, msg, wParam, lParam);
2794 }
2795
2796 static HWND create_container_window(void)
2797 {
2798 static const CHAR szHTMLDocumentTest[] = "HTMLDocumentTest";
2799 static WNDCLASSEXA wndclass = {
2800 sizeof(WNDCLASSEXA),
2801 0,
2802 wnd_proc,
2803 0, 0, NULL, NULL, NULL, NULL, NULL,
2804 szHTMLDocumentTest,
2805 NULL
2806 };
2807
2808 RegisterClassExA(&wndclass);
2809 return CreateWindowA(szHTMLDocumentTest, szHTMLDocumentTest,
2810 WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
2811 300, 300, NULL, NULL, NULL, NULL);
2812 }
2813
2814 static void test_empty_document(void)
2815 {
2816 HRESULT hres;
2817 IHTMLWindow2 *window;
2818 IHTMLDocument2 *windows_doc, *doc;
2819 IConnectionPoint *cp;
2820 DWORD cookie;
2821
2822 doc = create_document();
2823 if(!doc)
2824 return;
2825
2826 hres = IHTMLDocument2_get_parentWindow(doc, &window);
2827 ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
2828
2829 hres = IHTMLWindow2_get_document(window, &windows_doc);
2830 IHTMLWindow2_Release(window);
2831 ok(hres == S_OK, "get_document failed: %08x\n", hres);
2832
2833 cookie = register_cp((IUnknown*)windows_doc, &IID_IDispatch, (IUnknown*)&div_onclick_disp);
2834
2835 cp = get_cp((IUnknown*)doc, &IID_IDispatch);
2836 hres = IConnectionPoint_Unadvise(cp, cookie);
2837 IConnectionPoint_Release(cp);
2838 ok(hres == S_OK, "Unadvise failed: %08x\n", hres);
2839
2840 IHTMLDocument2_Release(windows_doc);
2841 IHTMLDocument2_Release(doc);
2842 }
2843
2844 static BOOL check_ie(void)
2845 {
2846 IHTMLDocument2 *doc;
2847 IHTMLDocument5 *doc5;
2848 IHTMLDocument7 *doc7;
2849 HRESULT hres;
2850
2851 doc = create_document();
2852 if(!doc)
2853 return FALSE;
2854
2855 hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument7, (void**)&doc7);
2856 if(SUCCEEDED(hres)) {
2857 is_ie9plus = TRUE;
2858 IHTMLDocument7_Release(doc7);
2859 }
2860
2861 trace("is_ie9plus %x\n", is_ie9plus);
2862
2863 hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
2864 if(SUCCEEDED(hres))
2865 IHTMLDocument5_Release(doc5);
2866
2867 IHTMLDocument2_Release(doc);
2868 return SUCCEEDED(hres);
2869 }
2870
2871 START_TEST(events)
2872 {
2873 CoInitialize(NULL);
2874
2875 if(check_ie()) {
2876 container_hwnd = create_container_window();
2877
2878 if(winetest_interactive)
2879 ShowWindow(container_hwnd, SW_SHOW);
2880
2881 run_test(empty_doc_str, test_timeout);
2882 run_test(click_doc_str, test_onclick);
2883 run_test(readystate_doc_str, test_onreadystatechange);
2884 run_test(img_doc_str, test_imgload);
2885 run_test(input_doc_str, test_focus);
2886 run_test(form_doc_str, test_submit);
2887 run_test(iframe_doc_str, test_iframe_connections);
2888
2889 test_empty_document();
2890
2891 DestroyWindow(container_hwnd);
2892 }else {
2893 win_skip("Too old IE\n");
2894 }
2895
2896 CoUninitialize();
2897 }