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