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