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