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