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