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