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