mshtml: Added IHTMLPrivateWindow stub implementation.
[wine] / dlls / mshtml / htmlwindow.c
1 /*
2  * Copyright 2006 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include <stdarg.h>
20
21 #define COBJMACROS
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "ole2.h"
27 #include "mshtmdid.h"
28
29 #include "wine/debug.h"
30
31 #include "mshtml_private.h"
32 #include "htmlevent.h"
33 #include "resource.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
36
37 #define HTMLPRIVWINDOW(x)  ((IHTMLPrivateWindow*)  &(x)->lpIHTMLPrivateWindowVtbl)
38
39 static struct list window_list = LIST_INIT(window_list);
40
41 static void window_set_docnode(HTMLWindow *window, HTMLDocumentNode *doc_node)
42 {
43     if(window->doc) {
44         abort_document_bindings(window->doc);
45         window->doc->basedoc.window = NULL;
46         htmldoc_release(&window->doc->basedoc);
47     }
48     window->doc = doc_node;
49     if(doc_node)
50         htmldoc_addref(&doc_node->basedoc);
51
52     if(window->doc_obj && window->doc_obj->basedoc.window == window) {
53         if(window->doc_obj->basedoc.doc_node)
54             htmldoc_release(&window->doc_obj->basedoc.doc_node->basedoc);
55         window->doc_obj->basedoc.doc_node = doc_node;
56         if(doc_node)
57             htmldoc_addref(&doc_node->basedoc);
58     }
59 }
60
61 nsIDOMWindow *get_nsdoc_window(nsIDOMDocument *nsdoc)
62 {
63     nsIDOMDocumentView *nsdocview;
64     nsIDOMAbstractView *nsview;
65     nsIDOMWindow *nswindow;
66     nsresult nsres;
67
68     nsres = nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMDocumentView, (void**)&nsdocview);
69     nsIDOMDocument_Release(nsdoc);
70     if(NS_FAILED(nsres)) {
71         ERR("Could not get nsIDOMDocumentView iface: %08x\n", nsres);
72         return NULL;
73     }
74
75     nsres = nsIDOMDocumentView_GetDefaultView(nsdocview, &nsview);
76     nsIDOMDocumentView_Release(nsview);
77     if(NS_FAILED(nsres)) {
78         ERR("GetDefaultView failed: %08x\n", nsres);
79         return NULL;
80     }
81
82     nsres = nsIDOMAbstractView_QueryInterface(nsview, &IID_nsIDOMWindow, (void**)&nswindow);
83     nsIDOMAbstractView_Release(nsview);
84     if(NS_FAILED(nsres)) {
85         ERR("Coult not get nsIDOMWindow iface: %08x\n", nsres);
86         return NULL;
87     }
88
89     return nswindow;
90 }
91
92 static void release_children(HTMLWindow *This)
93 {
94     HTMLWindow *child;
95
96     while(!list_empty(&This->children)) {
97         child = LIST_ENTRY(list_tail(&This->children), HTMLWindow, sibling_entry);
98
99         list_remove(&child->sibling_entry);
100         child->parent = NULL;
101         IHTMLWindow2_Release(HTMLWINDOW2(child));
102     }
103 }
104
105 static HRESULT get_location(HTMLWindow *This, HTMLLocation **ret)
106 {
107     if(This->location) {
108         IHTMLLocation_AddRef(HTMLLOCATION(This->location));
109     }else {
110         HRESULT hres;
111
112         hres = HTMLLocation_Create(This, &This->location);
113         if(FAILED(hres))
114             return hres;
115     }
116
117     *ret = This->location;
118     return S_OK;
119 }
120
121 static inline HRESULT set_window_event(HTMLWindow *window, eventid_t eid, VARIANT *var)
122 {
123     if(!window->doc) {
124         FIXME("No document\n");
125         return E_FAIL;
126     }
127
128     return set_event_handler(&window->doc->body_event_target, window->doc, eid, var);
129 }
130
131 static inline HRESULT get_window_event(HTMLWindow *window, eventid_t eid, VARIANT *var)
132 {
133     if(!window->doc) {
134         FIXME("No document\n");
135         return E_FAIL;
136     }
137
138     return get_event_handler(&window->doc->body_event_target, eid, var);
139 }
140
141 #define HTMLWINDOW2_THIS(iface) DEFINE_THIS(HTMLWindow, HTMLWindow2, iface)
142
143 static HRESULT WINAPI HTMLWindow2_QueryInterface(IHTMLWindow2 *iface, REFIID riid, void **ppv)
144 {
145     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
146
147     *ppv = NULL;
148
149     if(IsEqualGUID(&IID_IUnknown, riid)) {
150         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
151         *ppv = HTMLWINDOW2(This);
152     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
153         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
154         *ppv = HTMLWINDOW2(This);
155     }else if(IsEqualGUID(&IID_IDispatchEx, riid)) {
156         TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv);
157         *ppv = DISPATCHEX(This);
158     }else if(IsEqualGUID(&IID_IHTMLFramesCollection2, riid)) {
159         TRACE("(%p)->(IID_IHTMLFramesCollection2 %p)\n", This, ppv);
160         *ppv = HTMLWINDOW2(This);
161     }else if(IsEqualGUID(&IID_IHTMLWindow2, riid)) {
162         TRACE("(%p)->(IID_IHTMLWindow2 %p)\n", This, ppv);
163         *ppv = HTMLWINDOW2(This);
164     }else if(IsEqualGUID(&IID_IHTMLWindow3, riid)) {
165         TRACE("(%p)->(IID_IHTMLWindow3 %p)\n", This, ppv);
166         *ppv = HTMLWINDOW3(This);
167     }else if(IsEqualGUID(&IID_IHTMLWindow4, riid)) {
168         TRACE("(%p)->(IID_IHTMLWindow4 %p)\n", This, ppv);
169         *ppv = HTMLWINDOW4(This);
170     }else if(IsEqualGUID(&IID_IHTMLPrivateWindow, riid)) {
171         TRACE("(%p)->(IID_IHTMLPrivateWindow %p)\n", This, ppv);
172         *ppv = HTMLPRIVWINDOW(This);
173     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
174         return *ppv ? S_OK : E_NOINTERFACE;
175     }
176
177     if(*ppv) {
178         IUnknown_AddRef((IUnknown*)*ppv);
179         return S_OK;
180     }
181
182     WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
183     return E_NOINTERFACE;
184 }
185
186 static ULONG WINAPI HTMLWindow2_AddRef(IHTMLWindow2 *iface)
187 {
188     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
189     LONG ref = InterlockedIncrement(&This->ref);
190
191     TRACE("(%p) ref=%d\n", This, ref);
192
193     return ref;
194 }
195
196 static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface)
197 {
198     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
199     LONG ref = InterlockedDecrement(&This->ref);
200
201     TRACE("(%p) ref=%d\n", This, ref);
202
203     if(!ref) {
204         DWORD i;
205
206         remove_target_tasks(This->task_magic);
207         set_window_bscallback(This, NULL);
208         set_current_mon(This, NULL);
209         window_set_docnode(This, NULL);
210         release_children(This);
211
212         if(This->frame_element)
213             This->frame_element->content_window = NULL;
214
215         if(This->option_factory) {
216             This->option_factory->window = NULL;
217             IHTMLOptionElementFactory_Release(HTMLOPTFACTORY(This->option_factory));
218         }
219
220         if(This->image_factory) {
221             This->image_factory->window = NULL;
222             IHTMLImageElementFactory_Release(HTMLIMGFACTORY(This->image_factory));
223         }
224
225         if(This->location) {
226             This->location->window = NULL;
227             IHTMLLocation_Release(HTMLLOCATION(This->location));
228         }
229
230         if(This->screen)
231             IHTMLScreen_Release(This->screen);
232
233         for(i=0; i < This->global_prop_cnt; i++)
234             heap_free(This->global_props[i].name);
235
236         This->window_ref->window = NULL;
237         windowref_release(This->window_ref);
238
239         heap_free(This->global_props);
240         release_script_hosts(This);
241
242         if(This->nswindow)
243             nsIDOMWindow_Release(This->nswindow);
244
245         list_remove(&This->entry);
246         release_dispex(&This->dispex);
247         heap_free(This);
248     }
249
250     return ref;
251 }
252
253 static HRESULT WINAPI HTMLWindow2_GetTypeInfoCount(IHTMLWindow2 *iface, UINT *pctinfo)
254 {
255     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
256
257     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo);
258 }
259
260 static HRESULT WINAPI HTMLWindow2_GetTypeInfo(IHTMLWindow2 *iface, UINT iTInfo,
261                                               LCID lcid, ITypeInfo **ppTInfo)
262 {
263     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
264
265     return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo);
266 }
267
268 static HRESULT WINAPI HTMLWindow2_GetIDsOfNames(IHTMLWindow2 *iface, REFIID riid,
269                                                 LPOLESTR *rgszNames, UINT cNames,
270                                                 LCID lcid, DISPID *rgDispId)
271 {
272     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
273
274     return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId);
275 }
276
277 static HRESULT WINAPI HTMLWindow2_Invoke(IHTMLWindow2 *iface, DISPID dispIdMember,
278                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
279                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
280 {
281     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
282
283     return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams,
284             pVarResult, pExcepInfo, puArgErr);
285 }
286
287 static HRESULT get_frame_by_index(nsIDOMWindowCollection *nsFrames, PRUint32 index, HTMLWindow **ret)
288 {
289     PRUint32 length;
290     nsIDOMWindow *nsWindow;
291     nsresult nsres;
292
293     nsres = nsIDOMWindowCollection_GetLength(nsFrames, &length);
294     if(NS_FAILED(nsres)) {
295         FIXME("nsIDOMWindowCollection_GetLength failed: 0x%08x\n", nsres);
296         return E_FAIL;
297     }
298
299     if(index >= length)
300         return DISP_E_MEMBERNOTFOUND;
301
302     nsres = nsIDOMWindowCollection_Item(nsFrames, index, &nsWindow);
303     if(NS_FAILED(nsres)) {
304         FIXME("nsIDOMWindowCollection_Item failed: 0x%08x\n", nsres);
305         return E_FAIL;
306     }
307
308     *ret = nswindow_to_window(nsWindow);
309
310     nsIDOMWindow_Release(nsWindow);
311
312     return S_OK;
313 }
314
315 static HRESULT WINAPI HTMLWindow2_item(IHTMLWindow2 *iface, VARIANT *pvarIndex, VARIANT *pvarResult)
316 {
317     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
318     nsIDOMWindowCollection *nsFrames;
319     HTMLWindow *window;
320     HRESULT hres;
321     nsresult nsres;
322
323     TRACE("(%p)->(%p %p)\n", This, pvarIndex, pvarResult);
324
325     nsres = nsIDOMWindow_GetFrames(This->nswindow, &nsFrames);
326     if(NS_FAILED(nsres)) {
327         FIXME("nsIDOMWindow_GetFrames failed: 0x%08x\n", nsres);
328         return E_FAIL;
329     }
330
331     if(V_VT(pvarIndex) == VT_I4) {
332         int index = V_I4(pvarIndex);
333         TRACE("Getting index %d\n", index);
334         if(index < 0) {
335             hres = DISP_E_MEMBERNOTFOUND;
336             goto cleanup;
337         }
338         hres = get_frame_by_index(nsFrames, index, &window);
339         if(FAILED(hres))
340             goto cleanup;
341     }else if(V_VT(pvarIndex) == VT_UINT) {
342         unsigned int index = V_UINT(pvarIndex);
343         TRACE("Getting index %u\n", index);
344         hres = get_frame_by_index(nsFrames, index, &window);
345         if(FAILED(hres))
346             goto cleanup;
347     }else if(V_VT(pvarIndex) == VT_BSTR) {
348         BSTR str = V_BSTR(pvarIndex);
349         PRUint32 length, i;
350
351         TRACE("Getting name %s\n", wine_dbgstr_w(str));
352
353         nsres = nsIDOMWindowCollection_GetLength(nsFrames, &length);
354
355         window = NULL;
356         for(i = 0; i < length && !window; ++i) {
357             HTMLWindow *cur_window;
358             nsIDOMWindow *nsWindow;
359             BSTR id;
360
361             nsres = nsIDOMWindowCollection_Item(nsFrames, i, &nsWindow);
362             if(NS_FAILED(nsres)) {
363                 FIXME("nsIDOMWindowCollection_Item failed: 0x%08x\n", nsres);
364                 hres = E_FAIL;
365                 goto cleanup;
366             }
367
368             cur_window = nswindow_to_window(nsWindow);
369
370             nsIDOMWindow_Release(nsWindow);
371
372             hres = IHTMLElement_get_id(HTMLELEM(&cur_window->frame_element->element), &id);
373             if(FAILED(hres)) {
374                 FIXME("IHTMLElement_get_id failed: 0x%08x\n", hres);
375                 goto cleanup;
376             }
377
378             if(!strcmpW(id, str))
379                 window = cur_window;
380
381             SysFreeString(id);
382         }
383
384         if(!window) {
385             hres = DISP_E_MEMBERNOTFOUND;
386             goto cleanup;
387         }
388     }else {
389         hres = E_INVALIDARG;
390         goto cleanup;
391     }
392
393     IHTMLWindow2_AddRef(HTMLWINDOW2(window));
394     V_VT(pvarResult) = VT_DISPATCH;
395     V_DISPATCH(pvarResult) = (IDispatch*)window;
396
397     hres = S_OK;
398
399 cleanup:
400     nsIDOMWindowCollection_Release(nsFrames);
401
402     return hres;
403 }
404
405 static HRESULT WINAPI HTMLWindow2_get_length(IHTMLWindow2 *iface, LONG *p)
406 {
407     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
408     nsIDOMWindowCollection *nscollection;
409     PRUint32 length;
410     nsresult nsres;
411
412     TRACE("(%p)->(%p)\n", This, p);
413
414     nsres = nsIDOMWindow_GetFrames(This->nswindow, &nscollection);
415     if(NS_FAILED(nsres)) {
416         ERR("GetFrames failed: %08x\n", nsres);
417         return E_FAIL;
418     }
419
420     nsres = nsIDOMWindowCollection_GetLength(nscollection, &length);
421     nsIDOMWindowCollection_Release(nscollection);
422     if(NS_FAILED(nsres)) {
423         ERR("GetLength failed: %08x\n", nsres);
424         return E_FAIL;
425     }
426
427     *p = length;
428     return S_OK;
429 }
430
431 static HRESULT WINAPI HTMLWindow2_get_frames(IHTMLWindow2 *iface, IHTMLFramesCollection2 **p)
432 {
433     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
434     FIXME("(%p)->(%p): semi-stub\n", This, p);
435
436     /* FIXME: Should return a separate Window object */
437     *p = (IHTMLFramesCollection2*)HTMLWINDOW2(This);
438     HTMLWindow2_AddRef(iface);
439     return S_OK;
440 }
441
442 static HRESULT WINAPI HTMLWindow2_put_defaultStatus(IHTMLWindow2 *iface, BSTR v)
443 {
444     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
445     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
446     return E_NOTIMPL;
447 }
448
449 static HRESULT WINAPI HTMLWindow2_get_defaultStatus(IHTMLWindow2 *iface, BSTR *p)
450 {
451     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
452     FIXME("(%p)->(%p)\n", This, p);
453     return E_NOTIMPL;
454 }
455
456 static HRESULT WINAPI HTMLWindow2_put_status(IHTMLWindow2 *iface, BSTR v)
457 {
458     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
459     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
460     return E_NOTIMPL;
461 }
462
463 static HRESULT WINAPI HTMLWindow2_get_status(IHTMLWindow2 *iface, BSTR *p)
464 {
465     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
466     FIXME("(%p)->(%p)\n", This, p);
467     return E_NOTIMPL;
468 }
469
470 static HRESULT WINAPI HTMLWindow2_setTimeout(IHTMLWindow2 *iface, BSTR expression,
471         LONG msec, VARIANT *language, LONG *timerID)
472 {
473     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
474     VARIANT expr_var;
475
476     TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(expression), msec, language, timerID);
477
478     V_VT(&expr_var) = VT_BSTR;
479     V_BSTR(&expr_var) = expression;
480
481     return IHTMLWindow3_setTimeout(HTMLWINDOW3(This), &expr_var, msec, language, timerID);
482 }
483
484 static HRESULT WINAPI HTMLWindow2_clearTimeout(IHTMLWindow2 *iface, LONG timerID)
485 {
486     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
487
488     TRACE("(%p)->(%d)\n", This, timerID);
489
490     return clear_task_timer(&This->doc->basedoc, FALSE, timerID);
491 }
492
493 static HRESULT WINAPI HTMLWindow2_alert(IHTMLWindow2 *iface, BSTR message)
494 {
495     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
496     WCHAR wszTitle[100];
497
498     TRACE("(%p)->(%s)\n", This, debugstr_w(message));
499
500     if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
501                     sizeof(wszTitle)/sizeof(WCHAR))) {
502         WARN("Could not load message box title: %d\n", GetLastError());
503         return S_OK;
504     }
505
506     MessageBoxW(This->doc_obj->hwnd, message, wszTitle, MB_ICONWARNING);
507     return S_OK;
508 }
509
510 static HRESULT WINAPI HTMLWindow2_confirm(IHTMLWindow2 *iface, BSTR message,
511         VARIANT_BOOL *confirmed)
512 {
513     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
514     WCHAR wszTitle[100];
515
516     TRACE("(%p)->(%s %p)\n", This, debugstr_w(message), confirmed);
517
518     if(!confirmed) return E_INVALIDARG;
519
520     if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
521                 sizeof(wszTitle)/sizeof(WCHAR))) {
522         WARN("Could not load message box title: %d\n", GetLastError());
523         *confirmed = VARIANT_TRUE;
524         return S_OK;
525     }
526
527     if(MessageBoxW(This->doc_obj->hwnd, message, wszTitle,
528                 MB_OKCANCEL|MB_ICONQUESTION)==IDOK)
529         *confirmed = VARIANT_TRUE;
530     else *confirmed = VARIANT_FALSE;
531
532     return S_OK;
533 }
534
535 typedef struct
536 {
537     BSTR message;
538     BSTR dststr;
539     VARIANT *textdata;
540 }prompt_arg;
541
542 static INT_PTR CALLBACK prompt_dlgproc(HWND hwnd, UINT msg,
543         WPARAM wparam, LPARAM lparam)
544 {
545     switch(msg)
546     {
547         case WM_INITDIALOG:
548         {
549             prompt_arg *arg = (prompt_arg*)lparam;
550             WCHAR wszTitle[100];
551
552             if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
553                         sizeof(wszTitle)/sizeof(WCHAR))) {
554                 WARN("Could not load message box title: %d\n", GetLastError());
555                 EndDialog(hwnd, wparam);
556                 return FALSE;
557             }
558
559             SetWindowLongPtrW(hwnd, DWLP_USER, lparam);
560             SetWindowTextW(hwnd, wszTitle);
561             SetWindowTextW(GetDlgItem(hwnd, ID_PROMPT_PROMPT), arg->message);
562             SetWindowTextW(GetDlgItem(hwnd, ID_PROMPT_EDIT), arg->dststr);
563             return FALSE;
564         }
565         case WM_COMMAND:
566             switch(wparam)
567             {
568                 case MAKEWPARAM(IDCANCEL, BN_CLICKED):
569                     EndDialog(hwnd, wparam);
570                     return TRUE;
571                 case MAKEWPARAM(IDOK, BN_CLICKED):
572                 {
573                     prompt_arg *arg =
574                         (prompt_arg*)GetWindowLongPtrW(hwnd, DWLP_USER);
575                     HWND hwndPrompt = GetDlgItem(hwnd, ID_PROMPT_EDIT);
576                     INT len = GetWindowTextLengthW(hwndPrompt);
577
578                     if(!arg->textdata)
579                     {
580                         EndDialog(hwnd, wparam);
581                         return TRUE;
582                     }
583
584                     V_VT(arg->textdata) = VT_BSTR;
585                     if(!len && !arg->dststr)
586                         V_BSTR(arg->textdata) = NULL;
587                     else
588                     {
589                         V_BSTR(arg->textdata) = SysAllocStringLen(NULL, len);
590                         GetWindowTextW(hwndPrompt, V_BSTR(arg->textdata), len+1);
591                     }
592                     EndDialog(hwnd, wparam);
593                     return TRUE;
594                 }
595             }
596             return FALSE;
597         case WM_CLOSE:
598             EndDialog(hwnd, IDCANCEL);
599             return TRUE;
600         default:
601             return FALSE;
602     }
603 }
604
605 static HRESULT WINAPI HTMLWindow2_prompt(IHTMLWindow2 *iface, BSTR message,
606         BSTR dststr, VARIANT *textdata)
607 {
608     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
609     prompt_arg arg;
610
611     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(message), debugstr_w(dststr), textdata);
612
613     if(textdata) V_VT(textdata) = VT_NULL;
614
615     arg.message = message;
616     arg.dststr = dststr;
617     arg.textdata = textdata;
618
619     DialogBoxParamW(hInst, MAKEINTRESOURCEW(ID_PROMPT_DIALOG),
620             This->doc_obj->hwnd, prompt_dlgproc, (LPARAM)&arg);
621     return S_OK;
622 }
623
624 static HRESULT WINAPI HTMLWindow2_get_Image(IHTMLWindow2 *iface, IHTMLImageElementFactory **p)
625 {
626     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
627
628     TRACE("(%p)->(%p)\n", This, p);
629
630     if(!This->image_factory)
631         This->image_factory = HTMLImageElementFactory_Create(This);
632
633     *p = HTMLIMGFACTORY(This->image_factory);
634     IHTMLImageElementFactory_AddRef(*p);
635
636     return S_OK;
637 }
638
639 static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocation **p)
640 {
641     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
642     HTMLLocation *location;
643     HRESULT hres;
644
645     TRACE("(%p)->(%p)\n", This, p);
646
647     hres = get_location(This, &location);
648     if(FAILED(hres))
649         return hres;
650
651     *p = HTMLLOCATION(location);
652     return S_OK;
653 }
654
655 static HRESULT WINAPI HTMLWindow2_get_history(IHTMLWindow2 *iface, IOmHistory **p)
656 {
657     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
658     FIXME("(%p)->(%p)\n", This, p);
659     return E_NOTIMPL;
660 }
661
662 static HRESULT WINAPI HTMLWindow2_close(IHTMLWindow2 *iface)
663 {
664     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
665     FIXME("(%p)->()\n", This);
666     return E_NOTIMPL;
667 }
668
669 static HRESULT WINAPI HTMLWindow2_put_opener(IHTMLWindow2 *iface, VARIANT v)
670 {
671     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
672     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
673     return E_NOTIMPL;
674 }
675
676 static HRESULT WINAPI HTMLWindow2_get_opener(IHTMLWindow2 *iface, VARIANT *p)
677 {
678     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
679     FIXME("(%p)->(%p)\n", This, p);
680     return E_NOTIMPL;
681 }
682
683 static HRESULT WINAPI HTMLWindow2_get_navigator(IHTMLWindow2 *iface, IOmNavigator **p)
684 {
685     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
686
687     TRACE("(%p)->(%p)\n", This, p);
688
689     *p = OmNavigator_Create();
690     return S_OK;
691 }
692
693 static HRESULT WINAPI HTMLWindow2_put_name(IHTMLWindow2 *iface, BSTR v)
694 {
695     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
696     nsAString name_str;
697     nsresult nsres;
698
699     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
700
701     nsAString_InitDepend(&name_str, v);
702     nsres = nsIDOMWindow_SetName(This->nswindow, &name_str);
703     nsAString_Finish(&name_str);
704     if(NS_FAILED(nsres))
705         ERR("SetName failed: %08x\n", nsres);
706
707     return S_OK;
708 }
709
710 static HRESULT WINAPI HTMLWindow2_get_name(IHTMLWindow2 *iface, BSTR *p)
711 {
712     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
713     nsAString name_str;
714     nsresult nsres;
715     HRESULT hres;
716
717     TRACE("(%p)->(%p)\n", This, p);
718
719     nsAString_Init(&name_str, NULL);
720     nsres = nsIDOMWindow_GetName(This->nswindow, &name_str);
721     if(NS_SUCCEEDED(nsres)) {
722         const PRUnichar *name;
723
724         nsAString_GetData(&name_str, &name);
725         if(*name) {
726             *p = SysAllocString(name);
727             hres = *p ? S_OK : E_OUTOFMEMORY;
728         }else {
729             *p = NULL;
730             hres = S_OK;
731         }
732     }else {
733         ERR("GetName failed: %08x\n", nsres);
734         hres = E_FAIL;
735     }
736     nsAString_Finish(&name_str);
737
738     return hres;
739 }
740
741 static HRESULT WINAPI HTMLWindow2_get_parent(IHTMLWindow2 *iface, IHTMLWindow2 **p)
742 {
743     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
744     TRACE("(%p)->(%p)\n", This, p);
745
746     if(This->parent) {
747         *p = HTMLWINDOW2(This->parent);
748         IHTMLWindow2_AddRef(*p);
749     }else
750         *p = NULL;
751
752     return S_OK;
753 }
754
755 static HRESULT WINAPI HTMLWindow2_open(IHTMLWindow2 *iface, BSTR url, BSTR name,
756          BSTR features, VARIANT_BOOL replace, IHTMLWindow2 **pomWindowResult)
757 {
758     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
759     FIXME("(%p)->(%s %s %s %x %p)\n", This, debugstr_w(url), debugstr_w(name),
760           debugstr_w(features), replace, pomWindowResult);
761     return E_NOTIMPL;
762 }
763
764 static HRESULT WINAPI HTMLWindow2_get_self(IHTMLWindow2 *iface, IHTMLWindow2 **p)
765 {
766     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
767
768     TRACE("(%p)->(%p)\n", This, p);
769
770     /* FIXME: We should return kind of proxy window here. */
771     IHTMLWindow2_AddRef(HTMLWINDOW2(This));
772     *p = HTMLWINDOW2(This);
773     return S_OK;
774 }
775
776 static HRESULT WINAPI HTMLWindow2_get_top(IHTMLWindow2 *iface, IHTMLWindow2 **p)
777 {
778     HTMLWindow *This = HTMLWINDOW2_THIS(iface), *curr;
779     TRACE("(%p)->(%p)\n", This, p);
780
781     curr = This;
782     while(curr->parent)
783         curr = curr->parent;
784     *p = HTMLWINDOW2(curr);
785     IHTMLWindow2_AddRef(*p);
786
787     return S_OK;
788 }
789
790 static HRESULT WINAPI HTMLWindow2_get_window(IHTMLWindow2 *iface, IHTMLWindow2 **p)
791 {
792     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
793
794     TRACE("(%p)->(%p)\n", This, p);
795
796     /* FIXME: We should return kind of proxy window here. */
797     IHTMLWindow2_AddRef(HTMLWINDOW2(This));
798     *p = HTMLWINDOW2(This);
799     return S_OK;
800 }
801
802 static HRESULT WINAPI HTMLWindow2_navigate(IHTMLWindow2 *iface, BSTR url)
803 {
804     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
805     FIXME("(%p)->(%s)\n", This, debugstr_w(url));
806     return E_NOTIMPL;
807 }
808
809 static HRESULT WINAPI HTMLWindow2_put_onfocus(IHTMLWindow2 *iface, VARIANT v)
810 {
811     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
812     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
813     return E_NOTIMPL;
814 }
815
816 static HRESULT WINAPI HTMLWindow2_get_onfocus(IHTMLWindow2 *iface, VARIANT *p)
817 {
818     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
819     FIXME("(%p)->(%p)\n", This, p);
820     return E_NOTIMPL;
821 }
822
823 static HRESULT WINAPI HTMLWindow2_put_onblur(IHTMLWindow2 *iface, VARIANT v)
824 {
825     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
826     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
827     return E_NOTIMPL;
828 }
829
830 static HRESULT WINAPI HTMLWindow2_get_onblur(IHTMLWindow2 *iface, VARIANT *p)
831 {
832     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
833     FIXME("(%p)->(%p)\n", This, p);
834     return E_NOTIMPL;
835 }
836
837 static HRESULT WINAPI HTMLWindow2_put_onload(IHTMLWindow2 *iface, VARIANT v)
838 {
839     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
840
841     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
842
843     return set_window_event(This, EVENTID_LOAD, &v);
844 }
845
846 static HRESULT WINAPI HTMLWindow2_get_onload(IHTMLWindow2 *iface, VARIANT *p)
847 {
848     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
849
850     TRACE("(%p)->(%p)\n", This, p);
851
852     return get_window_event(This, EVENTID_LOAD, p);
853 }
854
855 static HRESULT WINAPI HTMLWindow2_put_onbeforeunload(IHTMLWindow2 *iface, VARIANT v)
856 {
857     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
858
859     TRACE("(%p)->(v(%d))\n", This, V_VT(&v));
860
861     return set_window_event(This, EVENTID_BEFOREUNLOAD, &v);
862 }
863
864 static HRESULT WINAPI HTMLWindow2_get_onbeforeunload(IHTMLWindow2 *iface, VARIANT *p)
865 {
866     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
867
868     TRACE("(%p)->(%p)\n", This, p);
869
870     return get_window_event(This, EVENTID_BEFOREUNLOAD, p);
871 }
872
873 static HRESULT WINAPI HTMLWindow2_put_onunload(IHTMLWindow2 *iface, VARIANT v)
874 {
875     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
876     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
877     return E_NOTIMPL;
878 }
879
880 static HRESULT WINAPI HTMLWindow2_get_onunload(IHTMLWindow2 *iface, VARIANT *p)
881 {
882     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
883     FIXME("(%p)->(%p)\n", This, p);
884     return E_NOTIMPL;
885 }
886
887 static HRESULT WINAPI HTMLWindow2_put_onhelp(IHTMLWindow2 *iface, VARIANT v)
888 {
889     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
890     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
891     return E_NOTIMPL;
892 }
893
894 static HRESULT WINAPI HTMLWindow2_get_onhelp(IHTMLWindow2 *iface, VARIANT *p)
895 {
896     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
897     FIXME("(%p)->(%p)\n", This, p);
898     return E_NOTIMPL;
899 }
900
901 static HRESULT WINAPI HTMLWindow2_put_onerror(IHTMLWindow2 *iface, VARIANT v)
902 {
903     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
904     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
905     return E_NOTIMPL;
906 }
907
908 static HRESULT WINAPI HTMLWindow2_get_onerror(IHTMLWindow2 *iface, VARIANT *p)
909 {
910     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
911     FIXME("(%p)->(%p)\n", This, p);
912     return E_NOTIMPL;
913 }
914
915 static HRESULT WINAPI HTMLWindow2_put_onresize(IHTMLWindow2 *iface, VARIANT v)
916 {
917     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
918
919     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
920
921     return set_window_event(This, EVENTID_RESIZE, &v);
922 }
923
924 static HRESULT WINAPI HTMLWindow2_get_onresize(IHTMLWindow2 *iface, VARIANT *p)
925 {
926     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
927
928     TRACE("(%p)->(%p)\n", This, p);
929
930     return get_window_event(This, EVENTID_RESIZE, p);
931 }
932
933 static HRESULT WINAPI HTMLWindow2_put_onscroll(IHTMLWindow2 *iface, VARIANT v)
934 {
935     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
936     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
937     return E_NOTIMPL;
938 }
939
940 static HRESULT WINAPI HTMLWindow2_get_onscroll(IHTMLWindow2 *iface, VARIANT *p)
941 {
942     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
943     FIXME("(%p)->(%p)\n", This, p);
944     return E_NOTIMPL;
945 }
946
947 static HRESULT WINAPI HTMLWindow2_get_document(IHTMLWindow2 *iface, IHTMLDocument2 **p)
948 {
949     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
950
951     TRACE("(%p)->(%p)\n", This, p);
952
953     if(This->doc) {
954         /* FIXME: We should return a wrapper object here */
955         *p = HTMLDOC(&This->doc->basedoc);
956         IHTMLDocument2_AddRef(*p);
957     }else {
958         *p = NULL;
959     }
960
961     return S_OK;
962 }
963
964 static HRESULT WINAPI HTMLWindow2_get_event(IHTMLWindow2 *iface, IHTMLEventObj **p)
965 {
966     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
967
968     TRACE("(%p)->(%p)\n", This, p);
969
970     if(This->event)
971         IHTMLEventObj_AddRef(This->event);
972     *p = This->event;
973     return S_OK;
974 }
975
976 static HRESULT WINAPI HTMLWindow2_get__newEnum(IHTMLWindow2 *iface, IUnknown **p)
977 {
978     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
979     FIXME("(%p)->(%p)\n", This, p);
980     return E_NOTIMPL;
981 }
982
983 static HRESULT WINAPI HTMLWindow2_showModalDialog(IHTMLWindow2 *iface, BSTR dialog,
984         VARIANT *varArgIn, VARIANT *varOptions, VARIANT *varArgOut)
985 {
986     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
987     FIXME("(%p)->(%s %p %p %p)\n", This, debugstr_w(dialog), varArgIn, varOptions, varArgOut);
988     return E_NOTIMPL;
989 }
990
991 static HRESULT WINAPI HTMLWindow2_showHelp(IHTMLWindow2 *iface, BSTR helpURL, VARIANT helpArg,
992         BSTR features)
993 {
994     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
995     FIXME("(%p)->(%s v(%d) %s)\n", This, debugstr_w(helpURL), V_VT(&helpArg), debugstr_w(features));
996     return E_NOTIMPL;
997 }
998
999 static HRESULT WINAPI HTMLWindow2_get_screen(IHTMLWindow2 *iface, IHTMLScreen **p)
1000 {
1001     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1002
1003     TRACE("(%p)->(%p)\n", This, p);
1004
1005     if(!This->screen) {
1006         HRESULT hres;
1007
1008         hres = HTMLScreen_Create(&This->screen);
1009         if(FAILED(hres))
1010             return hres;
1011     }
1012
1013     *p = This->screen;
1014     IHTMLScreen_AddRef(This->screen);
1015     return S_OK;
1016 }
1017
1018 static HRESULT WINAPI HTMLWindow2_get_Option(IHTMLWindow2 *iface, IHTMLOptionElementFactory **p)
1019 {
1020     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1021
1022     TRACE("(%p)->(%p)\n", This, p);
1023
1024     if(!This->option_factory)
1025         This->option_factory = HTMLOptionElementFactory_Create(This);
1026
1027     *p = HTMLOPTFACTORY(This->option_factory);
1028     IHTMLOptionElementFactory_AddRef(*p);
1029
1030     return S_OK;
1031 }
1032
1033 static HRESULT WINAPI HTMLWindow2_focus(IHTMLWindow2 *iface)
1034 {
1035     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1036     FIXME("(%p)->()\n", This);
1037     return E_NOTIMPL;
1038 }
1039
1040 static HRESULT WINAPI HTMLWindow2_get_closed(IHTMLWindow2 *iface, VARIANT_BOOL *p)
1041 {
1042     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1043     FIXME("(%p)->(%p)\n", This, p);
1044     return E_NOTIMPL;
1045 }
1046
1047 static HRESULT WINAPI HTMLWindow2_blur(IHTMLWindow2 *iface)
1048 {
1049     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1050     FIXME("(%p)->()\n", This);
1051     return E_NOTIMPL;
1052 }
1053
1054 static HRESULT WINAPI HTMLWindow2_scroll(IHTMLWindow2 *iface, LONG x, LONG y)
1055 {
1056     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1057     FIXME("(%p)->(%d %d)\n", This, x, y);
1058     return E_NOTIMPL;
1059 }
1060
1061 static HRESULT WINAPI HTMLWindow2_get_clientInformation(IHTMLWindow2 *iface, IOmNavigator **p)
1062 {
1063     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1064     FIXME("(%p)->(%p)\n", This, p);
1065     return E_NOTIMPL;
1066 }
1067
1068 static HRESULT WINAPI HTMLWindow2_setInterval(IHTMLWindow2 *iface, BSTR expression,
1069         LONG msec, VARIANT *language, LONG *timerID)
1070 {
1071     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1072     VARIANT expr;
1073
1074     TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(expression), msec, language, timerID);
1075
1076     V_VT(&expr) = VT_BSTR;
1077     V_BSTR(&expr) = expression;
1078     return IHTMLWindow3_setInterval(HTMLWINDOW3(This), &expr, msec, language, timerID);
1079 }
1080
1081 static HRESULT WINAPI HTMLWindow2_clearInterval(IHTMLWindow2 *iface, LONG timerID)
1082 {
1083     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1084
1085     TRACE("(%p)->(%d)\n", This, timerID);
1086
1087     return clear_task_timer(&This->doc->basedoc, TRUE, timerID);
1088 }
1089
1090 static HRESULT WINAPI HTMLWindow2_put_offscreenBuffering(IHTMLWindow2 *iface, VARIANT v)
1091 {
1092     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1093     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
1094     return E_NOTIMPL;
1095 }
1096
1097 static HRESULT WINAPI HTMLWindow2_get_offscreenBuffering(IHTMLWindow2 *iface, VARIANT *p)
1098 {
1099     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1100     FIXME("(%p)->(%p)\n", This, p);
1101     return E_NOTIMPL;
1102 }
1103
1104 static HRESULT WINAPI HTMLWindow2_execScript(IHTMLWindow2 *iface, BSTR scode, BSTR language,
1105         VARIANT *pvarRet)
1106 {
1107     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1108     FIXME("(%p)->(%s %s %p)\n", This, debugstr_w(scode), debugstr_w(language), pvarRet);
1109     return E_NOTIMPL;
1110 }
1111
1112 static HRESULT WINAPI HTMLWindow2_toString(IHTMLWindow2 *iface, BSTR *String)
1113 {
1114     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1115
1116     static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
1117
1118     TRACE("(%p)->(%p)\n", This, String);
1119
1120     if(!String)
1121         return E_INVALIDARG;
1122
1123     *String = SysAllocString(objectW);
1124     return *String ? S_OK : E_OUTOFMEMORY;
1125 }
1126
1127 static HRESULT WINAPI HTMLWindow2_scrollBy(IHTMLWindow2 *iface, LONG x, LONG y)
1128 {
1129     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1130     nsresult nsres;
1131
1132     TRACE("(%p)->(%d %d)\n", This, x, y);
1133
1134     nsres = nsIDOMWindow_ScrollBy(This->nswindow, x, y);
1135     if(NS_FAILED(nsres))
1136         ERR("ScrollBy failed: %08x\n", nsres);
1137
1138     return S_OK;
1139 }
1140
1141 static HRESULT WINAPI HTMLWindow2_scrollTo(IHTMLWindow2 *iface, LONG x, LONG y)
1142 {
1143     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1144     nsresult nsres;
1145
1146     TRACE("(%p)->(%d %d)\n", This, x, y);
1147
1148     nsres = nsIDOMWindow_ScrollTo(This->nswindow, x, y);
1149     if(NS_FAILED(nsres))
1150         ERR("ScrollTo failed: %08x\n", nsres);
1151
1152     return S_OK;
1153 }
1154
1155 static HRESULT WINAPI HTMLWindow2_moveTo(IHTMLWindow2 *iface, LONG x, LONG y)
1156 {
1157     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1158     FIXME("(%p)->(%d %d)\n", This, x, y);
1159     return E_NOTIMPL;
1160 }
1161
1162 static HRESULT WINAPI HTMLWindow2_moveBy(IHTMLWindow2 *iface, LONG x, LONG y)
1163 {
1164     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1165     FIXME("(%p)->(%d %d)\n", This, x, y);
1166     return E_NOTIMPL;
1167 }
1168
1169 static HRESULT WINAPI HTMLWindow2_resizeTo(IHTMLWindow2 *iface, LONG x, LONG y)
1170 {
1171     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1172     FIXME("(%p)->(%d %d)\n", This, x, y);
1173     return E_NOTIMPL;
1174 }
1175
1176 static HRESULT WINAPI HTMLWindow2_resizeBy(IHTMLWindow2 *iface, LONG x, LONG y)
1177 {
1178     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1179     FIXME("(%p)->(%d %d)\n", This, x, y);
1180     return E_NOTIMPL;
1181 }
1182
1183 static HRESULT WINAPI HTMLWindow2_get_external(IHTMLWindow2 *iface, IDispatch **p)
1184 {
1185     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1186
1187     TRACE("(%p)->(%p)\n", This, p);
1188
1189     *p = NULL;
1190
1191     if(!This->doc_obj->hostui)
1192         return S_OK;
1193
1194     return IDocHostUIHandler_GetExternal(This->doc_obj->hostui, p);
1195 }
1196
1197 static HRESULT HTMLWindow_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
1198         VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
1199 {
1200     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1201     global_prop_t *prop;
1202     DWORD idx;
1203     HRESULT hres;
1204
1205     idx = id - MSHTML_DISPID_CUSTOM_MIN;
1206     if(idx >= This->global_prop_cnt)
1207         return DISP_E_MEMBERNOTFOUND;
1208
1209     prop = This->global_props+idx;
1210
1211     switch(prop->type) {
1212     case GLOBAL_SCRIPTVAR: {
1213         IDispatchEx *dispex;
1214         IDispatch *disp;
1215
1216         disp = get_script_disp(prop->script_host);
1217         if(!disp)
1218             return E_UNEXPECTED;
1219
1220         hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1221         if(SUCCEEDED(hres)) {
1222             TRACE("%s >>>\n", debugstr_w(prop->name));
1223             hres = IDispatchEx_InvokeEx(dispex, prop->id, lcid, flags, params, res, ei, caller);
1224             if(hres == S_OK)
1225                 TRACE("%s <<<\n", debugstr_w(prop->name));
1226             else
1227                 WARN("%s <<< %08x\n", debugstr_w(prop->name), hres);
1228             IDispatchEx_Release(dispex);
1229         }else {
1230             FIXME("No IDispatchEx\n");
1231         }
1232         IDispatch_Release(disp);
1233         break;
1234     }
1235     case GLOBAL_ELEMENTVAR: {
1236         IHTMLElement *elem;
1237
1238         hres = IHTMLDocument3_getElementById(HTMLDOC3(&This->doc->basedoc), prop->name, &elem);
1239         if(FAILED(hres))
1240             return hres;
1241
1242         if(!elem)
1243             return DISP_E_MEMBERNOTFOUND;
1244
1245         V_VT(res) = VT_DISPATCH;
1246         V_DISPATCH(res) = (IDispatch*)elem;
1247         break;
1248     }
1249     default:
1250         ERR("invalid type %d\n", prop->type);
1251         hres = DISP_E_MEMBERNOTFOUND;
1252     }
1253
1254     return hres;
1255 }
1256
1257 #undef HTMLWINDOW2_THIS
1258
1259 static const IHTMLWindow2Vtbl HTMLWindow2Vtbl = {
1260     HTMLWindow2_QueryInterface,
1261     HTMLWindow2_AddRef,
1262     HTMLWindow2_Release,
1263     HTMLWindow2_GetTypeInfoCount,
1264     HTMLWindow2_GetTypeInfo,
1265     HTMLWindow2_GetIDsOfNames,
1266     HTMLWindow2_Invoke,
1267     HTMLWindow2_item,
1268     HTMLWindow2_get_length,
1269     HTMLWindow2_get_frames,
1270     HTMLWindow2_put_defaultStatus,
1271     HTMLWindow2_get_defaultStatus,
1272     HTMLWindow2_put_status,
1273     HTMLWindow2_get_status,
1274     HTMLWindow2_setTimeout,
1275     HTMLWindow2_clearTimeout,
1276     HTMLWindow2_alert,
1277     HTMLWindow2_confirm,
1278     HTMLWindow2_prompt,
1279     HTMLWindow2_get_Image,
1280     HTMLWindow2_get_location,
1281     HTMLWindow2_get_history,
1282     HTMLWindow2_close,
1283     HTMLWindow2_put_opener,
1284     HTMLWindow2_get_opener,
1285     HTMLWindow2_get_navigator,
1286     HTMLWindow2_put_name,
1287     HTMLWindow2_get_name,
1288     HTMLWindow2_get_parent,
1289     HTMLWindow2_open,
1290     HTMLWindow2_get_self,
1291     HTMLWindow2_get_top,
1292     HTMLWindow2_get_window,
1293     HTMLWindow2_navigate,
1294     HTMLWindow2_put_onfocus,
1295     HTMLWindow2_get_onfocus,
1296     HTMLWindow2_put_onblur,
1297     HTMLWindow2_get_onblur,
1298     HTMLWindow2_put_onload,
1299     HTMLWindow2_get_onload,
1300     HTMLWindow2_put_onbeforeunload,
1301     HTMLWindow2_get_onbeforeunload,
1302     HTMLWindow2_put_onunload,
1303     HTMLWindow2_get_onunload,
1304     HTMLWindow2_put_onhelp,
1305     HTMLWindow2_get_onhelp,
1306     HTMLWindow2_put_onerror,
1307     HTMLWindow2_get_onerror,
1308     HTMLWindow2_put_onresize,
1309     HTMLWindow2_get_onresize,
1310     HTMLWindow2_put_onscroll,
1311     HTMLWindow2_get_onscroll,
1312     HTMLWindow2_get_document,
1313     HTMLWindow2_get_event,
1314     HTMLWindow2_get__newEnum,
1315     HTMLWindow2_showModalDialog,
1316     HTMLWindow2_showHelp,
1317     HTMLWindow2_get_screen,
1318     HTMLWindow2_get_Option,
1319     HTMLWindow2_focus,
1320     HTMLWindow2_get_closed,
1321     HTMLWindow2_blur,
1322     HTMLWindow2_scroll,
1323     HTMLWindow2_get_clientInformation,
1324     HTMLWindow2_setInterval,
1325     HTMLWindow2_clearInterval,
1326     HTMLWindow2_put_offscreenBuffering,
1327     HTMLWindow2_get_offscreenBuffering,
1328     HTMLWindow2_execScript,
1329     HTMLWindow2_toString,
1330     HTMLWindow2_scrollBy,
1331     HTMLWindow2_scrollTo,
1332     HTMLWindow2_moveTo,
1333     HTMLWindow2_moveBy,
1334     HTMLWindow2_resizeTo,
1335     HTMLWindow2_resizeBy,
1336     HTMLWindow2_get_external
1337 };
1338
1339 #define HTMLWINDOW3_THIS(iface) DEFINE_THIS(HTMLWindow, HTMLWindow3, iface)
1340
1341 static HRESULT WINAPI HTMLWindow3_QueryInterface(IHTMLWindow3 *iface, REFIID riid, void **ppv)
1342 {
1343     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1344
1345     return IHTMLWindow2_QueryInterface(HTMLWINDOW2(This), riid, ppv);
1346 }
1347
1348 static ULONG WINAPI HTMLWindow3_AddRef(IHTMLWindow3 *iface)
1349 {
1350     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1351
1352     return IHTMLWindow2_AddRef(HTMLWINDOW2(This));
1353 }
1354
1355 static ULONG WINAPI HTMLWindow3_Release(IHTMLWindow3 *iface)
1356 {
1357     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1358
1359     return IHTMLWindow2_Release(HTMLWINDOW2(This));
1360 }
1361
1362 static HRESULT WINAPI HTMLWindow3_GetTypeInfoCount(IHTMLWindow3 *iface, UINT *pctinfo)
1363 {
1364     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1365
1366     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo);
1367 }
1368
1369 static HRESULT WINAPI HTMLWindow3_GetTypeInfo(IHTMLWindow3 *iface, UINT iTInfo,
1370                                               LCID lcid, ITypeInfo **ppTInfo)
1371 {
1372     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1373
1374     return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo);
1375 }
1376
1377 static HRESULT WINAPI HTMLWindow3_GetIDsOfNames(IHTMLWindow3 *iface, REFIID riid,
1378                                                 LPOLESTR *rgszNames, UINT cNames,
1379                                                 LCID lcid, DISPID *rgDispId)
1380 {
1381     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1382
1383     return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId);
1384 }
1385
1386 static HRESULT WINAPI HTMLWindow3_Invoke(IHTMLWindow3 *iface, DISPID dispIdMember,
1387                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1388                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1389 {
1390     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1391
1392     return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams,
1393             pVarResult, pExcepInfo, puArgErr);
1394 }
1395
1396 static HRESULT WINAPI HTMLWindow3_get_screenLeft(IHTMLWindow3 *iface, LONG *p)
1397 {
1398     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1399     FIXME("(%p)->(%p)\n", This, p);
1400     return E_NOTIMPL;
1401 }
1402
1403 static HRESULT WINAPI HTMLWindow3_get_screenTop(IHTMLWindow3 *iface, LONG *p)
1404 {
1405     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1406     FIXME("(%p)->(%p)\n", This, p);
1407     return E_NOTIMPL;
1408 }
1409
1410 static HRESULT WINAPI HTMLWindow3_attachEvent(IHTMLWindow3 *iface, BSTR event, IDispatch *pDisp, VARIANT_BOOL *pfResult)
1411 {
1412     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1413
1414     TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(event), pDisp, pfResult);
1415
1416     if(!This->doc) {
1417         FIXME("No document\n");
1418         return E_FAIL;
1419     }
1420
1421     return attach_event(&This->doc->body_event_target, &This->doc->basedoc, event, pDisp, pfResult);
1422 }
1423
1424 static HRESULT WINAPI HTMLWindow3_detachEvent(IHTMLWindow3 *iface, BSTR event, IDispatch *pDisp)
1425 {
1426     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1427     FIXME("(%p)->()\n", This);
1428     return E_NOTIMPL;
1429 }
1430
1431 static HRESULT window_set_timer(HTMLWindow *This, VARIANT *expr, LONG msec, VARIANT *language,
1432         BOOL interval, LONG *timer_id)
1433 {
1434     IDispatch *disp = NULL;
1435
1436     switch(V_VT(expr)) {
1437     case VT_DISPATCH:
1438         disp = V_DISPATCH(expr);
1439         IDispatch_AddRef(disp);
1440         break;
1441
1442     case VT_BSTR:
1443         disp = script_parse_event(This, V_BSTR(expr));
1444         break;
1445
1446     default:
1447         FIXME("unimplemented vt=%d\n", V_VT(expr));
1448         return E_NOTIMPL;
1449     }
1450
1451     if(!disp)
1452         return E_FAIL;
1453
1454     *timer_id = set_task_timer(&This->doc->basedoc, msec, interval, disp);
1455     IDispatch_Release(disp);
1456
1457     return S_OK;
1458 }
1459
1460 static HRESULT WINAPI HTMLWindow3_setTimeout(IHTMLWindow3 *iface, VARIANT *expression, LONG msec,
1461         VARIANT *language, LONG *timerID)
1462 {
1463     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1464
1465     TRACE("(%p)->(%p(%d) %d %p %p)\n", This, expression, V_VT(expression), msec, language, timerID);
1466
1467     return window_set_timer(This, expression, msec, language, FALSE, timerID);
1468 }
1469
1470 static HRESULT WINAPI HTMLWindow3_setInterval(IHTMLWindow3 *iface, VARIANT *expression, LONG msec,
1471         VARIANT *language, LONG *timerID)
1472 {
1473     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1474
1475     TRACE("(%p)->(%p %d %p %p)\n", This, expression, msec, language, timerID);
1476
1477     return window_set_timer(This, expression, msec, language, TRUE, timerID);
1478 }
1479
1480 static HRESULT WINAPI HTMLWindow3_print(IHTMLWindow3 *iface)
1481 {
1482     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1483     FIXME("(%p)\n", This);
1484     return E_NOTIMPL;
1485 }
1486
1487 static HRESULT WINAPI HTMLWindow3_put_onbeforeprint(IHTMLWindow3 *iface, VARIANT v)
1488 {
1489     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1490     FIXME("(%p)->()\n", This);
1491     return E_NOTIMPL;
1492 }
1493
1494 static HRESULT WINAPI HTMLWindow3_get_onbeforeprint(IHTMLWindow3 *iface, VARIANT *p)
1495 {
1496     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1497     FIXME("(%p)->(%p)\n", This, p);
1498     return E_NOTIMPL;
1499 }
1500
1501 static HRESULT WINAPI HTMLWindow3_put_onafterprint(IHTMLWindow3 *iface, VARIANT v)
1502 {
1503     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1504     FIXME("(%p)->()\n", This);
1505     return E_NOTIMPL;
1506 }
1507
1508 static HRESULT WINAPI HTMLWindow3_get_onafterprint(IHTMLWindow3 *iface, VARIANT *p)
1509 {
1510     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1511     FIXME("(%p)->(%p)\n", This, p);
1512     return E_NOTIMPL;
1513 }
1514
1515 static HRESULT WINAPI HTMLWindow3_get_clipboardData(IHTMLWindow3 *iface, IHTMLDataTransfer **p)
1516 {
1517     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1518     FIXME("(%p)->(%p)\n", This, p);
1519     return E_NOTIMPL;
1520 }
1521
1522 static HRESULT WINAPI HTMLWindow3_showModelessDialog(IHTMLWindow3 *iface, BSTR url,
1523         VARIANT *varArgIn, VARIANT *options, IHTMLWindow2 **pDialog)
1524 {
1525     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1526     FIXME("(%p)->(%s %p %p %p)\n", This, debugstr_w(url), varArgIn, options, pDialog);
1527     return E_NOTIMPL;
1528 }
1529
1530 #undef HTMLWINDOW3_THIS
1531
1532 static const IHTMLWindow3Vtbl HTMLWindow3Vtbl = {
1533     HTMLWindow3_QueryInterface,
1534     HTMLWindow3_AddRef,
1535     HTMLWindow3_Release,
1536     HTMLWindow3_GetTypeInfoCount,
1537     HTMLWindow3_GetTypeInfo,
1538     HTMLWindow3_GetIDsOfNames,
1539     HTMLWindow3_Invoke,
1540     HTMLWindow3_get_screenLeft,
1541     HTMLWindow3_get_screenTop,
1542     HTMLWindow3_attachEvent,
1543     HTMLWindow3_detachEvent,
1544     HTMLWindow3_setTimeout,
1545     HTMLWindow3_setInterval,
1546     HTMLWindow3_print,
1547     HTMLWindow3_put_onbeforeprint,
1548     HTMLWindow3_get_onbeforeprint,
1549     HTMLWindow3_put_onafterprint,
1550     HTMLWindow3_get_onafterprint,
1551     HTMLWindow3_get_clipboardData,
1552     HTMLWindow3_showModelessDialog
1553 };
1554
1555 #define HTMLWINDOW4_THIS(iface) DEFINE_THIS(HTMLWindow, HTMLWindow4, iface)
1556
1557 static HRESULT WINAPI HTMLWindow4_QueryInterface(IHTMLWindow4 *iface, REFIID riid, void **ppv)
1558 {
1559     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1560
1561     return IHTMLWindow2_QueryInterface(HTMLWINDOW2(This), riid, ppv);
1562 }
1563
1564 static ULONG WINAPI HTMLWindow4_AddRef(IHTMLWindow4 *iface)
1565 {
1566     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1567
1568     return IHTMLWindow2_AddRef(HTMLWINDOW2(This));
1569 }
1570
1571 static ULONG WINAPI HTMLWindow4_Release(IHTMLWindow4 *iface)
1572 {
1573     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1574
1575     return IHTMLWindow2_Release(HTMLWINDOW2(This));
1576 }
1577
1578 static HRESULT WINAPI HTMLWindow4_GetTypeInfoCount(IHTMLWindow4 *iface, UINT *pctinfo)
1579 {
1580     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1581
1582     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo);
1583 }
1584
1585 static HRESULT WINAPI HTMLWindow4_GetTypeInfo(IHTMLWindow4 *iface, UINT iTInfo,
1586                                               LCID lcid, ITypeInfo **ppTInfo)
1587 {
1588     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1589
1590     return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo);
1591 }
1592
1593 static HRESULT WINAPI HTMLWindow4_GetIDsOfNames(IHTMLWindow4 *iface, REFIID riid,
1594                                                 LPOLESTR *rgszNames, UINT cNames,
1595                                                 LCID lcid, DISPID *rgDispId)
1596 {
1597     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1598
1599     return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId);
1600 }
1601
1602 static HRESULT WINAPI HTMLWindow4_Invoke(IHTMLWindow4 *iface, DISPID dispIdMember,
1603                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1604                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1605 {
1606     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1607
1608     return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams,
1609             pVarResult, pExcepInfo, puArgErr);
1610 }
1611
1612 static HRESULT WINAPI HTMLWindow4_createPopup(IHTMLWindow4 *iface, VARIANT *varArgIn,
1613                             IDispatch **ppPopup)
1614 {
1615     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1616     FIXME("(%p)->(%p %p)\n", This, varArgIn, ppPopup);
1617     return E_NOTIMPL;
1618 }
1619
1620 static HRESULT WINAPI HTMLWindow4_get_frameElement(IHTMLWindow4 *iface, IHTMLFrameBase **p)
1621 {
1622     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1623     TRACE("(%p)->(%p)\n", This, p);
1624
1625     if(This->frame_element) {
1626         *p = HTMLFRAMEBASE(This->frame_element);
1627         IHTMLFrameBase_AddRef(*p);
1628     }else
1629         *p = NULL;
1630
1631     return S_OK;
1632 }
1633
1634 #undef HTMLWINDOW4_THIS
1635
1636 static const IHTMLWindow4Vtbl HTMLWindow4Vtbl = {
1637     HTMLWindow4_QueryInterface,
1638     HTMLWindow4_AddRef,
1639     HTMLWindow4_Release,
1640     HTMLWindow4_GetTypeInfoCount,
1641     HTMLWindow4_GetTypeInfo,
1642     HTMLWindow4_GetIDsOfNames,
1643     HTMLWindow4_Invoke,
1644     HTMLWindow4_createPopup,
1645     HTMLWindow4_get_frameElement
1646 };
1647
1648 #define HTMLPRIVWINDOW_THIS(iface) DEFINE_THIS(HTMLWindow, IHTMLPrivateWindow, iface)
1649
1650 static HRESULT WINAPI HTMLPrivateWindow_QueryInterface(IHTMLPrivateWindow *iface, REFIID riid, void **ppv)
1651 {
1652     HTMLWindow *This = HTMLPRIVWINDOW_THIS(iface);
1653
1654     return IHTMLWindow2_QueryInterface(HTMLWINDOW2(This), riid, ppv);
1655 }
1656
1657 static ULONG WINAPI HTMLPrivateWindow_AddRef(IHTMLPrivateWindow *iface)
1658 {
1659     HTMLWindow *This = HTMLPRIVWINDOW_THIS(iface);
1660
1661     return IHTMLWindow2_AddRef(HTMLWINDOW2(This));
1662 }
1663
1664 static ULONG WINAPI HTMLPrivateWindow_Release(IHTMLPrivateWindow *iface)
1665 {
1666     HTMLWindow *This = HTMLPRIVWINDOW_THIS(iface);
1667
1668     return IHTMLWindow2_Release(HTMLWINDOW2(This));
1669 }
1670
1671 static HRESULT WINAPI HTMLPrivateWindow_SuperNavigate(IHTMLPrivateWindow *iface, BSTR url, BSTR arg2, BSTR arg3,
1672         BSTR arg4, VARIANT *post_data_var, VARIANT *headers_var, ULONG flags)
1673 {
1674     HTMLWindow *This = HTMLPRIVWINDOW_THIS(iface);
1675     FIXME("(%p)->(%s %s %s %s %s %s %x)\n", This, debugstr_w(url), debugstr_w(arg2), debugstr_w(arg3),
1676           debugstr_w(arg4), debugstr_variant(post_data_var), debugstr_variant(headers_var), flags);
1677     return E_NOTIMPL;
1678 }
1679
1680 static HRESULT WINAPI HTMLPrivateWindow_GetPendingUrl(IHTMLPrivateWindow *iface, BSTR *url)
1681 {
1682     HTMLWindow *This = HTMLPRIVWINDOW_THIS(iface);
1683     FIXME("(%p)->(%p)\n", This, url);
1684     return E_NOTIMPL;
1685 }
1686
1687 static HRESULT WINAPI HTMLPrivateWindow_SetPICSTarget(IHTMLPrivateWindow *iface, IOleCommandTarget *cmdtrg)
1688 {
1689     HTMLWindow *This = HTMLPRIVWINDOW_THIS(iface);
1690     FIXME("(%p)->(%p)\n", This, cmdtrg);
1691     return E_NOTIMPL;
1692 }
1693
1694 static HRESULT WINAPI HTMLPrivateWindow_PICSComplete(IHTMLPrivateWindow *iface, int arg)
1695 {
1696     HTMLWindow *This = HTMLPRIVWINDOW_THIS(iface);
1697     FIXME("(%p)->(%x)\n", This, arg);
1698     return E_NOTIMPL;
1699 }
1700
1701 static HRESULT WINAPI HTMLPrivateWindow_FindWindowByName(IHTMLPrivateWindow *iface, LPCWSTR name, IHTMLWindow2 **ret)
1702 {
1703     HTMLWindow *This = HTMLPRIVWINDOW_THIS(iface);
1704     FIXME("(%p)->(%s %p)\n", This, debugstr_w(name), ret);
1705     return E_NOTIMPL;
1706 }
1707
1708 static HRESULT WINAPI HTMLPrivateWindow_GetAddressBar(IHTMLPrivateWindow *iface, BSTR *url)
1709 {
1710     HTMLWindow *This = HTMLPRIVWINDOW_THIS(iface);
1711     FIXME("(%p)->(%p)\n", This, url);
1712     return E_NOTIMPL;
1713 }
1714
1715 #undef HTMLPRIVWINDOW_THIS
1716
1717 static const IHTMLPrivateWindowVtbl HTMLPrivateWindowVtbl = {
1718     HTMLPrivateWindow_QueryInterface,
1719     HTMLPrivateWindow_AddRef,
1720     HTMLPrivateWindow_Release,
1721     HTMLPrivateWindow_SuperNavigate,
1722     HTMLPrivateWindow_GetPendingUrl,
1723     HTMLPrivateWindow_SetPICSTarget,
1724     HTMLPrivateWindow_PICSComplete,
1725     HTMLPrivateWindow_FindWindowByName,
1726     HTMLPrivateWindow_GetAddressBar
1727 };
1728
1729 #define DISPEX_THIS(iface) DEFINE_THIS(HTMLWindow, IDispatchEx, iface)
1730
1731 static HRESULT WINAPI WindowDispEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
1732 {
1733     HTMLWindow *This = DISPEX_THIS(iface);
1734
1735     return IHTMLWindow2_QueryInterface(HTMLWINDOW2(This), riid, ppv);
1736 }
1737
1738 static ULONG WINAPI WindowDispEx_AddRef(IDispatchEx *iface)
1739 {
1740     HTMLWindow *This = DISPEX_THIS(iface);
1741
1742     return IHTMLWindow2_AddRef(HTMLWINDOW2(This));
1743 }
1744
1745 static ULONG WINAPI WindowDispEx_Release(IDispatchEx *iface)
1746 {
1747     HTMLWindow *This = DISPEX_THIS(iface);
1748
1749     return IHTMLWindow2_Release(HTMLWINDOW2(This));
1750 }
1751
1752 static HRESULT WINAPI WindowDispEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
1753 {
1754     HTMLWindow *This = DISPEX_THIS(iface);
1755
1756     TRACE("(%p)->(%p)\n", This, pctinfo);
1757
1758     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo);
1759 }
1760
1761 static HRESULT WINAPI WindowDispEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
1762                                                LCID lcid, ITypeInfo **ppTInfo)
1763 {
1764     HTMLWindow *This = DISPEX_THIS(iface);
1765
1766     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1767
1768     return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo);
1769 }
1770
1771 static HRESULT WINAPI WindowDispEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
1772                                                  LPOLESTR *rgszNames, UINT cNames,
1773                                                  LCID lcid, DISPID *rgDispId)
1774 {
1775     HTMLWindow *This = DISPEX_THIS(iface);
1776     UINT i;
1777     HRESULT hres;
1778
1779     WARN("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1780           lcid, rgDispId);
1781
1782     for(i=0; i < cNames; i++) {
1783         /* We shouldn't use script's IDispatchEx here, so we shouldn't use GetDispID */
1784         hres = IDispatchEx_GetDispID(DISPATCHEX(This), rgszNames[i], 0, rgDispId+i);
1785         if(FAILED(hres))
1786             return hres;
1787     }
1788
1789     return S_OK;
1790 }
1791
1792 static HRESULT WINAPI WindowDispEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
1793                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1794                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1795 {
1796     HTMLWindow *This = DISPEX_THIS(iface);
1797
1798     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1799           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1800
1801     /* FIXME: Use script dispatch */
1802
1803     return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, wFlags, pDispParams,
1804                               pVarResult, pExcepInfo, puArgErr);
1805 }
1806
1807 static global_prop_t *alloc_global_prop(HTMLWindow *This, global_prop_type_t type, BSTR name)
1808 {
1809     if(This->global_prop_cnt == This->global_prop_size) {
1810         global_prop_t *new_props;
1811         DWORD new_size;
1812
1813         if(This->global_props) {
1814             new_size = This->global_prop_size*2;
1815             new_props = heap_realloc(This->global_props, new_size*sizeof(global_prop_t));
1816         }else {
1817             new_size = 16;
1818             new_props = heap_alloc(new_size*sizeof(global_prop_t));
1819         }
1820         if(!new_props)
1821             return NULL;
1822         This->global_props = new_props;
1823         This->global_prop_size = new_size;
1824     }
1825
1826     This->global_props[This->global_prop_cnt].name = heap_strdupW(name);
1827     if(!This->global_props[This->global_prop_cnt].name)
1828         return NULL;
1829
1830     This->global_props[This->global_prop_cnt].type = type;
1831     return This->global_props + This->global_prop_cnt++;
1832 }
1833
1834 static inline DWORD prop_to_dispid(HTMLWindow *This, global_prop_t *prop)
1835 {
1836     return MSHTML_DISPID_CUSTOM_MIN + (prop-This->global_props);
1837 }
1838
1839 HRESULT search_window_props(HTMLWindow *This, BSTR bstrName, DWORD grfdex, DISPID *pid)
1840 {
1841     DWORD i;
1842     ScriptHost *script_host;
1843     DISPID id;
1844
1845     for(i=0; i < This->global_prop_cnt; i++) {
1846         /* FIXME: case sensitivity */
1847         if(!strcmpW(This->global_props[i].name, bstrName)) {
1848             *pid = MSHTML_DISPID_CUSTOM_MIN+i;
1849             return S_OK;
1850         }
1851     }
1852
1853     if(find_global_prop(This, bstrName, grfdex, &script_host, &id)) {
1854         global_prop_t *prop;
1855
1856         prop = alloc_global_prop(This, GLOBAL_SCRIPTVAR, bstrName);
1857         if(!prop)
1858             return E_OUTOFMEMORY;
1859
1860         prop->script_host = script_host;
1861         prop->id = id;
1862
1863         *pid = prop_to_dispid(This, prop);
1864         return S_OK;
1865     }
1866
1867     return DISP_E_UNKNOWNNAME;
1868 }
1869
1870 static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
1871 {
1872     HTMLWindow *This = DISPEX_THIS(iface);
1873     HRESULT hres;
1874
1875     TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
1876
1877     hres = search_window_props(This, bstrName, grfdex, pid);
1878     if(hres != DISP_E_UNKNOWNNAME)
1879         return hres;
1880
1881     hres = IDispatchEx_GetDispID(DISPATCHEX(&This->dispex), bstrName, grfdex, pid);
1882     if(hres != DISP_E_UNKNOWNNAME)
1883         return hres;
1884
1885     if(This->doc) {
1886         global_prop_t *prop;
1887         IHTMLElement *elem;
1888
1889         hres = IHTMLDocument3_getElementById(HTMLDOC3(&This->doc->basedoc), bstrName, &elem);
1890         if(SUCCEEDED(hres) && elem) {
1891             IHTMLElement_Release(elem);
1892
1893             prop = alloc_global_prop(This, GLOBAL_ELEMENTVAR, bstrName);
1894             if(!prop)
1895                 return E_OUTOFMEMORY;
1896
1897             *pid = prop_to_dispid(This, prop);
1898             return S_OK;
1899         }
1900     }
1901
1902     return DISP_E_UNKNOWNNAME;
1903 }
1904
1905 static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1906         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1907 {
1908     HTMLWindow *This = DISPEX_THIS(iface);
1909
1910     TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1911
1912     if(id == DISPID_IHTMLWINDOW2_LOCATION && (wFlags & DISPATCH_PROPERTYPUT)) {
1913         HTMLLocation *location;
1914         HRESULT hres;
1915
1916         TRACE("forwarding to location.href\n");
1917
1918         hres = get_location(This, &location);
1919         if(FAILED(hres))
1920             return hres;
1921
1922         hres = IDispatchEx_InvokeEx(DISPATCHEX(&location->dispex), DISPID_VALUE, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1923         IHTMLLocation_Release(HTMLLOCATION(location));
1924         return hres;
1925     }
1926
1927     return IDispatchEx_InvokeEx(DISPATCHEX(&This->dispex), id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1928 }
1929
1930 static HRESULT WINAPI WindowDispEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
1931 {
1932     HTMLWindow *This = DISPEX_THIS(iface);
1933
1934     TRACE("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex);
1935
1936     return IDispatchEx_DeleteMemberByName(DISPATCHEX(&This->dispex), bstrName, grfdex);
1937 }
1938
1939 static HRESULT WINAPI WindowDispEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
1940 {
1941     HTMLWindow *This = DISPEX_THIS(iface);
1942
1943     TRACE("(%p)->(%x)\n", This, id);
1944
1945     return IDispatchEx_DeleteMemberByDispID(DISPATCHEX(&This->dispex), id);
1946 }
1947
1948 static HRESULT WINAPI WindowDispEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
1949 {
1950     HTMLWindow *This = DISPEX_THIS(iface);
1951
1952     TRACE("(%p)->(%x %x %p)\n", This, id, grfdexFetch, pgrfdex);
1953
1954     return IDispatchEx_GetMemberProperties(DISPATCHEX(&This->dispex), id, grfdexFetch, pgrfdex);
1955 }
1956
1957 static HRESULT WINAPI WindowDispEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
1958 {
1959     HTMLWindow *This = DISPEX_THIS(iface);
1960
1961     TRACE("(%p)->(%x %p)\n", This, id, pbstrName);
1962
1963     return IDispatchEx_GetMemberName(DISPATCHEX(&This->dispex), id, pbstrName);
1964 }
1965
1966 static HRESULT WINAPI WindowDispEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
1967 {
1968     HTMLWindow *This = DISPEX_THIS(iface);
1969
1970     TRACE("(%p)->(%x %x %p)\n", This, grfdex, id, pid);
1971
1972     return IDispatchEx_GetNextDispID(DISPATCHEX(&This->dispex), grfdex, id, pid);
1973 }
1974
1975 static HRESULT WINAPI WindowDispEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
1976 {
1977     HTMLWindow *This = DISPEX_THIS(iface);
1978
1979     TRACE("(%p)->(%p)\n", This, ppunk);
1980
1981     *ppunk = NULL;
1982     return S_OK;
1983 }
1984
1985 #undef DISPEX_THIS
1986
1987 static const IDispatchExVtbl WindowDispExVtbl = {
1988     WindowDispEx_QueryInterface,
1989     WindowDispEx_AddRef,
1990     WindowDispEx_Release,
1991     WindowDispEx_GetTypeInfoCount,
1992     WindowDispEx_GetTypeInfo,
1993     WindowDispEx_GetIDsOfNames,
1994     WindowDispEx_Invoke,
1995     WindowDispEx_GetDispID,
1996     WindowDispEx_InvokeEx,
1997     WindowDispEx_DeleteMemberByName,
1998     WindowDispEx_DeleteMemberByDispID,
1999     WindowDispEx_GetMemberProperties,
2000     WindowDispEx_GetMemberName,
2001     WindowDispEx_GetNextDispID,
2002     WindowDispEx_GetNameSpaceParent
2003 };
2004
2005 static const tid_t HTMLWindow_iface_tids[] = {
2006     IHTMLWindow2_tid,
2007     IHTMLWindow3_tid,
2008     IHTMLWindow4_tid,
2009     0
2010 };
2011
2012 static const dispex_static_data_vtbl_t HTMLWindow_dispex_vtbl = {
2013     NULL,
2014     NULL,
2015     HTMLWindow_invoke
2016 };
2017
2018 static dispex_static_data_t HTMLWindow_dispex = {
2019     &HTMLWindow_dispex_vtbl,
2020     DispHTMLWindow2_tid,
2021     NULL,
2022     HTMLWindow_iface_tids
2023 };
2024
2025 HRESULT HTMLWindow_Create(HTMLDocumentObj *doc_obj, nsIDOMWindow *nswindow, HTMLWindow *parent, HTMLWindow **ret)
2026 {
2027     HTMLWindow *window;
2028
2029     window = heap_alloc_zero(sizeof(HTMLWindow));
2030     if(!window)
2031         return E_OUTOFMEMORY;
2032
2033     window->window_ref = heap_alloc(sizeof(windowref_t));
2034     if(!window->window_ref) {
2035         heap_free(window);
2036         return E_OUTOFMEMORY;
2037     }
2038
2039     window->lpHTMLWindow2Vtbl = &HTMLWindow2Vtbl;
2040     window->lpHTMLWindow3Vtbl = &HTMLWindow3Vtbl;
2041     window->lpHTMLWindow4Vtbl = &HTMLWindow4Vtbl;
2042     window->lpIHTMLPrivateWindowVtbl = &HTMLPrivateWindowVtbl;
2043     window->lpIDispatchExVtbl = &WindowDispExVtbl;
2044     window->ref = 1;
2045     window->doc_obj = doc_obj;
2046
2047     window->window_ref->window = window;
2048     window->window_ref->ref = 1;
2049
2050     init_dispex(&window->dispex, (IUnknown*)HTMLWINDOW2(window), &HTMLWindow_dispex);
2051
2052     if(nswindow) {
2053         nsIDOMWindow_AddRef(nswindow);
2054         window->nswindow = nswindow;
2055     }
2056
2057     window->scriptmode = parent ? parent->scriptmode : SCRIPTMODE_GECKO;
2058     window->readystate = READYSTATE_UNINITIALIZED;
2059     list_init(&window->script_hosts);
2060
2061     window->task_magic = get_task_target_magic();
2062     update_window_doc(window);
2063
2064     list_init(&window->children);
2065     list_add_head(&window_list, &window->entry);
2066
2067     if(parent) {
2068         IHTMLWindow2_AddRef(HTMLWINDOW2(window));
2069
2070         window->parent = parent;
2071         list_add_tail(&parent->children, &window->sibling_entry);
2072     }
2073
2074     *ret = window;
2075     return S_OK;
2076 }
2077
2078 void update_window_doc(HTMLWindow *window)
2079 {
2080     nsIDOMHTMLDocument *nshtmldoc;
2081     nsIDOMDocument *nsdoc;
2082     nsresult nsres;
2083
2084     nsres = nsIDOMWindow_GetDocument(window->nswindow, &nsdoc);
2085     if(NS_FAILED(nsres) || !nsdoc) {
2086         ERR("GetDocument failed: %08x\n", nsres);
2087         return;
2088     }
2089
2090     nsres = nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMHTMLDocument, (void**)&nshtmldoc);
2091     nsIDOMDocument_Release(nsdoc);
2092     if(NS_FAILED(nsres)) {
2093         ERR("Could not get nsIDOMHTMLDocument iface: %08x\n", nsres);
2094         return;
2095     }
2096
2097     if(!window->doc || window->doc->nsdoc != nshtmldoc) {
2098         HTMLDocumentNode *doc;
2099         HRESULT hres;
2100
2101         hres = create_doc_from_nsdoc(nshtmldoc, window->doc_obj, window, &doc);
2102         if(SUCCEEDED(hres)) {
2103             window_set_docnode(window, doc);
2104             htmldoc_release(&doc->basedoc);
2105         }else {
2106             ERR("create_doc_from_nsdoc failed: %08x\n", hres);
2107         }
2108     }
2109
2110     nsIDOMHTMLDocument_Release(nshtmldoc);
2111 }
2112
2113 HTMLWindow *nswindow_to_window(const nsIDOMWindow *nswindow)
2114 {
2115     HTMLWindow *iter;
2116
2117     LIST_FOR_EACH_ENTRY(iter, &window_list, HTMLWindow, entry) {
2118         if(iter->nswindow == nswindow)
2119             return iter;
2120     }
2121
2122     return NULL;
2123 }