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