mshtml: Added IHTMLWindow3::attachEvent implementation.
[wine] / dlls / mshtml / htmlwindow.c
1 /*
2  * Copyright 2006 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 #include <stdarg.h>
20
21 #define COBJMACROS
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "ole2.h"
27
28 #include "wine/debug.h"
29 #include "wine/unicode.h"
30
31 #include "mshtml_private.h"
32 #include "htmlevent.h"
33 #include "resource.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
36
37 static struct list window_list = LIST_INIT(window_list);
38
39 #define HTMLWINDOW2_THIS(iface) DEFINE_THIS(HTMLWindow, HTMLWindow2, iface)
40
41 static HRESULT WINAPI HTMLWindow2_QueryInterface(IHTMLWindow2 *iface, REFIID riid, void **ppv)
42 {
43     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
44
45     *ppv = NULL;
46
47     if(IsEqualGUID(&IID_IUnknown, riid)) {
48         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
49         *ppv = HTMLWINDOW2(This);
50     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
51         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
52         *ppv = HTMLWINDOW2(This);
53     }else if(IsEqualGUID(&IID_IDispatchEx, riid)) {
54         TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv);
55         *ppv = DISPATCHEX(This);
56     }else if(IsEqualGUID(&IID_IHTMLFramesCollection2, riid)) {
57         TRACE("(%p)->(IID_IHTMLFramesCollection2 %p)\n", This, ppv);
58         *ppv = HTMLWINDOW2(This);
59     }else if(IsEqualGUID(&IID_IHTMLWindow2, riid)) {
60         TRACE("(%p)->(IID_IHTMLWindow2 %p)\n", This, ppv);
61         *ppv = HTMLWINDOW2(This);
62     }else if(IsEqualGUID(&IID_IHTMLWindow3, riid)) {
63         TRACE("(%p)->(IID_IHTMLWindow2 %p)\n", This, ppv);
64         *ppv = HTMLWINDOW3(This);
65     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
66         return *ppv ? S_OK : E_NOINTERFACE;
67     }
68
69     if(*ppv) {
70         IUnknown_AddRef((IUnknown*)*ppv);
71         return S_OK;
72     }
73
74     WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
75     return E_NOINTERFACE;
76 }
77
78 static ULONG WINAPI HTMLWindow2_AddRef(IHTMLWindow2 *iface)
79 {
80     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
81     LONG ref = InterlockedIncrement(&This->ref);
82
83     TRACE("(%p) ref=%d\n", This, ref);
84
85     return ref;
86 }
87
88 static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface)
89 {
90     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
91     LONG ref = InterlockedDecrement(&This->ref);
92
93     TRACE("(%p) ref=%d\n", This, ref);
94
95     if(!ref) {
96         if(This->event_target)
97             release_event_target(This->event_target);
98         list_remove(&This->entry);
99         release_dispex(&This->dispex);
100         heap_free(This);
101     }
102
103     return ref;
104 }
105
106 static HRESULT WINAPI HTMLWindow2_GetTypeInfoCount(IHTMLWindow2 *iface, UINT *pctinfo)
107 {
108     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
109
110     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo);
111 }
112
113 static HRESULT WINAPI HTMLWindow2_GetTypeInfo(IHTMLWindow2 *iface, UINT iTInfo,
114                                               LCID lcid, ITypeInfo **ppTInfo)
115 {
116     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
117
118     return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo);
119 }
120
121 static HRESULT WINAPI HTMLWindow2_GetIDsOfNames(IHTMLWindow2 *iface, REFIID riid,
122                                                 LPOLESTR *rgszNames, UINT cNames,
123                                                 LCID lcid, DISPID *rgDispId)
124 {
125     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
126
127     return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId);
128 }
129
130 static HRESULT WINAPI HTMLWindow2_Invoke(IHTMLWindow2 *iface, DISPID dispIdMember,
131                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
132                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
133 {
134     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
135
136     return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams,
137             pVarResult, pExcepInfo, puArgErr);
138 }
139
140 static HRESULT WINAPI HTMLWindow2_item(IHTMLWindow2 *iface, VARIANT *pvarIndex, VARIANT *pvarResult)
141 {
142     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
143     FIXME("(%p)->(%p %p)\n", This, pvarIndex, pvarResult);
144     return E_NOTIMPL;
145 }
146
147 static HRESULT WINAPI HTMLWindow2_get_length(IHTMLWindow2 *iface, LONG *p)
148 {
149     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
150     FIXME("(%p)->(%p)\n", This, p);
151     return E_NOTIMPL;
152 }
153
154 static HRESULT WINAPI HTMLWindow2_get_frames(IHTMLWindow2 *iface, IHTMLFramesCollection2 **p)
155 {
156     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
157     FIXME("(%p)->(%p)\n", This, p);
158     return E_NOTIMPL;
159 }
160
161 static HRESULT WINAPI HTMLWindow2_put_defaultStatus(IHTMLWindow2 *iface, BSTR v)
162 {
163     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
164     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
165     return E_NOTIMPL;
166 }
167
168 static HRESULT WINAPI HTMLWindow2_get_defaultStatus(IHTMLWindow2 *iface, BSTR *p)
169 {
170     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
171     FIXME("(%p)->(%p)\n", This, p);
172     return E_NOTIMPL;
173 }
174
175 static HRESULT WINAPI HTMLWindow2_put_status(IHTMLWindow2 *iface, BSTR v)
176 {
177     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
178     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
179     return E_NOTIMPL;
180 }
181
182 static HRESULT WINAPI HTMLWindow2_get_status(IHTMLWindow2 *iface, BSTR *p)
183 {
184     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
185     FIXME("(%p)->(%p)\n", This, p);
186     return E_NOTIMPL;
187 }
188
189 static HRESULT WINAPI HTMLWindow2_setTimeout(IHTMLWindow2 *iface, BSTR expression,
190         LONG msec, VARIANT *language, LONG *timerID)
191 {
192     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
193     VARIANT expr_var;
194
195     TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(expression), msec, language, timerID);
196
197     V_VT(&expr_var) = VT_BSTR;
198     V_BSTR(&expr_var) = expression;
199
200     return IHTMLWindow3_setTimeout(HTMLWINDOW3(This), &expr_var, msec, language, timerID);
201 }
202
203 static HRESULT WINAPI HTMLWindow2_clearTimeout(IHTMLWindow2 *iface, LONG timerID)
204 {
205     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
206
207     TRACE("(%p)->(%d)\n", This, timerID);
208
209     return clear_task_timer(This->doc, FALSE, timerID);
210 }
211
212 static HRESULT WINAPI HTMLWindow2_alert(IHTMLWindow2 *iface, BSTR message)
213 {
214     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
215     WCHAR wszTitle[100];
216
217     TRACE("(%p)->(%s)\n", This, debugstr_w(message));
218
219     if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
220                     sizeof(wszTitle)/sizeof(WCHAR))) {
221         WARN("Could not load message box title: %d\n", GetLastError());
222         return S_OK;
223     }
224
225     MessageBoxW(This->doc->hwnd, message, wszTitle, MB_ICONWARNING);
226     return S_OK;
227 }
228
229 static HRESULT WINAPI HTMLWindow2_confirm(IHTMLWindow2 *iface, BSTR message,
230         VARIANT_BOOL *confirmed)
231 {
232     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
233     WCHAR wszTitle[100];
234
235     TRACE("(%p)->(%s %p)\n", This, debugstr_w(message), confirmed);
236
237     if(!confirmed) return E_INVALIDARG;
238
239     if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
240                 sizeof(wszTitle)/sizeof(WCHAR))) {
241         WARN("Could not load message box title: %d\n", GetLastError());
242         *confirmed = VARIANT_TRUE;
243         return S_OK;
244     }
245
246     if(MessageBoxW(This->doc->hwnd, message, wszTitle,
247                 MB_OKCANCEL|MB_ICONQUESTION)==IDOK)
248         *confirmed = VARIANT_TRUE;
249     else *confirmed = VARIANT_FALSE;
250
251     return S_OK;
252 }
253
254 typedef struct
255 {
256     BSTR message;
257     BSTR dststr;
258     VARIANT *textdata;
259 }prompt_arg;
260
261 static INT_PTR CALLBACK prompt_dlgproc(HWND hwnd, UINT msg,
262         WPARAM wparam, LPARAM lparam)
263 {
264     switch(msg)
265     {
266         case WM_INITDIALOG:
267         {
268             prompt_arg *arg = (prompt_arg*)lparam;
269             WCHAR wszTitle[100];
270
271             if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
272                         sizeof(wszTitle)/sizeof(WCHAR))) {
273                 WARN("Could not load message box title: %d\n", GetLastError());
274                 EndDialog(hwnd, wparam);
275                 return FALSE;
276             }
277
278             SetWindowLongPtrW(hwnd, DWLP_USER, lparam);
279             SetWindowTextW(hwnd, wszTitle);
280             SetWindowTextW(GetDlgItem(hwnd, ID_PROMPT_PROMPT), arg->message);
281             SetWindowTextW(GetDlgItem(hwnd, ID_PROMPT_EDIT), arg->dststr);
282             return FALSE;
283         }
284         case WM_COMMAND:
285             switch(wparam)
286             {
287                 case MAKEWPARAM(IDCANCEL, BN_CLICKED):
288                     EndDialog(hwnd, wparam);
289                     return TRUE;
290                 case MAKEWPARAM(IDOK, BN_CLICKED):
291                 {
292                     prompt_arg *arg =
293                         (prompt_arg*)GetWindowLongPtrW(hwnd, DWLP_USER);
294                     HWND hwndPrompt = GetDlgItem(hwnd, ID_PROMPT_EDIT);
295                     INT len = GetWindowTextLengthW(hwndPrompt);
296
297                     if(!arg->textdata)
298                     {
299                         EndDialog(hwnd, wparam);
300                         return TRUE;
301                     }
302
303                     V_VT(arg->textdata) = VT_BSTR;
304                     if(!len && !arg->dststr)
305                         V_BSTR(arg->textdata) = NULL;
306                     else
307                     {
308                         V_BSTR(arg->textdata) = SysAllocStringLen(NULL, len);
309                         GetWindowTextW(hwndPrompt, V_BSTR(arg->textdata), len+1);
310                     }
311                     EndDialog(hwnd, wparam);
312                     return TRUE;
313                 }
314             }
315             return FALSE;
316         case WM_CLOSE:
317             EndDialog(hwnd, IDCANCEL);
318             return TRUE;
319         default:
320             return FALSE;
321     }
322 }
323
324 static HRESULT WINAPI HTMLWindow2_prompt(IHTMLWindow2 *iface, BSTR message,
325         BSTR dststr, VARIANT *textdata)
326 {
327     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
328     prompt_arg arg;
329
330     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(message), debugstr_w(dststr), textdata);
331
332     if(textdata) V_VT(textdata) = VT_NULL;
333
334     arg.message = message;
335     arg.dststr = dststr;
336     arg.textdata = textdata;
337
338     DialogBoxParamW(hInst, MAKEINTRESOURCEW(ID_PROMPT_DIALOG),
339             This->doc->hwnd, prompt_dlgproc, (LPARAM)&arg);
340     return S_OK;
341 }
342
343 static HRESULT WINAPI HTMLWindow2_get_Image(IHTMLWindow2 *iface, IHTMLImageElementFactory **p)
344 {
345     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
346     FIXME("(%p)->(%p)\n", This, p);
347     return E_NOTIMPL;
348 }
349
350 static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocation **p)
351 {
352     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
353
354     TRACE("(%p)->(%p)\n", This, p);
355
356     if(!This->doc) {
357         FIXME("This->doc is NULL\n");
358         return E_FAIL;
359     }
360
361     return IHTMLDocument2_get_location(HTMLDOC(This->doc), p);
362 }
363
364 static HRESULT WINAPI HTMLWindow2_get_history(IHTMLWindow2 *iface, IOmHistory **p)
365 {
366     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
367     FIXME("(%p)->(%p)\n", This, p);
368     return E_NOTIMPL;
369 }
370
371 static HRESULT WINAPI HTMLWindow2_close(IHTMLWindow2 *iface)
372 {
373     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
374     FIXME("(%p)->()\n", This);
375     return E_NOTIMPL;
376 }
377
378 static HRESULT WINAPI HTMLWindow2_put_opener(IHTMLWindow2 *iface, VARIANT v)
379 {
380     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
381     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
382     return E_NOTIMPL;
383 }
384
385 static HRESULT WINAPI HTMLWindow2_get_opener(IHTMLWindow2 *iface, VARIANT *p)
386 {
387     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
388     FIXME("(%p)->(%p)\n", This, p);
389     return E_NOTIMPL;
390 }
391
392 static HRESULT WINAPI HTMLWindow2_get_navigator(IHTMLWindow2 *iface, IOmNavigator **p)
393 {
394     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
395
396     TRACE("(%p)->(%p)\n", This, p);
397
398     *p = OmNavigator_Create();
399     return S_OK;
400 }
401
402 static HRESULT WINAPI HTMLWindow2_put_name(IHTMLWindow2 *iface, BSTR v)
403 {
404     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
405     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
406     return E_NOTIMPL;
407 }
408
409 static HRESULT WINAPI HTMLWindow2_get_name(IHTMLWindow2 *iface, BSTR *p)
410 {
411     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
412     FIXME("(%p)->(%p)\n", This, p);
413     return E_NOTIMPL;
414 }
415
416 static HRESULT WINAPI HTMLWindow2_get_parent(IHTMLWindow2 *iface, IHTMLWindow2 **p)
417 {
418     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
419     FIXME("(%p)->(%p)\n", This, p);
420     return E_NOTIMPL;
421 }
422
423 static HRESULT WINAPI HTMLWindow2_open(IHTMLWindow2 *iface, BSTR url, BSTR name,
424          BSTR features, VARIANT_BOOL replace, IHTMLWindow2 **pomWindowResult)
425 {
426     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
427     FIXME("(%p)->(%s %s %s %x %p)\n", This, debugstr_w(url), debugstr_w(name),
428           debugstr_w(features), replace, pomWindowResult);
429     return E_NOTIMPL;
430 }
431
432 static HRESULT WINAPI HTMLWindow2_get_self(IHTMLWindow2 *iface, IHTMLWindow2 **p)
433 {
434     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
435
436     TRACE("(%p)->(%p)\n", This, p);
437
438     /* FIXME: We should return kind of proxy window here. */
439     IHTMLWindow2_AddRef(HTMLWINDOW2(This));
440     *p = HTMLWINDOW2(This);
441     return S_OK;
442 }
443
444 static HRESULT WINAPI HTMLWindow2_get_top(IHTMLWindow2 *iface, IHTMLWindow2 **p)
445 {
446     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
447     FIXME("(%p)->(%p)\n", This, p);
448     return E_NOTIMPL;
449 }
450
451 static HRESULT WINAPI HTMLWindow2_get_window(IHTMLWindow2 *iface, IHTMLWindow2 **p)
452 {
453     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
454
455     TRACE("(%p)->(%p)\n", This, p);
456
457     /* FIXME: We should return kind of proxy window here. */
458     IHTMLWindow2_AddRef(HTMLWINDOW2(This));
459     *p = HTMLWINDOW2(This);
460     return S_OK;
461 }
462
463 static HRESULT WINAPI HTMLWindow2_navigate(IHTMLWindow2 *iface, BSTR url)
464 {
465     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
466     FIXME("(%p)->(%s)\n", This, debugstr_w(url));
467     return E_NOTIMPL;
468 }
469
470 static HRESULT WINAPI HTMLWindow2_put_onfocus(IHTMLWindow2 *iface, VARIANT v)
471 {
472     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
473     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
474     return E_NOTIMPL;
475 }
476
477 static HRESULT WINAPI HTMLWindow2_get_onfocus(IHTMLWindow2 *iface, VARIANT *p)
478 {
479     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
480     FIXME("(%p)->(%p)\n", This, p);
481     return E_NOTIMPL;
482 }
483
484 static HRESULT WINAPI HTMLWindow2_put_onblur(IHTMLWindow2 *iface, VARIANT v)
485 {
486     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
487     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
488     return E_NOTIMPL;
489 }
490
491 static HRESULT WINAPI HTMLWindow2_get_onblur(IHTMLWindow2 *iface, VARIANT *p)
492 {
493     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
494     FIXME("(%p)->(%p)\n", This, p);
495     return E_NOTIMPL;
496 }
497
498 static HRESULT WINAPI HTMLWindow2_put_onload(IHTMLWindow2 *iface, VARIANT v)
499 {
500     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
501
502     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
503
504     return set_window_event(This, EVENTID_LOAD, &v);
505 }
506
507 static HRESULT WINAPI HTMLWindow2_get_onload(IHTMLWindow2 *iface, VARIANT *p)
508 {
509     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
510
511     TRACE("(%p)->(%p)\n", This, p);
512
513     return get_window_event(This, EVENTID_LOAD, p);
514 }
515
516 static HRESULT WINAPI HTMLWindow2_put_onbeforeunload(IHTMLWindow2 *iface, VARIANT v)
517 {
518     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
519
520     TRACE("(%p)->(v(%d))\n", This, V_VT(&v));
521
522     return set_window_event(This, EVENTID_BEFOREUNLOAD, &v);
523 }
524
525 static HRESULT WINAPI HTMLWindow2_get_onbeforeunload(IHTMLWindow2 *iface, VARIANT *p)
526 {
527     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
528
529     TRACE("(%p)->(%p)\n", This, p);
530
531     return get_window_event(This, EVENTID_BEFOREUNLOAD, p);
532 }
533
534 static HRESULT WINAPI HTMLWindow2_put_onunload(IHTMLWindow2 *iface, VARIANT v)
535 {
536     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
537     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
538     return E_NOTIMPL;
539 }
540
541 static HRESULT WINAPI HTMLWindow2_get_onunload(IHTMLWindow2 *iface, VARIANT *p)
542 {
543     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
544     FIXME("(%p)->(%p)\n", This, p);
545     return E_NOTIMPL;
546 }
547
548 static HRESULT WINAPI HTMLWindow2_put_onhelp(IHTMLWindow2 *iface, VARIANT v)
549 {
550     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
551     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
552     return E_NOTIMPL;
553 }
554
555 static HRESULT WINAPI HTMLWindow2_get_onhelp(IHTMLWindow2 *iface, VARIANT *p)
556 {
557     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
558     FIXME("(%p)->(%p)\n", This, p);
559     return E_NOTIMPL;
560 }
561
562 static HRESULT WINAPI HTMLWindow2_put_onerror(IHTMLWindow2 *iface, VARIANT v)
563 {
564     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
565     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
566     return E_NOTIMPL;
567 }
568
569 static HRESULT WINAPI HTMLWindow2_get_onerror(IHTMLWindow2 *iface, VARIANT *p)
570 {
571     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
572     FIXME("(%p)->(%p)\n", This, p);
573     return E_NOTIMPL;
574 }
575
576 static HRESULT WINAPI HTMLWindow2_put_onresize(IHTMLWindow2 *iface, VARIANT v)
577 {
578     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
579     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
580     return E_NOTIMPL;
581 }
582
583 static HRESULT WINAPI HTMLWindow2_get_onresize(IHTMLWindow2 *iface, VARIANT *p)
584 {
585     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
586     FIXME("(%p)->(%p)\n", This, p);
587     return E_NOTIMPL;
588 }
589
590 static HRESULT WINAPI HTMLWindow2_put_onscroll(IHTMLWindow2 *iface, VARIANT v)
591 {
592     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
593     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
594     return E_NOTIMPL;
595 }
596
597 static HRESULT WINAPI HTMLWindow2_get_onscroll(IHTMLWindow2 *iface, VARIANT *p)
598 {
599     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
600     FIXME("(%p)->(%p)\n", This, p);
601     return E_NOTIMPL;
602 }
603
604 static HRESULT WINAPI HTMLWindow2_get_document(IHTMLWindow2 *iface, IHTMLDocument2 **p)
605 {
606     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
607
608     TRACE("(%p)->(%p)\n", This, p);
609
610     if(This->doc) {
611         /* FIXME: We should return a wrapper object here */
612         *p = HTMLDOC(This->doc);
613         IHTMLDocument2_AddRef(*p);
614     }else {
615         *p = NULL;
616     }
617
618     return S_OK;
619 }
620
621 static HRESULT WINAPI HTMLWindow2_get_event(IHTMLWindow2 *iface, IHTMLEventObj **p)
622 {
623     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
624
625     TRACE("(%p)->(%p)\n", This, p);
626
627     if(This->event)
628         IHTMLEventObj_AddRef(This->event);
629     *p = This->event;
630     return S_OK;
631 }
632
633 static HRESULT WINAPI HTMLWindow2_get__newEnum(IHTMLWindow2 *iface, IUnknown **p)
634 {
635     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
636     FIXME("(%p)->(%p)\n", This, p);
637     return E_NOTIMPL;
638 }
639
640 static HRESULT WINAPI HTMLWindow2_showModalDialog(IHTMLWindow2 *iface, BSTR dialog,
641         VARIANT *varArgIn, VARIANT *varOptions, VARIANT *varArgOut)
642 {
643     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
644     FIXME("(%p)->(%s %p %p %p)\n", This, debugstr_w(dialog), varArgIn, varOptions, varArgOut);
645     return E_NOTIMPL;
646 }
647
648 static HRESULT WINAPI HTMLWindow2_showHelp(IHTMLWindow2 *iface, BSTR helpURL, VARIANT helpArg,
649         BSTR features)
650 {
651     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
652     FIXME("(%p)->(%s v(%d) %s)\n", This, debugstr_w(helpURL), V_VT(&helpArg), debugstr_w(features));
653     return E_NOTIMPL;
654 }
655
656 static HRESULT WINAPI HTMLWindow2_get_screen(IHTMLWindow2 *iface, IHTMLScreen **p)
657 {
658     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
659     FIXME("(%p)->(%p)\n", This, p);
660     return E_NOTIMPL;
661 }
662
663 static HRESULT WINAPI HTMLWindow2_get_Option(IHTMLWindow2 *iface, IHTMLOptionElementFactory **p)
664 {
665     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
666
667     TRACE("(%p)->(%p)\n", This, p);
668
669     if(!This->doc->option_factory)
670         This->doc->option_factory = HTMLOptionElementFactory_Create(This->doc);
671
672     *p = HTMLOPTFACTORY(This->doc->option_factory);
673     IHTMLOptionElementFactory_AddRef(*p);
674
675     return S_OK;
676 }
677
678 static HRESULT WINAPI HTMLWindow2_focus(IHTMLWindow2 *iface)
679 {
680     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
681     FIXME("(%p)->()\n", This);
682     return E_NOTIMPL;
683 }
684
685 static HRESULT WINAPI HTMLWindow2_get_closed(IHTMLWindow2 *iface, VARIANT_BOOL *p)
686 {
687     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
688     FIXME("(%p)->(%p)\n", This, p);
689     return E_NOTIMPL;
690 }
691
692 static HRESULT WINAPI HTMLWindow2_blur(IHTMLWindow2 *iface)
693 {
694     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
695     FIXME("(%p)->()\n", This);
696     return E_NOTIMPL;
697 }
698
699 static HRESULT WINAPI HTMLWindow2_scroll(IHTMLWindow2 *iface, LONG x, LONG y)
700 {
701     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
702     FIXME("(%p)->(%d %d)\n", This, x, y);
703     return E_NOTIMPL;
704 }
705
706 static HRESULT WINAPI HTMLWindow2_get_clientInformation(IHTMLWindow2 *iface, IOmNavigator **p)
707 {
708     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
709     FIXME("(%p)->(%p)\n", This, p);
710     return E_NOTIMPL;
711 }
712
713 static HRESULT WINAPI HTMLWindow2_setInterval(IHTMLWindow2 *iface, BSTR expression,
714         LONG msec, VARIANT *language, LONG *timerID)
715 {
716     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
717     VARIANT expr;
718
719     TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(expression), msec, language, timerID);
720
721     V_VT(&expr) = VT_BSTR;
722     V_BSTR(&expr) = expression;
723     return IHTMLWindow3_setInterval(HTMLWINDOW3(This), &expr, msec, language, timerID);
724 }
725
726 static HRESULT WINAPI HTMLWindow2_clearInterval(IHTMLWindow2 *iface, LONG timerID)
727 {
728     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
729
730     TRACE("(%p)->(%d)\n", This, timerID);
731
732     return clear_task_timer(This->doc, TRUE, timerID);
733 }
734
735 static HRESULT WINAPI HTMLWindow2_put_offscreenBuffering(IHTMLWindow2 *iface, VARIANT v)
736 {
737     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
738     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
739     return E_NOTIMPL;
740 }
741
742 static HRESULT WINAPI HTMLWindow2_get_offscreenBuffering(IHTMLWindow2 *iface, VARIANT *p)
743 {
744     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
745     FIXME("(%p)->(%p)\n", This, p);
746     return E_NOTIMPL;
747 }
748
749 static HRESULT WINAPI HTMLWindow2_execScript(IHTMLWindow2 *iface, BSTR scode, BSTR language,
750         VARIANT *pvarRet)
751 {
752     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
753     FIXME("(%p)->(%s %s %p)\n", This, debugstr_w(scode), debugstr_w(language), pvarRet);
754     return E_NOTIMPL;
755 }
756
757 static HRESULT WINAPI HTMLWindow2_toString(IHTMLWindow2 *iface, BSTR *String)
758 {
759     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
760
761     static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
762
763     TRACE("(%p)->(%p)\n", This, String);
764
765     if(!String)
766         return E_INVALIDARG;
767
768     *String = SysAllocString(objectW);
769     return *String ? S_OK : E_OUTOFMEMORY;
770 }
771
772 static HRESULT WINAPI HTMLWindow2_scrollBy(IHTMLWindow2 *iface, LONG x, LONG y)
773 {
774     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
775     nsresult nsres;
776
777     TRACE("(%p)->(%d %d)\n", This, x, y);
778
779     nsres = nsIDOMWindow_ScrollBy(This->nswindow, x, y);
780     if(NS_FAILED(nsres))
781         ERR("ScrollBy failed: %08x\n", nsres);
782
783     return S_OK;
784 }
785
786 static HRESULT WINAPI HTMLWindow2_scrollTo(IHTMLWindow2 *iface, LONG x, LONG y)
787 {
788     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
789     nsresult nsres;
790
791     TRACE("(%p)->(%d %d)\n", This, x, y);
792
793     nsres = nsIDOMWindow_ScrollTo(This->nswindow, x, y);
794     if(NS_FAILED(nsres))
795         ERR("ScrollTo failed: %08x\n", nsres);
796
797     return S_OK;
798 }
799
800 static HRESULT WINAPI HTMLWindow2_moveTo(IHTMLWindow2 *iface, LONG x, LONG y)
801 {
802     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
803     FIXME("(%p)->(%d %d)\n", This, x, y);
804     return E_NOTIMPL;
805 }
806
807 static HRESULT WINAPI HTMLWindow2_moveBy(IHTMLWindow2 *iface, LONG x, LONG y)
808 {
809     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
810     FIXME("(%p)->(%d %d)\n", This, x, y);
811     return E_NOTIMPL;
812 }
813
814 static HRESULT WINAPI HTMLWindow2_resizeTo(IHTMLWindow2 *iface, LONG x, LONG y)
815 {
816     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
817     FIXME("(%p)->(%d %d)\n", This, x, y);
818     return E_NOTIMPL;
819 }
820
821 static HRESULT WINAPI HTMLWindow2_resizeBy(IHTMLWindow2 *iface, LONG x, LONG y)
822 {
823     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
824     FIXME("(%p)->(%d %d)\n", This, x, y);
825     return E_NOTIMPL;
826 }
827
828 static HRESULT WINAPI HTMLWindow2_get_external(IHTMLWindow2 *iface, IDispatch **p)
829 {
830     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
831
832     TRACE("(%p)->(%p)\n", This, p);
833
834     *p = NULL;
835
836     if(!This->doc->hostui)
837         return S_OK;
838
839     return IDocHostUIHandler_GetExternal(This->doc->hostui, p);
840 }
841
842 #undef HTMLWINDOW2_THIS
843
844 static const IHTMLWindow2Vtbl HTMLWindow2Vtbl = {
845     HTMLWindow2_QueryInterface,
846     HTMLWindow2_AddRef,
847     HTMLWindow2_Release,
848     HTMLWindow2_GetTypeInfoCount,
849     HTMLWindow2_GetTypeInfo,
850     HTMLWindow2_GetIDsOfNames,
851     HTMLWindow2_Invoke,
852     HTMLWindow2_item,
853     HTMLWindow2_get_length,
854     HTMLWindow2_get_frames,
855     HTMLWindow2_put_defaultStatus,
856     HTMLWindow2_get_defaultStatus,
857     HTMLWindow2_put_status,
858     HTMLWindow2_get_status,
859     HTMLWindow2_setTimeout,
860     HTMLWindow2_clearTimeout,
861     HTMLWindow2_alert,
862     HTMLWindow2_confirm,
863     HTMLWindow2_prompt,
864     HTMLWindow2_get_Image,
865     HTMLWindow2_get_location,
866     HTMLWindow2_get_history,
867     HTMLWindow2_close,
868     HTMLWindow2_put_opener,
869     HTMLWindow2_get_opener,
870     HTMLWindow2_get_navigator,
871     HTMLWindow2_put_name,
872     HTMLWindow2_get_name,
873     HTMLWindow2_get_parent,
874     HTMLWindow2_open,
875     HTMLWindow2_get_self,
876     HTMLWindow2_get_top,
877     HTMLWindow2_get_window,
878     HTMLWindow2_navigate,
879     HTMLWindow2_put_onfocus,
880     HTMLWindow2_get_onfocus,
881     HTMLWindow2_put_onblur,
882     HTMLWindow2_get_onblur,
883     HTMLWindow2_put_onload,
884     HTMLWindow2_get_onload,
885     HTMLWindow2_put_onbeforeunload,
886     HTMLWindow2_get_onbeforeunload,
887     HTMLWindow2_put_onunload,
888     HTMLWindow2_get_onunload,
889     HTMLWindow2_put_onhelp,
890     HTMLWindow2_get_onhelp,
891     HTMLWindow2_put_onerror,
892     HTMLWindow2_get_onerror,
893     HTMLWindow2_put_onresize,
894     HTMLWindow2_get_onresize,
895     HTMLWindow2_put_onscroll,
896     HTMLWindow2_get_onscroll,
897     HTMLWindow2_get_document,
898     HTMLWindow2_get_event,
899     HTMLWindow2_get__newEnum,
900     HTMLWindow2_showModalDialog,
901     HTMLWindow2_showHelp,
902     HTMLWindow2_get_screen,
903     HTMLWindow2_get_Option,
904     HTMLWindow2_focus,
905     HTMLWindow2_get_closed,
906     HTMLWindow2_blur,
907     HTMLWindow2_scroll,
908     HTMLWindow2_get_clientInformation,
909     HTMLWindow2_setInterval,
910     HTMLWindow2_clearInterval,
911     HTMLWindow2_put_offscreenBuffering,
912     HTMLWindow2_get_offscreenBuffering,
913     HTMLWindow2_execScript,
914     HTMLWindow2_toString,
915     HTMLWindow2_scrollBy,
916     HTMLWindow2_scrollTo,
917     HTMLWindow2_moveTo,
918     HTMLWindow2_moveBy,
919     HTMLWindow2_resizeTo,
920     HTMLWindow2_resizeBy,
921     HTMLWindow2_get_external
922 };
923
924 #define HTMLWINDOW3_THIS(iface) DEFINE_THIS(HTMLWindow, HTMLWindow3, iface)
925
926 static HRESULT WINAPI HTMLWindow3_QueryInterface(IHTMLWindow3 *iface, REFIID riid, void **ppv)
927 {
928     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
929
930     return IHTMLWindow2_QueryInterface(HTMLWINDOW2(This), riid, ppv);
931 }
932
933 static ULONG WINAPI HTMLWindow3_AddRef(IHTMLWindow3 *iface)
934 {
935     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
936
937     return IHTMLWindow2_AddRef(HTMLWINDOW2(This));
938 }
939
940 static ULONG WINAPI HTMLWindow3_Release(IHTMLWindow3 *iface)
941 {
942     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
943
944     return IHTMLWindow2_Release(HTMLWINDOW2(This));
945 }
946
947 static HRESULT WINAPI HTMLWindow3_GetTypeInfoCount(IHTMLWindow3 *iface, UINT *pctinfo)
948 {
949     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
950
951     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo);
952 }
953
954 static HRESULT WINAPI HTMLWindow3_GetTypeInfo(IHTMLWindow3 *iface, UINT iTInfo,
955                                               LCID lcid, ITypeInfo **ppTInfo)
956 {
957     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
958
959     return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo);
960 }
961
962 static HRESULT WINAPI HTMLWindow3_GetIDsOfNames(IHTMLWindow3 *iface, REFIID riid,
963                                                 LPOLESTR *rgszNames, UINT cNames,
964                                                 LCID lcid, DISPID *rgDispId)
965 {
966     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
967
968     return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId);
969 }
970
971 static HRESULT WINAPI HTMLWindow3_Invoke(IHTMLWindow3 *iface, DISPID dispIdMember,
972                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
973                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
974 {
975     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
976
977     return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams,
978             pVarResult, pExcepInfo, puArgErr);
979 }
980
981 static HRESULT WINAPI HTMLWindow3_get_screenLeft(IHTMLWindow3 *iface, LONG *p)
982 {
983     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
984     FIXME("(%p)->(%p)\n", This, p);
985     return E_NOTIMPL;
986 }
987
988 static HRESULT WINAPI HTMLWindow3_get_screenTop(IHTMLWindow3 *iface, LONG *p)
989 {
990     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
991     FIXME("(%p)->(%p)\n", This, p);
992     return E_NOTIMPL;
993 }
994
995 static HRESULT WINAPI HTMLWindow3_attachEvent(IHTMLWindow3 *iface, BSTR event, IDispatch *pDisp, VARIANT_BOOL *pfResult)
996 {
997     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
998
999     TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(event), pDisp, pfResult);
1000
1001     return attach_event(&This->event_target, This->doc, event, pDisp, pfResult);
1002 }
1003
1004 static HRESULT WINAPI HTMLWindow3_detachEvent(IHTMLWindow3 *iface, BSTR event, IDispatch *pDisp)
1005 {
1006     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1007     FIXME("(%p)->()\n", This);
1008     return E_NOTIMPL;
1009 }
1010
1011 static HRESULT window_set_timer(HTMLWindow *This, VARIANT *expr, LONG msec, VARIANT *language,
1012         BOOL interval, LONG *timer_id)
1013 {
1014     IDispatch *disp = NULL;
1015
1016     switch(V_VT(expr)) {
1017     case VT_DISPATCH:
1018         disp = V_DISPATCH(expr);
1019         IDispatch_AddRef(disp);
1020         break;
1021
1022     case VT_BSTR:
1023         disp = script_parse_event(This->doc, V_BSTR(expr));
1024         break;
1025
1026     default:
1027         FIXME("unimplemented vt=%d\n", V_VT(expr));
1028         return E_NOTIMPL;
1029     }
1030
1031     if(!disp)
1032         return E_FAIL;
1033
1034     *timer_id = set_task_timer(This->doc, msec, interval, disp);
1035     IDispatch_Release(disp);
1036
1037     return S_OK;
1038 }
1039
1040 static HRESULT WINAPI HTMLWindow3_setTimeout(IHTMLWindow3 *iface, VARIANT *expression, LONG msec,
1041         VARIANT *language, LONG *timerID)
1042 {
1043     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1044
1045     TRACE("(%p)->(%p(%d) %d %p %p)\n", This, expression, V_VT(expression), msec, language, timerID);
1046
1047     return window_set_timer(This, expression, msec, language, FALSE, timerID);
1048 }
1049
1050 static HRESULT WINAPI HTMLWindow3_setInterval(IHTMLWindow3 *iface, VARIANT *expression, LONG msec,
1051         VARIANT *language, LONG *timerID)
1052 {
1053     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1054
1055     TRACE("(%p)->(%p %d %p %p)\n", This, expression, msec, language, timerID);
1056
1057     return window_set_timer(This, expression, msec, language, TRUE, timerID);
1058 }
1059
1060 static HRESULT WINAPI HTMLWindow3_print(IHTMLWindow3 *iface)
1061 {
1062     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1063     FIXME("(%p)\n", This);
1064     return E_NOTIMPL;
1065 }
1066
1067 static HRESULT WINAPI HTMLWindow3_put_onbeforeprint(IHTMLWindow3 *iface, VARIANT v)
1068 {
1069     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1070     FIXME("(%p)->()\n", This);
1071     return E_NOTIMPL;
1072 }
1073
1074 static HRESULT WINAPI HTMLWindow3_get_onbeforeprint(IHTMLWindow3 *iface, VARIANT *p)
1075 {
1076     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1077     FIXME("(%p)->(%p)\n", This, p);
1078     return E_NOTIMPL;
1079 }
1080
1081 static HRESULT WINAPI HTMLWindow3_put_onafterprint(IHTMLWindow3 *iface, VARIANT v)
1082 {
1083     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1084     FIXME("(%p)->()\n", This);
1085     return E_NOTIMPL;
1086 }
1087
1088 static HRESULT WINAPI HTMLWindow3_get_onafterprint(IHTMLWindow3 *iface, VARIANT *p)
1089 {
1090     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1091     FIXME("(%p)->(%p)\n", This, p);
1092     return E_NOTIMPL;
1093 }
1094
1095 static HRESULT WINAPI HTMLWindow3_get_clipboardData(IHTMLWindow3 *iface, IHTMLDataTransfer **p)
1096 {
1097     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1098     FIXME("(%p)->(%p)\n", This, p);
1099     return E_NOTIMPL;
1100 }
1101
1102 static HRESULT WINAPI HTMLWindow3_showModelessDialog(IHTMLWindow3 *iface, BSTR url,
1103         VARIANT *varArgIn, VARIANT *options, IHTMLWindow2 **pDialog)
1104 {
1105     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1106     FIXME("(%p)->(%s %p %p %p)\n", This, debugstr_w(url), varArgIn, options, pDialog);
1107     return E_NOTIMPL;
1108 }
1109
1110 #undef HTMLWINDOW3_THIS
1111
1112 static const IHTMLWindow3Vtbl HTMLWindow3Vtbl = {
1113     HTMLWindow3_QueryInterface,
1114     HTMLWindow3_AddRef,
1115     HTMLWindow3_Release,
1116     HTMLWindow3_GetTypeInfoCount,
1117     HTMLWindow3_GetTypeInfo,
1118     HTMLWindow3_GetIDsOfNames,
1119     HTMLWindow3_Invoke,
1120     HTMLWindow3_get_screenLeft,
1121     HTMLWindow3_get_screenTop,
1122     HTMLWindow3_attachEvent,
1123     HTMLWindow3_detachEvent,
1124     HTMLWindow3_setTimeout,
1125     HTMLWindow3_setInterval,
1126     HTMLWindow3_print,
1127     HTMLWindow3_put_onbeforeprint,
1128     HTMLWindow3_get_onbeforeprint,
1129     HTMLWindow3_put_onafterprint,
1130     HTMLWindow3_get_onafterprint,
1131     HTMLWindow3_get_clipboardData,
1132     HTMLWindow3_showModelessDialog
1133 };
1134
1135 #define DISPEX_THIS(iface) DEFINE_THIS(HTMLWindow, IDispatchEx, iface)
1136
1137 static HRESULT WINAPI WindowDispEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
1138 {
1139     HTMLWindow *This = DISPEX_THIS(iface);
1140
1141     return IHTMLWindow2_QueryInterface(HTMLWINDOW2(This), riid, ppv);
1142 }
1143
1144 static ULONG WINAPI WindowDispEx_AddRef(IDispatchEx *iface)
1145 {
1146     HTMLWindow *This = DISPEX_THIS(iface);
1147
1148     return IHTMLWindow2_AddRef(HTMLWINDOW2(This));
1149 }
1150
1151 static ULONG WINAPI WindowDispEx_Release(IDispatchEx *iface)
1152 {
1153     HTMLWindow *This = DISPEX_THIS(iface);
1154
1155     return IHTMLWindow2_Release(HTMLWINDOW2(This));
1156 }
1157
1158 static HRESULT WINAPI WindowDispEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
1159 {
1160     HTMLWindow *This = DISPEX_THIS(iface);
1161
1162     TRACE("(%p)->(%p)\n", This, pctinfo);
1163
1164     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo);
1165 }
1166
1167 static HRESULT WINAPI WindowDispEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
1168                                                LCID lcid, ITypeInfo **ppTInfo)
1169 {
1170     HTMLWindow *This = DISPEX_THIS(iface);
1171
1172     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1173
1174     return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo);
1175 }
1176
1177 static HRESULT WINAPI WindowDispEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
1178                                                  LPOLESTR *rgszNames, UINT cNames,
1179                                                  LCID lcid, DISPID *rgDispId)
1180 {
1181     HTMLWindow *This = DISPEX_THIS(iface);
1182
1183     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1184           lcid, rgDispId);
1185
1186     /* FIXME: Use script dispatch */
1187
1188     return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId);
1189 }
1190
1191 static HRESULT WINAPI WindowDispEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
1192                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1193                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1194 {
1195     HTMLWindow *This = DISPEX_THIS(iface);
1196
1197     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1198           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1199
1200     /* FIXME: Use script dispatch */
1201
1202     return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, wFlags, pDispParams,
1203                               pVarResult, pExcepInfo, puArgErr);
1204 }
1205
1206 static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
1207 {
1208     HTMLWindow *This = DISPEX_THIS(iface);
1209
1210     TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
1211
1212     return IDispatchEx_GetDispID(DISPATCHEX(&This->dispex), bstrName, grfdex, pid);
1213 }
1214
1215 static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1216         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1217 {
1218     HTMLWindow *This = DISPEX_THIS(iface);
1219
1220     TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1221
1222     return IDispatchEx_InvokeEx(DISPATCHEX(&This->dispex), id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1223 }
1224
1225 static HRESULT WINAPI WindowDispEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
1226 {
1227     HTMLWindow *This = DISPEX_THIS(iface);
1228
1229     TRACE("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex);
1230
1231     return IDispatchEx_DeleteMemberByName(DISPATCHEX(&This->dispex), bstrName, grfdex);
1232 }
1233
1234 static HRESULT WINAPI WindowDispEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
1235 {
1236     HTMLWindow *This = DISPEX_THIS(iface);
1237
1238     TRACE("(%p)->(%x)\n", This, id);
1239
1240     return IDispatchEx_DeleteMemberByDispID(DISPATCHEX(&This->dispex), id);
1241 }
1242
1243 static HRESULT WINAPI WindowDispEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
1244 {
1245     HTMLWindow *This = DISPEX_THIS(iface);
1246
1247     TRACE("(%p)->(%x %x %p)\n", This, id, grfdexFetch, pgrfdex);
1248
1249     return IDispatchEx_GetMemberProperties(DISPATCHEX(&This->dispex), id, grfdexFetch, pgrfdex);
1250 }
1251
1252 static HRESULT WINAPI WindowDispEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
1253 {
1254     HTMLWindow *This = DISPEX_THIS(iface);
1255
1256     TRACE("(%p)->(%x %p)\n", This, id, pbstrName);
1257
1258     return IDispatchEx_GetMemberName(DISPATCHEX(&This->dispex), id, pbstrName);
1259 }
1260
1261 static HRESULT WINAPI WindowDispEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
1262 {
1263     HTMLWindow *This = DISPEX_THIS(iface);
1264
1265     TRACE("(%p)->(%x %x %p)\n", This, grfdex, id, pid);
1266
1267     return IDispatchEx_GetNextDispID(DISPATCHEX(&This->dispex), grfdex, id, pid);
1268 }
1269
1270 static HRESULT WINAPI WindowDispEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
1271 {
1272     HTMLWindow *This = DISPEX_THIS(iface);
1273
1274     TRACE("(%p)->(%p)\n", This, ppunk);
1275
1276     *ppunk = NULL;
1277     return S_OK;
1278 }
1279
1280 #undef DISPEX_THIS
1281
1282 static const IDispatchExVtbl WindowDispExVtbl = {
1283     WindowDispEx_QueryInterface,
1284     WindowDispEx_AddRef,
1285     WindowDispEx_Release,
1286     WindowDispEx_GetTypeInfoCount,
1287     WindowDispEx_GetTypeInfo,
1288     WindowDispEx_GetIDsOfNames,
1289     WindowDispEx_Invoke,
1290     WindowDispEx_GetDispID,
1291     WindowDispEx_InvokeEx,
1292     WindowDispEx_DeleteMemberByName,
1293     WindowDispEx_DeleteMemberByDispID,
1294     WindowDispEx_GetMemberProperties,
1295     WindowDispEx_GetMemberName,
1296     WindowDispEx_GetNextDispID,
1297     WindowDispEx_GetNameSpaceParent
1298 };
1299
1300 static const tid_t HTMLWindow_iface_tids[] = {
1301     IHTMLWindow2_tid,
1302     IHTMLWindow3_tid,
1303     0
1304 };
1305 static dispex_static_data_t HTMLWindow_dispex = {
1306     NULL,
1307     DispHTMLWindow2_tid,
1308     NULL,
1309     HTMLWindow_iface_tids
1310 };
1311
1312 HRESULT HTMLWindow_Create(HTMLDocument *doc, nsIDOMWindow *nswindow, HTMLWindow **ret)
1313 {
1314     HTMLWindow *window;
1315
1316     window = heap_alloc_zero(sizeof(HTMLWindow));
1317     if(!window)
1318         return E_OUTOFMEMORY;
1319
1320     window->lpHTMLWindow2Vtbl = &HTMLWindow2Vtbl;
1321     window->lpHTMLWindow3Vtbl = &HTMLWindow3Vtbl;
1322     window->lpIDispatchExVtbl = &WindowDispExVtbl;
1323     window->ref = 1;
1324     window->doc = doc;
1325
1326     init_dispex(&window->dispex, (IUnknown*)HTMLWINDOW2(window), &HTMLWindow_dispex);
1327
1328     if(nswindow) {
1329         nsIDOMWindow_AddRef(nswindow);
1330         window->nswindow = nswindow;
1331     }
1332
1333     list_add_head(&window_list, &window->entry);
1334
1335     *ret = window;
1336     return S_OK;
1337 }
1338
1339 HTMLWindow *nswindow_to_window(const nsIDOMWindow *nswindow)
1340 {
1341     HTMLWindow *iter;
1342
1343     LIST_FOR_EACH_ENTRY(iter, &window_list, HTMLWindow, entry) {
1344         if(iter->nswindow == nswindow)
1345             return iter;
1346     }
1347
1348     return NULL;
1349 }