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