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