mshtml: Fixed handling channels without container and necko channel.
[wine] / dlls / shdocvw / webbrowser.c
1 /*
2  * Implementation of IWebBrowser interface for WebBrowser control
3  *
4  * Copyright 2001 John R. Sheets (for CodeWeavers)
5  * Copyright 2005 Jacek Caban
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "wine/debug.h"
23 #include "shdocvw.h"
24 #include "exdispid.h"
25
26 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
27
28 /**********************************************************************
29  * Implement the IWebBrowser interface
30  */
31
32 #define WEBBROWSER_THIS(iface) DEFINE_THIS(WebBrowser, WebBrowser2, iface)
33
34 static HRESULT WINAPI WebBrowser_QueryInterface(IWebBrowser2 *iface, REFIID riid, LPVOID *ppv)
35 {
36     WebBrowser *This = WEBBROWSER_THIS(iface);
37
38     if (ppv == NULL)
39         return E_POINTER;
40     *ppv = NULL;
41
42     if(IsEqualGUID(&IID_IUnknown, riid)) {
43         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
44         *ppv = WEBBROWSER(This);
45     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
46         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
47         *ppv = WEBBROWSER(This);
48     }else if(IsEqualGUID(&IID_IWebBrowser, riid)) {
49         TRACE("(%p)->(IID_IWebBrowser %p)\n", This, ppv);
50         *ppv = WEBBROWSER(This);
51     }else if(IsEqualGUID(&IID_IWebBrowserApp, riid)) {
52         TRACE("(%p)->(IID_IWebBrowserApp %p)\n", This, ppv);
53         *ppv = WEBBROWSER(This);
54     }else if(IsEqualGUID(&IID_IWebBrowser2, riid)) {
55         TRACE("(%p)->(IID_IWebBrowser2 %p)\n", This, ppv);
56         *ppv = WEBBROWSER(This);
57     }else if(IsEqualGUID(&IID_IOleObject, riid)) {
58         TRACE("(%p)->(IID_IOleObject %p)\n", This, ppv);
59         *ppv = OLEOBJ(This);
60     }else if(IsEqualGUID(&IID_IOleWindow, riid)) {
61         TRACE("(%p)->(IID_IOleWindow %p)\n", This, ppv);
62         *ppv = INPLACEOBJ(This);
63     }else if(IsEqualGUID (&IID_IOleInPlaceObject, riid)) {
64         TRACE("(%p)->(IID_IOleInPlaceObject %p)\n", This, ppv);
65         *ppv = INPLACEOBJ(This);
66     }else if(IsEqualGUID(&IID_IOleControl, riid)) {
67         TRACE("(%p)->(IID_IOleControl %p)\n", This, ppv);
68         *ppv = CONTROL(This);
69     }else if(IsEqualGUID(&IID_IPersist, riid)) {
70         TRACE("(%p)->(IID_IPersist %p)\n", This, ppv);
71         *ppv = PERSTORAGE(This);
72     }else if(IsEqualGUID(&IID_IPersistStorage, riid)) {
73         TRACE("(%p)->(IID_IPersistStorage %p)\n", This, ppv);
74         *ppv = PERSTORAGE(This);
75     }else if(IsEqualGUID(&IID_IPersistMemory, riid)) {
76         TRACE("(%p)->(IID_IPersistStorage %p)\n", This, ppv);
77         *ppv = PERMEMORY(This);
78     }else if(IsEqualGUID (&IID_IPersistStreamInit, riid)) {
79         TRACE("(%p)->(IID_IPersistStreamInit %p)\n", This, ppv);
80         *ppv = PERSTRINIT(This);
81     }else if(IsEqualGUID(&IID_IProvideClassInfo, riid)) {
82         TRACE("(%p)->(IID_IProvideClassInfo %p)\n", This, ppv);
83         *ppv = CLASSINFO(This);
84     }else if(IsEqualGUID(&IID_IProvideClassInfo2, riid)) {
85         TRACE("(%p)->(IID_IProvideClassInfo2 %p)\n", This, ppv);
86         *ppv = CLASSINFO(This);
87     }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
88         TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
89         *ppv = CONPTCONT(&This->doc_host.cps);
90     }else if(IsEqualGUID(&IID_IViewObject, riid)) {
91         TRACE("(%p)->(IID_IViewObject %p)\n", This, ppv);
92         *ppv = VIEWOBJ(This);
93     }else if(IsEqualGUID(&IID_IViewObject2, riid)) {
94         TRACE("(%p)->(IID_IViewObject2 %p)\n", This, ppv);
95         *ppv = VIEWOBJ2(This);
96     }else if(IsEqualGUID(&IID_IOleInPlaceActiveObject, riid)) {
97         TRACE("(%p)->(IID_IOleInPlaceActiveObject %p)\n", This, ppv);
98         *ppv = ACTIVEOBJ(This);
99     }else if(IsEqualGUID(&IID_IOleCommandTarget, riid)) {
100         TRACE("(%p)->(IID_IOleCommandTarget %p)\n", This, ppv);
101         *ppv = OLECMD(This);
102     }else if(IsEqualGUID(&IID_IHlinkFrame, riid)) {
103         TRACE("(%p)->(IID_IHlinkFrame %p)\n", This, ppv);
104         *ppv = HLINKFRAME(This);
105     }else if(IsEqualGUID(&IID_IQuickActivate, riid)) {
106         TRACE("(%p)->(IID_IQuickActivate %p) returning NULL\n", This, ppv);
107         return E_NOINTERFACE;
108     }else if(IsEqualGUID(&IID_IRunnableObject, riid)) {
109         TRACE("(%p)->(IID_IRunnableObject %p) returning NULL\n", This, ppv);
110         return E_NOINTERFACE;
111     }
112
113     if(*ppv) {
114         IUnknown_AddRef((IUnknown*)*ppv);
115         return S_OK;
116     }
117
118     FIXME("(%p)->(%s %p) interface not supported\n", This, debugstr_guid(riid), ppv);
119     return E_NOINTERFACE;
120 }
121
122 static ULONG WINAPI WebBrowser_AddRef(IWebBrowser2 *iface)
123 {
124     WebBrowser *This = WEBBROWSER_THIS(iface);
125     LONG ref = InterlockedIncrement(&This->ref);
126     TRACE("(%p) ref=%d\n", This, ref);
127     return ref;
128 }
129
130 static ULONG WINAPI WebBrowser_Release(IWebBrowser2 *iface)
131 {
132     WebBrowser *This = WEBBROWSER_THIS(iface);
133     LONG ref = InterlockedDecrement(&This->ref);
134
135     TRACE("(%p) ref=%d\n", This, ref);
136
137     if(!ref) {
138         if(This->doc_host.document)
139             IUnknown_Release(This->doc_host.document);
140
141         DocHost_Release(&This->doc_host);
142
143         WebBrowser_OleObject_Destroy(This);
144
145         shdocvw_free(This);
146         SHDOCVW_UnlockModule();
147     }
148
149     return ref;
150 }
151
152 /* IDispatch methods */
153 static HRESULT WINAPI WebBrowser_GetTypeInfoCount(IWebBrowser2 *iface, UINT *pctinfo)
154 {
155     WebBrowser *This = WEBBROWSER_THIS(iface);
156     FIXME("(%p)->(%p)\n", This, pctinfo);
157     return E_NOTIMPL;
158 }
159
160 static HRESULT WINAPI WebBrowser_GetTypeInfo(IWebBrowser2 *iface, UINT iTInfo, LCID lcid,
161                                      LPTYPEINFO *ppTInfo)
162 {
163     WebBrowser *This = WEBBROWSER_THIS(iface);
164     FIXME("(%p)->(%d %d %p)\n", This, iTInfo, lcid, ppTInfo);
165     return E_NOTIMPL;
166 }
167
168 static HRESULT WINAPI WebBrowser_GetIDsOfNames(IWebBrowser2 *iface, REFIID riid,
169                                        LPOLESTR *rgszNames, UINT cNames,
170                                        LCID lcid, DISPID *rgDispId)
171 {
172     WebBrowser *This = WEBBROWSER_THIS(iface);
173     FIXME("(%p)->(%s %p %d %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
174             lcid, rgDispId);
175     return E_NOTIMPL;
176 }
177
178 static HRESULT WINAPI WebBrowser_Invoke(IWebBrowser2 *iface, DISPID dispIdMember,
179                                 REFIID riid, LCID lcid, WORD wFlags,
180                                 DISPPARAMS *pDispParams, VARIANT *pVarResult,
181                                 EXCEPINFO *pExepInfo, UINT *puArgErr)
182 {
183     WebBrowser *This = WEBBROWSER_THIS(iface);
184     ITypeInfo *typeinfo;
185     HRESULT hres;
186
187     TRACE("(%p)->(%d %s %d %08x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
188             lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
189
190     hres = get_typeinfo(&typeinfo);
191     if(FAILED(hres))
192         return hres;
193
194     return ITypeInfo_Invoke(typeinfo, WEBBROWSER2(This), dispIdMember, wFlags, pDispParams,
195                             pVarResult, pExepInfo, puArgErr);
196 }
197
198 /* IWebBrowser methods */
199 static HRESULT WINAPI WebBrowser_GoBack(IWebBrowser2 *iface)
200 {
201     WebBrowser *This = WEBBROWSER_THIS(iface);
202     FIXME("(%p)\n", This);
203     return E_NOTIMPL;
204 }
205
206 static HRESULT WINAPI WebBrowser_GoForward(IWebBrowser2 *iface)
207 {
208     WebBrowser *This = WEBBROWSER_THIS(iface);
209     FIXME("(%p)\n", This);
210     return E_NOTIMPL;
211 }
212
213 static HRESULT WINAPI WebBrowser_GoHome(IWebBrowser2 *iface)
214 {
215     WebBrowser *This = WEBBROWSER_THIS(iface);
216     TRACE("(%p)\n", This);
217     return go_home(&This->doc_host);
218 }
219
220 static HRESULT WINAPI WebBrowser_GoSearch(IWebBrowser2 *iface)
221 {
222     WebBrowser *This = WEBBROWSER_THIS(iface);
223     FIXME("(%p)\n", This);
224     return E_NOTIMPL;
225 }
226
227 static HRESULT WINAPI WebBrowser_Navigate(IWebBrowser2 *iface, BSTR szUrl,
228                                   VARIANT *Flags, VARIANT *TargetFrameName,
229                                   VARIANT *PostData, VARIANT *Headers)
230 {
231     WebBrowser *This = WEBBROWSER_THIS(iface);
232
233     TRACE("(%p)->(%s %p %p %p %p)\n", This, debugstr_w(szUrl), Flags, TargetFrameName,
234           PostData, Headers);
235
236     return navigate_url(&This->doc_host, szUrl, Flags, TargetFrameName, PostData, Headers);
237 }
238
239 static HRESULT WINAPI WebBrowser_Refresh(IWebBrowser2 *iface)
240 {
241     WebBrowser *This = WEBBROWSER_THIS(iface);
242     FIXME("(%p)\n", This);
243     return E_NOTIMPL;
244 }
245
246 static HRESULT WINAPI WebBrowser_Refresh2(IWebBrowser2 *iface, VARIANT *Level)
247 {
248     WebBrowser *This = WEBBROWSER_THIS(iface);
249     FIXME("(%p)->(%p)\n", This, Level);
250     return E_NOTIMPL;
251 }
252
253 static HRESULT WINAPI WebBrowser_Stop(IWebBrowser2 *iface)
254 {
255     WebBrowser *This = WEBBROWSER_THIS(iface);
256     FIXME("(%p)\n", This);
257     return E_NOTIMPL;
258 }
259
260 static HRESULT WINAPI WebBrowser_get_Application(IWebBrowser2 *iface, IDispatch **ppDisp)
261 {
262     WebBrowser *This = WEBBROWSER_THIS(iface);
263     FIXME("(%p)->(%p)\n", This, ppDisp);
264     return E_NOTIMPL;
265 }
266
267 static HRESULT WINAPI WebBrowser_get_Parent(IWebBrowser2 *iface, IDispatch **ppDisp)
268 {
269     WebBrowser *This = WEBBROWSER_THIS(iface);
270     FIXME("(%p)->(%p)\n", This, ppDisp);
271     return E_NOTIMPL;
272 }
273
274 static HRESULT WINAPI WebBrowser_get_Container(IWebBrowser2 *iface, IDispatch **ppDisp)
275 {
276     WebBrowser *This = WEBBROWSER_THIS(iface);
277     FIXME("(%p)->(%p)\n", This, ppDisp);
278     return E_NOTIMPL;
279 }
280
281 static HRESULT WINAPI WebBrowser_get_Document(IWebBrowser2 *iface, IDispatch **ppDisp)
282 {
283     WebBrowser *This = WEBBROWSER_THIS(iface);
284
285     TRACE("(%p)->(%p)\n", This, ppDisp);
286
287     *ppDisp = NULL;
288     if(This->doc_host.document)
289         IUnknown_QueryInterface(This->doc_host.document, &IID_IDispatch, (void**)ppDisp);
290
291     return S_OK;
292 }
293
294 static HRESULT WINAPI WebBrowser_get_TopLevelContainer(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
295 {
296     WebBrowser *This = WEBBROWSER_THIS(iface);
297     FIXME("(%p)->(%p)\n", This, pBool);
298     return E_NOTIMPL;
299 }
300
301 static HRESULT WINAPI WebBrowser_get_Type(IWebBrowser2 *iface, BSTR *Type)
302 {
303     WebBrowser *This = WEBBROWSER_THIS(iface);
304     FIXME("(%p)->(%p)\n", This, Type);
305     return E_NOTIMPL;
306 }
307
308 static HRESULT WINAPI WebBrowser_get_Left(IWebBrowser2 *iface, long *pl)
309 {
310     WebBrowser *This = WEBBROWSER_THIS(iface);
311
312     TRACE("(%p)->(%p)\n", This, pl);
313
314     *pl = This->pos_rect.left;
315     return S_OK;
316 }
317
318 static HRESULT WINAPI WebBrowser_put_Left(IWebBrowser2 *iface, long Left)
319 {
320     WebBrowser *This = WEBBROWSER_THIS(iface);
321     RECT rect;
322
323     TRACE("(%p)->(%ld)\n", This, Left);
324
325     if(!This->inplace)
326         return E_UNEXPECTED;
327
328     memcpy(&rect, &This->pos_rect, sizeof(RECT));
329     rect.left = Left;
330
331     /* We don't really change the window position here.
332      * We just notify the embedder that he should do so. */
333     return IOleInPlaceSite_OnPosRectChange(This->inplace, &rect);
334 }
335
336 static HRESULT WINAPI WebBrowser_get_Top(IWebBrowser2 *iface, long *pl)
337 {
338     WebBrowser *This = WEBBROWSER_THIS(iface);
339
340     TRACE("(%p)->(%p)\n", This, pl);
341
342     *pl = This->pos_rect.top;
343     return S_OK;
344 }
345
346 static HRESULT WINAPI WebBrowser_put_Top(IWebBrowser2 *iface, long Top)
347 {
348     WebBrowser *This = WEBBROWSER_THIS(iface);
349     RECT rect;
350
351     TRACE("(%p)->(%ld)\n", This, Top);
352
353     if(!This->inplace)
354         return E_UNEXPECTED;
355
356     memcpy(&rect, &This->pos_rect, sizeof(RECT));
357     rect.top = Top;
358
359     /* We don't really change the window position here.
360      * We just notify the embedder that he should do so. */
361     return IOleInPlaceSite_OnPosRectChange(This->inplace, &rect);
362 }
363
364 static HRESULT WINAPI WebBrowser_get_Width(IWebBrowser2 *iface, long *pl)
365 {
366     WebBrowser *This = WEBBROWSER_THIS(iface);
367
368     TRACE("(%p)->(%p)\n", This, pl);
369
370     *pl = This->pos_rect.right - This->pos_rect.left;
371     return S_OK;
372 }
373
374 static HRESULT WINAPI WebBrowser_put_Width(IWebBrowser2 *iface, long Width)
375 {
376     WebBrowser *This = WEBBROWSER_THIS(iface);
377     RECT rect;
378
379     TRACE("(%p)->(%ld)\n", This, Width);
380
381     if(!This->inplace)
382         return E_UNEXPECTED;
383
384     memcpy(&rect, &This->pos_rect, sizeof(RECT));
385     rect.right = rect.left+Width;
386  
387     /* We don't really change the window size here.
388      * We just notify the embedder that he should do so. */
389    return IOleInPlaceSite_OnPosRectChange(This->inplace, &rect);
390 }
391
392 static HRESULT WINAPI WebBrowser_get_Height(IWebBrowser2 *iface, long *pl)
393 {
394     WebBrowser *This = WEBBROWSER_THIS(iface);
395
396     TRACE("(%p)->(%p)\n", This, pl);
397
398     *pl = This->pos_rect.bottom - This->pos_rect.top;
399     return S_OK;
400 }
401
402 static HRESULT WINAPI WebBrowser_put_Height(IWebBrowser2 *iface, long Height)
403 {
404     WebBrowser *This = WEBBROWSER_THIS(iface);
405     RECT rect;
406
407     TRACE("(%p)->(%ld)\n", This, Height);
408
409     if(!This->inplace)
410         return E_UNEXPECTED;
411
412     memcpy(&rect, &This->pos_rect, sizeof(RECT));
413     rect.bottom = rect.top+Height;
414
415     /* We don't really change the window size here.
416      * We just notify the embedder that he should do so. */
417     return IOleInPlaceSite_OnPosRectChange(This->inplace, &rect);
418 }
419
420 static HRESULT WINAPI WebBrowser_get_LocationName(IWebBrowser2 *iface, BSTR *LocationName)
421 {
422     WebBrowser *This = WEBBROWSER_THIS(iface);
423     FIXME("(%p)->(%p)\n", This, LocationName);
424     return E_NOTIMPL;
425 }
426
427 static HRESULT WINAPI WebBrowser_get_LocationURL(IWebBrowser2 *iface, BSTR *LocationURL)
428 {
429     WebBrowser *This = WEBBROWSER_THIS(iface);
430
431     FIXME("(%p)->(%p)\n", This, LocationURL);
432
433     if(!This->doc_host.url) {
434         static const WCHAR null_char = 0;
435         *LocationURL = SysAllocString(&null_char);
436         return S_FALSE;
437     }
438
439     *LocationURL = SysAllocString(This->doc_host.url);
440     return S_OK;
441 }
442
443 static HRESULT WINAPI WebBrowser_get_Busy(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
444 {
445     WebBrowser *This = WEBBROWSER_THIS(iface);
446     FIXME("(%p)->(%p)\n", This, pBool);
447     return E_NOTIMPL;
448 }
449
450 static HRESULT WINAPI WebBrowser_Quit(IWebBrowser2 *iface)
451 {
452     WebBrowser *This = WEBBROWSER_THIS(iface);
453     FIXME("(%p)\n", This);
454     return E_NOTIMPL;
455 }
456
457 static HRESULT WINAPI WebBrowser_ClientToWindow(IWebBrowser2 *iface, int *pcx, int *pcy)
458 {
459     WebBrowser *This = WEBBROWSER_THIS(iface);
460     FIXME("(%p)->(%p %p)\n", This, pcx, pcy);
461     return E_NOTIMPL;
462 }
463
464 static HRESULT WINAPI WebBrowser_PutProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT vtValue)
465 {
466     WebBrowser *This = WEBBROWSER_THIS(iface);
467     FIXME("(%p)->(%s)\n", This, debugstr_w(szProperty));
468     return E_NOTIMPL;
469 }
470
471 static HRESULT WINAPI WebBrowser_GetProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT *pvtValue)
472 {
473     WebBrowser *This = WEBBROWSER_THIS(iface);
474     FIXME("(%p)->(%s %p)\n", This, debugstr_w(szProperty), pvtValue);
475     return E_NOTIMPL;
476 }
477
478 static HRESULT WINAPI WebBrowser_get_Name(IWebBrowser2 *iface, BSTR *Name)
479 {
480     WebBrowser *This = WEBBROWSER_THIS(iface);
481     FIXME("(%p)->(%p)\n", This, Name);
482     return E_NOTIMPL;
483 }
484
485 static HRESULT WINAPI WebBrowser_get_HWND(IWebBrowser2 *iface, long *pHWND)
486 {
487     WebBrowser *This = WEBBROWSER_THIS(iface);
488
489     TRACE("(%p)->(%p)\n", This, pHWND);
490
491     /* WebBrowser control never has a frame window (in opposition to InternetExplorer) */
492     *pHWND = 0;
493     return E_FAIL;
494 }
495
496 static HRESULT WINAPI WebBrowser_get_FullName(IWebBrowser2 *iface, BSTR *FullName)
497 {
498     WebBrowser *This = WEBBROWSER_THIS(iface);
499     FIXME("(%p)->(%p)\n", This, FullName);
500     return E_NOTIMPL;
501 }
502
503 static HRESULT WINAPI WebBrowser_get_Path(IWebBrowser2 *iface, BSTR *Path)
504 {
505     WebBrowser *This = WEBBROWSER_THIS(iface);
506     FIXME("(%p)->(%p)\n", This, Path);
507     return E_NOTIMPL;
508 }
509
510 static HRESULT WINAPI WebBrowser_get_Visible(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
511 {
512     WebBrowser *This = WEBBROWSER_THIS(iface);
513
514     TRACE("(%p)->(%p)\n", This, pBool);
515
516     *pBool = This->visible;
517     return S_OK;
518 }
519
520 static HRESULT WINAPI WebBrowser_put_Visible(IWebBrowser2 *iface, VARIANT_BOOL Value)
521 {
522     WebBrowser *This = WEBBROWSER_THIS(iface);
523     VARIANTARG arg;
524     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
525
526     TRACE("(%p)->(%x)\n", This, Value);
527
528     This->visible = Value;
529
530     V_VT(&arg) = VT_BOOL;
531     V_BOOL(&arg) = Value;
532     call_sink(This->doc_host.cps.wbe2, DISPID_ONVISIBLE, &dispparams);
533
534     return S_OK;
535 }
536
537 static HRESULT WINAPI WebBrowser_get_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
538 {
539     WebBrowser *This = WEBBROWSER_THIS(iface);
540
541     TRACE("(%p)->(%p)\n", This, pBool);
542
543     *pBool = This->status_bar;
544     return S_OK;
545 }
546
547 static HRESULT WINAPI WebBrowser_put_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
548 {
549     WebBrowser *This = WEBBROWSER_THIS(iface);
550     VARIANTARG arg;
551     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
552
553     TRACE("(%p)->(%x)\n", This, Value);
554
555     This->status_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;
556
557     /* In opposition to InternetExplorer, all we should do here is
558      * inform the embedder about the status bar change. */
559
560     V_VT(&arg) = VT_BOOL;
561     V_BOOL(&arg) = Value;
562     call_sink(This->doc_host.cps.wbe2, DISPID_ONSTATUSBAR, &dispparams);
563
564     return S_OK;
565 }
566
567 static HRESULT WINAPI WebBrowser_get_StatusText(IWebBrowser2 *iface, BSTR *StatusText)
568 {
569     WebBrowser *This = WEBBROWSER_THIS(iface);
570     FIXME("(%p)->(%p)\n", This, StatusText);
571     return E_NOTIMPL;
572 }
573
574 static HRESULT WINAPI WebBrowser_put_StatusText(IWebBrowser2 *iface, BSTR StatusText)
575 {
576     WebBrowser *This = WEBBROWSER_THIS(iface);
577     FIXME("(%p)->(%s)\n", This, debugstr_w(StatusText));
578     return E_NOTIMPL;
579 }
580
581 static HRESULT WINAPI WebBrowser_get_ToolBar(IWebBrowser2 *iface, int *Value)
582 {
583     WebBrowser *This = WEBBROWSER_THIS(iface);
584
585     TRACE("(%p)->(%p)\n", This, Value);
586
587     *Value = This->tool_bar;
588     return S_OK;
589 }
590
591 static HRESULT WINAPI WebBrowser_put_ToolBar(IWebBrowser2 *iface, int Value)
592 {
593     WebBrowser *This = WEBBROWSER_THIS(iface);
594     VARIANTARG arg;
595     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
596
597     TRACE("(%p)->(%x)\n", This, Value);
598
599     This->tool_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;
600
601     /* In opposition to InternetExplorer, all we should do here is
602      * inform the embedder about the tool bar change. */
603
604     V_VT(&arg) = VT_BOOL;
605     V_BOOL(&arg) = Value;
606     call_sink(This->doc_host.cps.wbe2, DISPID_ONTOOLBAR, &dispparams);
607
608     return S_OK;
609 }
610
611 static HRESULT WINAPI WebBrowser_get_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL *Value)
612 {
613     WebBrowser *This = WEBBROWSER_THIS(iface);
614
615     TRACE("(%p)->(%p)\n", This, Value);
616
617     *Value = This->menu_bar;
618     return S_OK;
619 }
620
621 static HRESULT WINAPI WebBrowser_put_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
622 {
623     WebBrowser *This = WEBBROWSER_THIS(iface);
624     VARIANTARG arg;
625     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
626
627     TRACE("(%p)->(%x)\n", This, Value);
628
629     This->menu_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;
630
631     /* In opposition to InternetExplorer, all we should do here is
632      * inform the embedder about the menu bar change. */
633
634     V_VT(&arg) = VT_BOOL;
635     V_BOOL(&arg) = Value;
636     call_sink(This->doc_host.cps.wbe2, DISPID_ONMENUBAR, &dispparams);
637
638     return S_OK;
639 }
640
641 static HRESULT WINAPI WebBrowser_get_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL *pbFullScreen)
642 {
643     WebBrowser *This = WEBBROWSER_THIS(iface);
644
645     TRACE("(%p)->(%p)\n", This, pbFullScreen);
646
647     *pbFullScreen = This->full_screen;
648     return S_OK;
649 }
650
651 static HRESULT WINAPI WebBrowser_put_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL bFullScreen)
652 {
653     WebBrowser *This = WEBBROWSER_THIS(iface);
654
655     TRACE("(%p)->(%x)\n", This, bFullScreen);
656
657     This->full_screen = bFullScreen ? VARIANT_TRUE : VARIANT_FALSE;
658     return S_OK;
659 }
660
661 static HRESULT WINAPI WebBrowser_Navigate2(IWebBrowser2 *iface, VARIANT *URL, VARIANT *Flags,
662         VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
663 {
664     WebBrowser *This = WEBBROWSER_THIS(iface);
665
666     TRACE("(%p)->(%p %p %p %p %p)\n", This, URL, Flags, TargetFrameName, PostData, Headers);
667
668     if(!This->client)
669         return E_FAIL;
670
671     if(!URL)
672         return S_OK;
673
674     if(V_VT(URL) != VT_BSTR) {
675         FIXME("Unsupported V_VT(URL) %d\n", V_VT(URL));
676         return E_INVALIDARG;
677     }
678
679     return navigate_url(&This->doc_host, V_BSTR(URL), Flags, TargetFrameName, PostData, Headers);
680 }
681
682 static HRESULT WINAPI WebBrowser_QueryStatusWB(IWebBrowser2 *iface, OLECMDID cmdID, OLECMDF *pcmdf)
683 {
684     WebBrowser *This = WEBBROWSER_THIS(iface);
685     FIXME("(%p)->(%d %p)\n", This, cmdID, pcmdf);
686     return E_NOTIMPL;
687 }
688
689 static HRESULT WINAPI WebBrowser_ExecWB(IWebBrowser2 *iface, OLECMDID cmdID,
690         OLECMDEXECOPT cmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
691 {
692     WebBrowser *This = WEBBROWSER_THIS(iface);
693     FIXME("(%p)->(%d %d %p %p)\n", This, cmdID, cmdexecopt, pvaIn, pvaOut);
694     return E_NOTIMPL;
695 }
696
697 static HRESULT WINAPI WebBrowser_ShowBrowserBar(IWebBrowser2 *iface, VARIANT *pvaClsid,
698         VARIANT *pvarShow, VARIANT *pvarSize)
699 {
700     WebBrowser *This = WEBBROWSER_THIS(iface);
701     FIXME("(%p)->(%p %p %p)\n", This, pvaClsid, pvarShow, pvarSize);
702     return E_NOTIMPL;
703 }
704
705 static HRESULT WINAPI WebBrowser_get_ReadyState(IWebBrowser2 *iface, READYSTATE *lpReadyState)
706 {
707     WebBrowser *This = WEBBROWSER_THIS(iface);
708     FIXME("(%p)->(%p)\n", This, lpReadyState);
709     return E_NOTIMPL;
710 }
711
712 static HRESULT WINAPI WebBrowser_get_Offline(IWebBrowser2 *iface, VARIANT_BOOL *pbOffline)
713 {
714     WebBrowser *This = WEBBROWSER_THIS(iface);
715
716     TRACE("(%p)->(%p)\n", This, pbOffline);
717
718     *pbOffline = This->doc_host.offline;
719     return S_OK;
720 }
721
722 static HRESULT WINAPI WebBrowser_put_Offline(IWebBrowser2 *iface, VARIANT_BOOL bOffline)
723 {
724     WebBrowser *This = WEBBROWSER_THIS(iface);
725
726     TRACE("(%p)->(%x)\n", This, bOffline);
727
728     This->doc_host.offline = bOffline ? VARIANT_TRUE : VARIANT_FALSE;
729     return S_OK;
730 }
731
732 static HRESULT WINAPI WebBrowser_get_Silent(IWebBrowser2 *iface, VARIANT_BOOL *pbSilent)
733 {
734     WebBrowser *This = WEBBROWSER_THIS(iface);
735
736     TRACE("(%p)->(%p)\n", This, pbSilent);
737
738     *pbSilent = This->doc_host.silent;
739     return S_OK;
740 }
741
742 static HRESULT WINAPI WebBrowser_put_Silent(IWebBrowser2 *iface, VARIANT_BOOL bSilent)
743 {
744     WebBrowser *This = WEBBROWSER_THIS(iface);
745
746     TRACE("(%p)->(%x)\n", This, bSilent);
747
748     This->doc_host.silent = bSilent ? VARIANT_TRUE : VARIANT_FALSE;
749     return S_OK;
750 }
751
752 static HRESULT WINAPI WebBrowser_get_RegisterAsBrowser(IWebBrowser2 *iface,
753         VARIANT_BOOL *pbRegister)
754 {
755     WebBrowser *This = WEBBROWSER_THIS(iface);
756     FIXME("(%p)->(%p)\n", This, pbRegister);
757     return E_NOTIMPL;
758 }
759
760 static HRESULT WINAPI WebBrowser_put_RegisterAsBrowser(IWebBrowser2 *iface,
761         VARIANT_BOOL bRegister)
762 {
763     WebBrowser *This = WEBBROWSER_THIS(iface);
764     FIXME("(%p)->(%x)\n", This, bRegister);
765     return E_NOTIMPL;
766 }
767
768 static HRESULT WINAPI WebBrowser_get_RegisterAsDropTarget(IWebBrowser2 *iface,
769         VARIANT_BOOL *pbRegister)
770 {
771     WebBrowser *This = WEBBROWSER_THIS(iface);
772     FIXME("(%p)->(%p)\n", This, pbRegister);
773     return E_NOTIMPL;
774 }
775
776 static HRESULT WINAPI WebBrowser_put_RegisterAsDropTarget(IWebBrowser2 *iface,
777         VARIANT_BOOL bRegister)
778 {
779     WebBrowser *This = WEBBROWSER_THIS(iface);
780     FIXME("(%p)->(%x)\n", This, bRegister);
781     return S_OK;
782 }
783
784 static HRESULT WINAPI WebBrowser_get_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL *pbRegister)
785 {
786     WebBrowser *This = WEBBROWSER_THIS(iface);
787     FIXME("(%p)->(%p)\n", This, pbRegister);
788     return E_NOTIMPL;
789 }
790
791 static HRESULT WINAPI WebBrowser_put_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL bRegister)
792 {
793     WebBrowser *This = WEBBROWSER_THIS(iface);
794     FIXME("(%p)->(%x)\n", This, bRegister);
795     return E_NOTIMPL;
796 }
797
798 static HRESULT WINAPI WebBrowser_get_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL *Value)
799 {
800     WebBrowser *This = WEBBROWSER_THIS(iface);
801
802     TRACE("(%p)->(%p)\n", This, Value);
803
804     *Value = This->address_bar;
805     return S_OK;
806 }
807
808 static HRESULT WINAPI WebBrowser_put_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
809 {
810     WebBrowser *This = WEBBROWSER_THIS(iface);
811     VARIANTARG arg;
812     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
813
814     TRACE("(%p)->(%x)\n", This, Value);
815
816     This->address_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;
817
818     /* In opposition to InternetExplorer, all we should do here is
819      * inform the embedder about the address bar change. */
820
821     V_VT(&arg) = VT_BOOL;
822     V_BOOL(&arg) = Value;
823     call_sink(This->doc_host.cps.wbe2, DISPID_ONADDRESSBAR, &dispparams);
824
825     return S_OK;
826 }
827
828 static HRESULT WINAPI WebBrowser_get_Resizable(IWebBrowser2 *iface, VARIANT_BOOL *Value)
829 {
830     WebBrowser *This = WEBBROWSER_THIS(iface);
831
832     TRACE("(%p)->(%p)\n", This, Value);
833
834     /* It's InternetExplorer object's method. We have nothing to do here. */
835     return E_NOTIMPL;
836 }
837
838 static HRESULT WINAPI WebBrowser_put_Resizable(IWebBrowser2 *iface, VARIANT_BOOL Value)
839 {
840     WebBrowser *This = WEBBROWSER_THIS(iface);
841
842     TRACE("(%p)->(%x)\n", This, Value);
843
844     /* It's InternetExplorer object's method. We have nothing to do here. */
845     return S_OK;
846 }
847
848 #undef WEBBROWSER_THIS
849
850 static const IWebBrowser2Vtbl WebBrowser2Vtbl =
851 {
852     WebBrowser_QueryInterface,
853     WebBrowser_AddRef,
854     WebBrowser_Release,
855     WebBrowser_GetTypeInfoCount,
856     WebBrowser_GetTypeInfo,
857     WebBrowser_GetIDsOfNames,
858     WebBrowser_Invoke,
859     WebBrowser_GoBack,
860     WebBrowser_GoForward,
861     WebBrowser_GoHome,
862     WebBrowser_GoSearch,
863     WebBrowser_Navigate,
864     WebBrowser_Refresh,
865     WebBrowser_Refresh2,
866     WebBrowser_Stop,
867     WebBrowser_get_Application,
868     WebBrowser_get_Parent,
869     WebBrowser_get_Container,
870     WebBrowser_get_Document,
871     WebBrowser_get_TopLevelContainer,
872     WebBrowser_get_Type,
873     WebBrowser_get_Left,
874     WebBrowser_put_Left,
875     WebBrowser_get_Top,
876     WebBrowser_put_Top,
877     WebBrowser_get_Width,
878     WebBrowser_put_Width,
879     WebBrowser_get_Height,
880     WebBrowser_put_Height,
881     WebBrowser_get_LocationName,
882     WebBrowser_get_LocationURL,
883     WebBrowser_get_Busy,
884     WebBrowser_Quit,
885     WebBrowser_ClientToWindow,
886     WebBrowser_PutProperty,
887     WebBrowser_GetProperty,
888     WebBrowser_get_Name,
889     WebBrowser_get_HWND,
890     WebBrowser_get_FullName,
891     WebBrowser_get_Path,
892     WebBrowser_get_Visible,
893     WebBrowser_put_Visible,
894     WebBrowser_get_StatusBar,
895     WebBrowser_put_StatusBar,
896     WebBrowser_get_StatusText,
897     WebBrowser_put_StatusText,
898     WebBrowser_get_ToolBar,
899     WebBrowser_put_ToolBar,
900     WebBrowser_get_MenuBar,
901     WebBrowser_put_MenuBar,
902     WebBrowser_get_FullScreen,
903     WebBrowser_put_FullScreen,
904     WebBrowser_Navigate2,
905     WebBrowser_QueryStatusWB,
906     WebBrowser_ExecWB,
907     WebBrowser_ShowBrowserBar,
908     WebBrowser_get_ReadyState,
909     WebBrowser_get_Offline,
910     WebBrowser_put_Offline,
911     WebBrowser_get_Silent,
912     WebBrowser_put_Silent,
913     WebBrowser_get_RegisterAsBrowser,
914     WebBrowser_put_RegisterAsBrowser,
915     WebBrowser_get_RegisterAsDropTarget,
916     WebBrowser_put_RegisterAsDropTarget,
917     WebBrowser_get_TheaterMode,
918     WebBrowser_put_TheaterMode,
919     WebBrowser_get_AddressBar,
920     WebBrowser_put_AddressBar,
921     WebBrowser_get_Resizable,
922     WebBrowser_put_Resizable
923 };
924
925 static HRESULT WebBrowser_Create(INT version, IUnknown *pOuter, REFIID riid, void **ppv)
926 {
927     WebBrowser *ret;
928     HRESULT hres;
929
930     TRACE("(%p %s %p) version=%d\n", pOuter, debugstr_guid(riid), ppv, version);
931
932     ret = shdocvw_alloc(sizeof(WebBrowser));
933
934     ret->lpWebBrowser2Vtbl = &WebBrowser2Vtbl;
935     ret->ref = 0;
936     ret->version = version;
937
938     DocHost_Init(&ret->doc_host, (IDispatch*)WEBBROWSER2(ret));
939
940     ret->visible = VARIANT_TRUE;
941     ret->menu_bar = VARIANT_TRUE;
942     ret->address_bar = VARIANT_TRUE;
943     ret->status_bar = VARIANT_TRUE;
944     ret->tool_bar = VARIANT_TRUE;
945     ret->full_screen = VARIANT_FALSE;
946
947     WebBrowser_OleObject_Init(ret);
948     WebBrowser_ViewObject_Init(ret);
949     WebBrowser_Persist_Init(ret);
950     WebBrowser_ClassInfo_Init(ret);
951     WebBrowser_HlinkFrame_Init(ret);
952
953     hres = IWebBrowser_QueryInterface(WEBBROWSER(ret), riid, ppv);
954     if(SUCCEEDED(hres)) {
955         SHDOCVW_LockModule();
956     }else {
957         shdocvw_free(ret);
958         return hres;
959     }
960
961     return hres;
962 }
963
964 HRESULT WebBrowserV1_Create(IUnknown *pOuter, REFIID riid, void **ppv)
965 {
966     return WebBrowser_Create(1, pOuter, riid, ppv);
967 }
968
969 HRESULT WebBrowserV2_Create(IUnknown *pOuter, REFIID riid, void **ppv)
970 {
971     return WebBrowser_Create(2, pOuter, riid, ppv);
972 }