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