ntdll: Allocate a console (without renderer) when starting a program from unix console.
[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 #include "mshtml.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
28
29 /**********************************************************************
30  * Implement the IWebBrowser interface
31  */
32
33 #define WEBBROWSER_THIS(iface) DEFINE_THIS(WebBrowser, WebBrowser2, iface)
34
35 static HRESULT WINAPI WebBrowser_QueryInterface(IWebBrowser2 *iface, REFIID riid, LPVOID *ppv)
36 {
37     WebBrowser *This = WEBBROWSER_THIS(iface);
38
39     if (ppv == NULL)
40         return E_POINTER;
41     *ppv = NULL;
42
43     if(IsEqualGUID(&IID_IUnknown, riid)) {
44         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
45         *ppv = WEBBROWSER(This);
46     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
47         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
48         *ppv = WEBBROWSER(This);
49     }else if(IsEqualGUID(&IID_IWebBrowser, riid)) {
50         TRACE("(%p)->(IID_IWebBrowser %p)\n", This, ppv);
51         *ppv = WEBBROWSER(This);
52     }else if(IsEqualGUID(&IID_IWebBrowserApp, riid)) {
53         TRACE("(%p)->(IID_IWebBrowserApp %p)\n", This, ppv);
54         *ppv = WEBBROWSER(This);
55     }else if(IsEqualGUID(&IID_IWebBrowser2, riid)) {
56         TRACE("(%p)->(IID_IWebBrowser2 %p)\n", This, ppv);
57         *ppv = WEBBROWSER(This);
58     }else if(IsEqualGUID(&IID_IOleObject, riid)) {
59         TRACE("(%p)->(IID_IOleObject %p)\n", This, ppv);
60         *ppv = OLEOBJ(This);
61     }else if(IsEqualGUID(&IID_IOleWindow, riid)) {
62         TRACE("(%p)->(IID_IOleWindow %p)\n", This, ppv);
63         *ppv = INPLACEOBJ(This);
64     }else if(IsEqualGUID (&IID_IOleInPlaceObject, riid)) {
65         TRACE("(%p)->(IID_IOleInPlaceObject %p)\n", This, ppv);
66         *ppv = INPLACEOBJ(This);
67     }else if(IsEqualGUID(&IID_IOleControl, riid)) {
68         TRACE("(%p)->(IID_IOleControl %p)\n", This, ppv);
69         *ppv = CONTROL(This);
70     }else if(IsEqualGUID(&IID_IPersist, riid)) {
71         TRACE("(%p)->(IID_IPersist %p)\n", This, ppv);
72         *ppv = PERSTORAGE(This);
73     }else if(IsEqualGUID(&IID_IPersistStorage, riid)) {
74         TRACE("(%p)->(IID_IPersistStorage %p)\n", This, ppv);
75         *ppv = PERSTORAGE(This);
76     }else if(IsEqualGUID(&IID_IPersistMemory, riid)) {
77         TRACE("(%p)->(IID_IPersistStorage %p)\n", This, ppv);
78         *ppv = PERMEMORY(This);
79     }else if(IsEqualGUID (&IID_IPersistStreamInit, riid)) {
80         TRACE("(%p)->(IID_IPersistStreamInit %p)\n", This, ppv);
81         *ppv = PERSTRINIT(This);
82     }else if(IsEqualGUID(&IID_IProvideClassInfo, riid)) {
83         TRACE("(%p)->(IID_IProvideClassInfo %p)\n", This, ppv);
84         *ppv = CLASSINFO(This);
85     }else if(IsEqualGUID(&IID_IProvideClassInfo2, riid)) {
86         TRACE("(%p)->(IID_IProvideClassInfo2 %p)\n", This, ppv);
87         *ppv = CLASSINFO(This);
88     }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
89         TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
90         *ppv = CONPTCONT(&This->doc_host.cps);
91     }else if(IsEqualGUID(&IID_IViewObject, riid)) {
92         TRACE("(%p)->(IID_IViewObject %p)\n", This, ppv);
93         *ppv = VIEWOBJ(This);
94     }else if(IsEqualGUID(&IID_IViewObject2, riid)) {
95         TRACE("(%p)->(IID_IViewObject2 %p)\n", This, ppv);
96         *ppv = VIEWOBJ2(This);
97     }else if(IsEqualGUID(&IID_IOleInPlaceActiveObject, riid)) {
98         TRACE("(%p)->(IID_IOleInPlaceActiveObject %p)\n", This, ppv);
99         *ppv = ACTIVEOBJ(This);
100     }else if(IsEqualGUID(&IID_IOleCommandTarget, riid)) {
101         TRACE("(%p)->(IID_IOleCommandTarget %p)\n", This, ppv);
102         *ppv = OLECMD(This);
103     }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
104         *ppv = SERVPROV(This);
105         TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
106     }else if(IsEqualGUID(&IID_IDataObject, riid)) {
107         *ppv = DATAOBJECT(This);
108         TRACE("(%p)->(IID_IDataObject %p)\n", This, ppv);
109     }else if(IsEqualGUID(&IID_IQuickActivate, riid)) {
110         TRACE("(%p)->(IID_IQuickActivate %p) returning NULL\n", This, ppv);
111         return E_NOINTERFACE;
112     }else if(IsEqualGUID(&IID_IRunnableObject, riid)) {
113         TRACE("(%p)->(IID_IRunnableObject %p) returning NULL\n", This, ppv);
114         return E_NOINTERFACE;
115     }else if(IsEqualGUID(&IID_IPerPropertyBrowsing, riid)) {
116         TRACE("(%p)->(IID_IPerPropertyBrowsing %p) returning NULL\n", This, ppv);
117         return E_NOINTERFACE;
118     }else if(IsEqualGUID(&IID_IOleCache, riid)) {
119         TRACE("(%p)->(IID_IOleCache %p) returning NULL\n", This, ppv);
120         return E_NOINTERFACE;
121     }else if(IsEqualGUID(&IID_IOleInPlaceSite, riid)) {
122         TRACE("(%p)->(IID_IOleInPlaceSite %p) returning NULL\n", This, ppv);
123         return E_NOINTERFACE;
124     }else if(IsEqualGUID(&IID_IObjectWithSite, riid)) {
125         TRACE("(%p)->(IID_IObjectWithSite %p) returning NULL\n", This, ppv);
126         return E_NOINTERFACE;
127     }else if(IsEqualGUID(&IID_IViewObjectEx, riid)) {
128         TRACE("(%p)->(IID_IViewObjectEx %p) returning NULL\n", This, ppv);
129         return E_NOINTERFACE;
130     }else if(HlinkFrame_QI(&This->hlink_frame, riid, ppv)) {
131         return S_OK;
132     }
133
134     if(*ppv) {
135         IUnknown_AddRef((IUnknown*)*ppv);
136         return S_OK;
137     }
138
139     FIXME("(%p)->(%s %p) interface not supported\n", This, debugstr_guid(riid), ppv);
140     return E_NOINTERFACE;
141 }
142
143 static ULONG WINAPI WebBrowser_AddRef(IWebBrowser2 *iface)
144 {
145     WebBrowser *This = WEBBROWSER_THIS(iface);
146     LONG ref = InterlockedIncrement(&This->ref);
147     TRACE("(%p) ref=%d\n", This, ref);
148     return ref;
149 }
150
151 static ULONG WINAPI WebBrowser_Release(IWebBrowser2 *iface)
152 {
153     WebBrowser *This = WEBBROWSER_THIS(iface);
154     LONG ref = InterlockedDecrement(&This->ref);
155
156     TRACE("(%p) ref=%d\n", This, ref);
157
158     if(!ref) {
159         if(This->doc_host.document)
160             IUnknown_Release(This->doc_host.document);
161
162         DocHost_Release(&This->doc_host);
163
164         WebBrowser_OleObject_Destroy(This);
165
166         heap_free(This);
167         SHDOCVW_UnlockModule();
168     }
169
170     return ref;
171 }
172
173 /* IDispatch methods */
174 static HRESULT WINAPI WebBrowser_GetTypeInfoCount(IWebBrowser2 *iface, UINT *pctinfo)
175 {
176     WebBrowser *This = WEBBROWSER_THIS(iface);
177
178     TRACE("(%p)->(%p)\n", This, pctinfo);
179
180     *pctinfo = 1;
181     return S_OK;
182 }
183
184 static HRESULT WINAPI WebBrowser_GetTypeInfo(IWebBrowser2 *iface, UINT iTInfo, LCID lcid,
185                                      LPTYPEINFO *ppTInfo)
186 {
187     WebBrowser *This = WEBBROWSER_THIS(iface);
188     ITypeInfo *typeinfo;
189     HRESULT hres;
190
191     TRACE("(%p)->(%d %d %p)\n", This, iTInfo, lcid, ppTInfo);
192
193     hres = get_typeinfo(&typeinfo);
194     if(FAILED(hres))
195         return hres;
196
197     ITypeInfo_AddRef(typeinfo);
198     *ppTInfo = typeinfo;
199     return S_OK;
200 }
201
202 static HRESULT WINAPI WebBrowser_GetIDsOfNames(IWebBrowser2 *iface, REFIID riid,
203                                        LPOLESTR *rgszNames, UINT cNames,
204                                        LCID lcid, DISPID *rgDispId)
205 {
206     WebBrowser *This = WEBBROWSER_THIS(iface);
207     ITypeInfo *typeinfo;
208     HRESULT hres;
209
210     TRACE("(%p)->(%s %p %d %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
211           lcid, rgDispId);
212
213     hres = get_typeinfo(&typeinfo);
214     if(FAILED(hres))
215         return hres;
216
217     return ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
218 }
219
220 static HRESULT WINAPI WebBrowser_Invoke(IWebBrowser2 *iface, DISPID dispIdMember,
221                                 REFIID riid, LCID lcid, WORD wFlags,
222                                 DISPPARAMS *pDispParams, VARIANT *pVarResult,
223                                 EXCEPINFO *pExepInfo, UINT *puArgErr)
224 {
225     WebBrowser *This = WEBBROWSER_THIS(iface);
226     ITypeInfo *typeinfo;
227     HRESULT hres;
228
229     TRACE("(%p)->(%d %s %d %08x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
230             lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
231
232     hres = get_typeinfo(&typeinfo);
233     if(FAILED(hres))
234         return hres;
235
236     return ITypeInfo_Invoke(typeinfo, WEBBROWSER2(This), dispIdMember, wFlags, pDispParams,
237                             pVarResult, pExepInfo, puArgErr);
238 }
239
240 /* IWebBrowser methods */
241 static HRESULT WINAPI WebBrowser_GoBack(IWebBrowser2 *iface)
242 {
243     WebBrowser *This = WEBBROWSER_THIS(iface);
244     FIXME("(%p)\n", This);
245     return E_NOTIMPL;
246 }
247
248 static HRESULT WINAPI WebBrowser_GoForward(IWebBrowser2 *iface)
249 {
250     WebBrowser *This = WEBBROWSER_THIS(iface);
251     FIXME("(%p)\n", This);
252     return E_NOTIMPL;
253 }
254
255 static HRESULT WINAPI WebBrowser_GoHome(IWebBrowser2 *iface)
256 {
257     WebBrowser *This = WEBBROWSER_THIS(iface);
258     TRACE("(%p)\n", This);
259     return go_home(&This->doc_host);
260 }
261
262 static HRESULT WINAPI WebBrowser_GoSearch(IWebBrowser2 *iface)
263 {
264     WebBrowser *This = WEBBROWSER_THIS(iface);
265     FIXME("(%p)\n", This);
266     return E_NOTIMPL;
267 }
268
269 static HRESULT WINAPI WebBrowser_Navigate(IWebBrowser2 *iface, BSTR szUrl,
270                                   VARIANT *Flags, VARIANT *TargetFrameName,
271                                   VARIANT *PostData, VARIANT *Headers)
272 {
273     WebBrowser *This = WEBBROWSER_THIS(iface);
274
275     TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(szUrl), debugstr_variant(Flags),
276           debugstr_variant(TargetFrameName), debugstr_variant(PostData),
277           debugstr_variant(Headers));
278
279     return navigate_url(&This->doc_host, szUrl, Flags, TargetFrameName, PostData, Headers);
280 }
281
282 static HRESULT WINAPI WebBrowser_Refresh(IWebBrowser2 *iface)
283 {
284     WebBrowser *This = WEBBROWSER_THIS(iface);
285     FIXME("(%p)\n", This);
286     return E_NOTIMPL;
287 }
288
289 static HRESULT WINAPI WebBrowser_Refresh2(IWebBrowser2 *iface, VARIANT *Level)
290 {
291     WebBrowser *This = WEBBROWSER_THIS(iface);
292     FIXME("(%p)->(%s)\n", This, debugstr_variant(Level));
293     return E_NOTIMPL;
294 }
295
296 static HRESULT WINAPI WebBrowser_Stop(IWebBrowser2 *iface)
297 {
298     WebBrowser *This = WEBBROWSER_THIS(iface);
299     FIXME("(%p)\n", This);
300     return S_OK;
301 }
302
303 static HRESULT WINAPI WebBrowser_get_Application(IWebBrowser2 *iface, IDispatch **ppDisp)
304 {
305     WebBrowser *This = WEBBROWSER_THIS(iface);
306
307     TRACE("(%p)->(%p)\n", This, ppDisp);
308
309     if(!ppDisp)
310         return E_POINTER;
311
312     *ppDisp = (IDispatch*)WEBBROWSER2(This);
313     IDispatch_AddRef(*ppDisp);
314     return S_OK;
315 }
316
317 static HRESULT WINAPI WebBrowser_get_Parent(IWebBrowser2 *iface, IDispatch **ppDisp)
318 {
319     WebBrowser *This = WEBBROWSER_THIS(iface);
320     FIXME("(%p)->(%p)\n", This, ppDisp);
321     return E_NOTIMPL;
322 }
323
324 static HRESULT WINAPI WebBrowser_get_Container(IWebBrowser2 *iface, IDispatch **ppDisp)
325 {
326     WebBrowser *This = WEBBROWSER_THIS(iface);
327     FIXME("(%p)->(%p)\n", This, ppDisp);
328     return E_NOTIMPL;
329 }
330
331 static HRESULT WINAPI WebBrowser_get_Document(IWebBrowser2 *iface, IDispatch **ppDisp)
332 {
333     WebBrowser *This = WEBBROWSER_THIS(iface);
334     IDispatch *disp = NULL;
335
336     TRACE("(%p)->(%p)\n", This, ppDisp);
337
338     if(This->doc_host.document) {
339         HRESULT hres;
340
341         hres = IUnknown_QueryInterface(This->doc_host.document, &IID_IDispatch, (void**)&disp);
342         if(SUCCEEDED(hres)) {
343             IDispatch *html_doc;
344
345             /* Some broken apps cast returned IDispatch to IHTMLDocument2
346              * without QueryInterface call */
347             hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&html_doc);
348             if(SUCCEEDED(hres)) {
349                 IDispatch_Release(disp);
350                 disp = html_doc;
351             }
352         }
353     }
354
355     *ppDisp = disp;
356     return S_OK;
357 }
358
359 static HRESULT WINAPI WebBrowser_get_TopLevelContainer(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
360 {
361     WebBrowser *This = WEBBROWSER_THIS(iface);
362     FIXME("(%p)->(%p)\n", This, pBool);
363     return E_NOTIMPL;
364 }
365
366 static HRESULT WINAPI WebBrowser_get_Type(IWebBrowser2 *iface, BSTR *Type)
367 {
368     WebBrowser *This = WEBBROWSER_THIS(iface);
369     FIXME("(%p)->(%p)\n", This, Type);
370     return E_NOTIMPL;
371 }
372
373 static HRESULT WINAPI WebBrowser_get_Left(IWebBrowser2 *iface, LONG *pl)
374 {
375     WebBrowser *This = WEBBROWSER_THIS(iface);
376
377     TRACE("(%p)->(%p)\n", This, pl);
378
379     *pl = This->pos_rect.left;
380     return S_OK;
381 }
382
383 static HRESULT WINAPI WebBrowser_put_Left(IWebBrowser2 *iface, LONG Left)
384 {
385     WebBrowser *This = WEBBROWSER_THIS(iface);
386     RECT rect;
387
388     TRACE("(%p)->(%d)\n", This, Left);
389
390     if(!This->inplace)
391         return E_UNEXPECTED;
392
393     rect = This->pos_rect;
394     rect.left = Left;
395
396     /* We don't really change the window position here.
397      * We just notify the embedder that he should do so. */
398     return IOleInPlaceSite_OnPosRectChange(This->inplace, &rect);
399 }
400
401 static HRESULT WINAPI WebBrowser_get_Top(IWebBrowser2 *iface, LONG *pl)
402 {
403     WebBrowser *This = WEBBROWSER_THIS(iface);
404
405     TRACE("(%p)->(%p)\n", This, pl);
406
407     *pl = This->pos_rect.top;
408     return S_OK;
409 }
410
411 static HRESULT WINAPI WebBrowser_put_Top(IWebBrowser2 *iface, LONG Top)
412 {
413     WebBrowser *This = WEBBROWSER_THIS(iface);
414     RECT rect;
415
416     TRACE("(%p)->(%d)\n", This, Top);
417
418     if(!This->inplace)
419         return E_UNEXPECTED;
420
421     rect = This->pos_rect;
422     rect.top = Top;
423
424     /* We don't really change the window position here.
425      * We just notify the embedder that he should do so. */
426     return IOleInPlaceSite_OnPosRectChange(This->inplace, &rect);
427 }
428
429 static HRESULT WINAPI WebBrowser_get_Width(IWebBrowser2 *iface, LONG *pl)
430 {
431     WebBrowser *This = WEBBROWSER_THIS(iface);
432
433     TRACE("(%p)->(%p)\n", This, pl);
434
435     *pl = This->pos_rect.right - This->pos_rect.left;
436     return S_OK;
437 }
438
439 static HRESULT WINAPI WebBrowser_put_Width(IWebBrowser2 *iface, LONG Width)
440 {
441     WebBrowser *This = WEBBROWSER_THIS(iface);
442     RECT rect;
443
444     TRACE("(%p)->(%d)\n", This, Width);
445
446     if(!This->inplace)
447         return E_UNEXPECTED;
448
449     rect = This->pos_rect;
450     rect.right = rect.left+Width;
451
452     /* We don't really change the window size here.
453      * We just notify the embedder that he should do so. */
454    return IOleInPlaceSite_OnPosRectChange(This->inplace, &rect);
455 }
456
457 static HRESULT WINAPI WebBrowser_get_Height(IWebBrowser2 *iface, LONG *pl)
458 {
459     WebBrowser *This = WEBBROWSER_THIS(iface);
460
461     TRACE("(%p)->(%p)\n", This, pl);
462
463     *pl = This->pos_rect.bottom - This->pos_rect.top;
464     return S_OK;
465 }
466
467 static HRESULT WINAPI WebBrowser_put_Height(IWebBrowser2 *iface, LONG Height)
468 {
469     WebBrowser *This = WEBBROWSER_THIS(iface);
470     RECT rect;
471
472     TRACE("(%p)->(%d)\n", This, Height);
473
474     if(!This->inplace)
475         return E_UNEXPECTED;
476
477     rect = This->pos_rect;
478     rect.bottom = rect.top+Height;
479
480     /* We don't really change the window size here.
481      * We just notify the embedder that he should do so. */
482     return IOleInPlaceSite_OnPosRectChange(This->inplace, &rect);
483 }
484
485 static HRESULT WINAPI WebBrowser_get_LocationName(IWebBrowser2 *iface, BSTR *LocationName)
486 {
487     WebBrowser *This = WEBBROWSER_THIS(iface);
488     FIXME("(%p)->(%p)\n", This, LocationName);
489     return E_NOTIMPL;
490 }
491
492 static HRESULT WINAPI WebBrowser_get_LocationURL(IWebBrowser2 *iface, BSTR *LocationURL)
493 {
494     WebBrowser *This = WEBBROWSER_THIS(iface);
495
496     FIXME("(%p)->(%p)\n", This, LocationURL);
497
498     if(!This->doc_host.url) {
499         static const WCHAR null_char = 0;
500         *LocationURL = SysAllocString(&null_char);
501         return S_FALSE;
502     }
503
504     *LocationURL = SysAllocString(This->doc_host.url);
505     return S_OK;
506 }
507
508 static HRESULT WINAPI WebBrowser_get_Busy(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
509 {
510     WebBrowser *This = WEBBROWSER_THIS(iface);
511
512     TRACE("(%p)->(%p)\n", This, pBool);
513
514     *pBool = This->doc_host.busy;
515     return S_OK;
516 }
517
518 static HRESULT WINAPI WebBrowser_Quit(IWebBrowser2 *iface)
519 {
520     WebBrowser *This = WEBBROWSER_THIS(iface);
521
522     TRACE("(%p)\n", This);
523
524     /* It's a InternetExplorer specific method, we have nothing to do here. */
525     return E_FAIL;
526 }
527
528 static HRESULT WINAPI WebBrowser_ClientToWindow(IWebBrowser2 *iface, int *pcx, int *pcy)
529 {
530     WebBrowser *This = WEBBROWSER_THIS(iface);
531     FIXME("(%p)->(%p %p)\n", This, pcx, pcy);
532     return E_NOTIMPL;
533 }
534
535 static HRESULT WINAPI WebBrowser_PutProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT vtValue)
536 {
537     WebBrowser *This = WEBBROWSER_THIS(iface);
538     FIXME("(%p)->(%s %s)\n", This, debugstr_w(szProperty), debugstr_variant(&vtValue));
539     return E_NOTIMPL;
540 }
541
542 static HRESULT WINAPI WebBrowser_GetProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT *pvtValue)
543 {
544     WebBrowser *This = WEBBROWSER_THIS(iface);
545     FIXME("(%p)->(%s %s)\n", This, debugstr_w(szProperty), debugstr_variant(pvtValue));
546     return E_NOTIMPL;
547 }
548
549 static HRESULT WINAPI WebBrowser_get_Name(IWebBrowser2 *iface, BSTR *Name)
550 {
551     static const WCHAR sName[] = {'M','i','c','r','o','s','o','f','t',' ','W','e','b',
552                                   ' ','B','r','o','w','s','e','r',' ','C','o','n','t','r','o','l',0};
553     WebBrowser *This = WEBBROWSER_THIS(iface);
554
555     TRACE("(%p)->(%p)\n", This, Name);
556
557     *Name = SysAllocString(sName);
558
559     return S_OK;
560 }
561
562 static HRESULT WINAPI WebBrowser_get_HWND(IWebBrowser2 *iface, LONG *pHWND)
563 {
564     WebBrowser *This = WEBBROWSER_THIS(iface);
565
566     TRACE("(%p)->(%p)\n", This, pHWND);
567
568     /* WebBrowser control never has a frame window (in opposition to InternetExplorer) */
569     *pHWND = 0;
570     return E_FAIL;
571 }
572
573 static HRESULT WINAPI WebBrowser_get_FullName(IWebBrowser2 *iface, BSTR *FullName)
574 {
575     WebBrowser *This = WEBBROWSER_THIS(iface);
576     FIXME("(%p)->(%p)\n", This, FullName);
577     return E_NOTIMPL;
578 }
579
580 static HRESULT WINAPI WebBrowser_get_Path(IWebBrowser2 *iface, BSTR *Path)
581 {
582     WebBrowser *This = WEBBROWSER_THIS(iface);
583     FIXME("(%p)->(%p)\n", This, Path);
584     return E_NOTIMPL;
585 }
586
587 static HRESULT WINAPI WebBrowser_get_Visible(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
588 {
589     WebBrowser *This = WEBBROWSER_THIS(iface);
590
591     TRACE("(%p)->(%p)\n", This, pBool);
592
593     *pBool = This->visible;
594     return S_OK;
595 }
596
597 static HRESULT WINAPI WebBrowser_put_Visible(IWebBrowser2 *iface, VARIANT_BOOL Value)
598 {
599     WebBrowser *This = WEBBROWSER_THIS(iface);
600     VARIANTARG arg;
601     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
602
603     TRACE("(%p)->(%x)\n", This, Value);
604
605     This->visible = Value;
606
607     V_VT(&arg) = VT_BOOL;
608     V_BOOL(&arg) = Value;
609     call_sink(This->doc_host.cps.wbe2, DISPID_ONVISIBLE, &dispparams);
610
611     return S_OK;
612 }
613
614 static HRESULT WINAPI WebBrowser_get_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
615 {
616     WebBrowser *This = WEBBROWSER_THIS(iface);
617
618     TRACE("(%p)->(%p)\n", This, pBool);
619
620     *pBool = This->status_bar;
621     return S_OK;
622 }
623
624 static HRESULT WINAPI WebBrowser_put_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
625 {
626     WebBrowser *This = WEBBROWSER_THIS(iface);
627     VARIANTARG arg;
628     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
629
630     TRACE("(%p)->(%x)\n", This, Value);
631
632     This->status_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;
633
634     /* In opposition to InternetExplorer, all we should do here is
635      * inform the embedder about the status bar change. */
636
637     V_VT(&arg) = VT_BOOL;
638     V_BOOL(&arg) = Value;
639     call_sink(This->doc_host.cps.wbe2, DISPID_ONSTATUSBAR, &dispparams);
640
641     return S_OK;
642 }
643
644 static HRESULT WINAPI WebBrowser_get_StatusText(IWebBrowser2 *iface, BSTR *StatusText)
645 {
646     WebBrowser *This = WEBBROWSER_THIS(iface);
647     FIXME("(%p)->(%p)\n", This, StatusText);
648     return E_NOTIMPL;
649 }
650
651 static HRESULT WINAPI WebBrowser_put_StatusText(IWebBrowser2 *iface, BSTR StatusText)
652 {
653     WebBrowser *This = WEBBROWSER_THIS(iface);
654     FIXME("(%p)->(%s)\n", This, debugstr_w(StatusText));
655     return E_NOTIMPL;
656 }
657
658 static HRESULT WINAPI WebBrowser_get_ToolBar(IWebBrowser2 *iface, int *Value)
659 {
660     WebBrowser *This = WEBBROWSER_THIS(iface);
661
662     TRACE("(%p)->(%p)\n", This, Value);
663
664     *Value = This->tool_bar;
665     return S_OK;
666 }
667
668 static HRESULT WINAPI WebBrowser_put_ToolBar(IWebBrowser2 *iface, int Value)
669 {
670     WebBrowser *This = WEBBROWSER_THIS(iface);
671     VARIANTARG arg;
672     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
673
674     TRACE("(%p)->(%x)\n", This, Value);
675
676     This->tool_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;
677
678     /* In opposition to InternetExplorer, all we should do here is
679      * inform the embedder about the tool bar change. */
680
681     V_VT(&arg) = VT_BOOL;
682     V_BOOL(&arg) = This->tool_bar;
683     call_sink(This->doc_host.cps.wbe2, DISPID_ONTOOLBAR, &dispparams);
684
685     return S_OK;
686 }
687
688 static HRESULT WINAPI WebBrowser_get_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL *Value)
689 {
690     WebBrowser *This = WEBBROWSER_THIS(iface);
691
692     TRACE("(%p)->(%p)\n", This, Value);
693
694     *Value = This->menu_bar;
695     return S_OK;
696 }
697
698 static HRESULT WINAPI WebBrowser_put_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
699 {
700     WebBrowser *This = WEBBROWSER_THIS(iface);
701     VARIANTARG arg;
702     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
703
704     TRACE("(%p)->(%x)\n", This, Value);
705
706     This->menu_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;
707
708     /* In opposition to InternetExplorer, all we should do here is
709      * inform the embedder about the menu bar change. */
710
711     V_VT(&arg) = VT_BOOL;
712     V_BOOL(&arg) = Value;
713     call_sink(This->doc_host.cps.wbe2, DISPID_ONMENUBAR, &dispparams);
714
715     return S_OK;
716 }
717
718 static HRESULT WINAPI WebBrowser_get_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL *pbFullScreen)
719 {
720     WebBrowser *This = WEBBROWSER_THIS(iface);
721
722     TRACE("(%p)->(%p)\n", This, pbFullScreen);
723
724     *pbFullScreen = This->full_screen;
725     return S_OK;
726 }
727
728 static HRESULT WINAPI WebBrowser_put_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL bFullScreen)
729 {
730     WebBrowser *This = WEBBROWSER_THIS(iface);
731     VARIANTARG arg;
732     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
733
734     /* In opposition to InternetExplorer, all we should do here is
735      * inform the embedder about the fullscreen change. */
736
737     TRACE("(%p)->(%x)\n", This, bFullScreen);
738
739     This->full_screen = bFullScreen ? VARIANT_TRUE : VARIANT_FALSE;
740
741     V_VT(&arg) = VT_BOOL;
742     V_BOOL(&arg) = bFullScreen;
743     call_sink(This->doc_host.cps.wbe2, DISPID_ONFULLSCREEN, &dispparams);
744
745     return S_OK;
746 }
747
748 static HRESULT WINAPI WebBrowser_Navigate2(IWebBrowser2 *iface, VARIANT *URL, VARIANT *Flags,
749         VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
750 {
751     WebBrowser *This = WEBBROWSER_THIS(iface);
752     LPCWSTR url;
753
754     TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_variant(URL), debugstr_variant(Flags),
755           debugstr_variant(TargetFrameName), debugstr_variant(PostData), debugstr_variant(Headers));
756
757     if(!This->client)
758         return E_FAIL;
759
760     if(!URL)
761         return S_OK;
762
763     switch (V_VT(URL))
764     {
765     case VT_BSTR:
766         url = V_BSTR(URL);
767         break;
768     case VT_BSTR|VT_BYREF:
769         url = *V_BSTRREF(URL);
770         break;
771     default:
772         FIXME("Unsupported V_VT(URL) %d\n", V_VT(URL));
773         return E_INVALIDARG;
774     }
775
776     return navigate_url(&This->doc_host, url, Flags, TargetFrameName, PostData, Headers);
777 }
778
779 static HRESULT WINAPI WebBrowser_QueryStatusWB(IWebBrowser2 *iface, OLECMDID cmdID, OLECMDF *pcmdf)
780 {
781     WebBrowser *This = WEBBROWSER_THIS(iface);
782     FIXME("(%p)->(%d %p)\n", This, cmdID, pcmdf);
783     return E_NOTIMPL;
784 }
785
786 static HRESULT WINAPI WebBrowser_ExecWB(IWebBrowser2 *iface, OLECMDID cmdID,
787         OLECMDEXECOPT cmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
788 {
789     WebBrowser *This = WEBBROWSER_THIS(iface);
790     FIXME("(%p)->(%d %d %s %p)\n", This, cmdID, cmdexecopt, debugstr_variant(pvaIn), pvaOut);
791     return E_NOTIMPL;
792 }
793
794 static HRESULT WINAPI WebBrowser_ShowBrowserBar(IWebBrowser2 *iface, VARIANT *pvaClsid,
795         VARIANT *pvarShow, VARIANT *pvarSize)
796 {
797     WebBrowser *This = WEBBROWSER_THIS(iface);
798     FIXME("(%p)->(%s %s %s)\n", This, debugstr_variant(pvaClsid), debugstr_variant(pvarShow),
799           debugstr_variant(pvarSize));
800     return E_NOTIMPL;
801 }
802
803 static HRESULT WINAPI WebBrowser_get_ReadyState(IWebBrowser2 *iface, READYSTATE *lpReadyState)
804 {
805     WebBrowser *This = WEBBROWSER_THIS(iface);
806
807     TRACE("(%p)->(%p)\n", This, lpReadyState);
808
809     *lpReadyState = This->doc_host.ready_state;
810     return S_OK;
811 }
812
813 static HRESULT WINAPI WebBrowser_get_Offline(IWebBrowser2 *iface, VARIANT_BOOL *pbOffline)
814 {
815     WebBrowser *This = WEBBROWSER_THIS(iface);
816
817     TRACE("(%p)->(%p)\n", This, pbOffline);
818
819     *pbOffline = This->doc_host.offline;
820     return S_OK;
821 }
822
823 static HRESULT WINAPI WebBrowser_put_Offline(IWebBrowser2 *iface, VARIANT_BOOL bOffline)
824 {
825     WebBrowser *This = WEBBROWSER_THIS(iface);
826
827     TRACE("(%p)->(%x)\n", This, bOffline);
828
829     This->doc_host.offline = bOffline ? VARIANT_TRUE : VARIANT_FALSE;
830     return S_OK;
831 }
832
833 static HRESULT WINAPI WebBrowser_get_Silent(IWebBrowser2 *iface, VARIANT_BOOL *pbSilent)
834 {
835     WebBrowser *This = WEBBROWSER_THIS(iface);
836
837     TRACE("(%p)->(%p)\n", This, pbSilent);
838
839     *pbSilent = This->doc_host.silent;
840     return S_OK;
841 }
842
843 static HRESULT WINAPI WebBrowser_put_Silent(IWebBrowser2 *iface, VARIANT_BOOL bSilent)
844 {
845     WebBrowser *This = WEBBROWSER_THIS(iface);
846
847     TRACE("(%p)->(%x)\n", This, bSilent);
848
849     This->doc_host.silent = bSilent ? VARIANT_TRUE : VARIANT_FALSE;
850     return S_OK;
851 }
852
853 static HRESULT WINAPI WebBrowser_get_RegisterAsBrowser(IWebBrowser2 *iface,
854         VARIANT_BOOL *pbRegister)
855 {
856     WebBrowser *This = WEBBROWSER_THIS(iface);
857
858     FIXME("(%p)->(%p)\n", This, pbRegister);
859
860     *pbRegister = This->register_browser;
861     return S_OK;
862 }
863
864 static HRESULT WINAPI WebBrowser_put_RegisterAsBrowser(IWebBrowser2 *iface,
865         VARIANT_BOOL bRegister)
866 {
867     WebBrowser *This = WEBBROWSER_THIS(iface);
868
869     FIXME("(%p)->(%x)\n", This, bRegister);
870
871     This->register_browser = bRegister ? VARIANT_TRUE : VARIANT_FALSE;
872     return S_OK;
873 }
874
875 static HRESULT WINAPI WebBrowser_get_RegisterAsDropTarget(IWebBrowser2 *iface,
876         VARIANT_BOOL *pbRegister)
877 {
878     WebBrowser *This = WEBBROWSER_THIS(iface);
879     FIXME("(%p)->(%p)\n", This, pbRegister);
880     *pbRegister=0;
881     return S_OK;
882 }
883
884 static HRESULT WINAPI WebBrowser_put_RegisterAsDropTarget(IWebBrowser2 *iface,
885         VARIANT_BOOL bRegister)
886 {
887     WebBrowser *This = WEBBROWSER_THIS(iface);
888     FIXME("(%p)->(%x)\n", This, bRegister);
889     return S_OK;
890 }
891
892 static HRESULT WINAPI WebBrowser_get_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL *pbRegister)
893 {
894     WebBrowser *This = WEBBROWSER_THIS(iface);
895
896     TRACE("(%p)->(%p)\n", This, pbRegister);
897
898     *pbRegister = This->theater_mode;
899     return S_OK;
900 }
901
902 static HRESULT WINAPI WebBrowser_put_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL bRegister)
903 {
904     WebBrowser *This = WEBBROWSER_THIS(iface);
905     VARIANTARG arg;
906     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
907
908     TRACE("(%p)->(%x)\n", This, bRegister);
909
910     This->theater_mode = bRegister ? VARIANT_TRUE : VARIANT_FALSE;
911
912     /* In opposition to InternetExplorer, all we should do here is
913      * inform the embedder about the theater mode change. */
914
915     V_VT(&arg) = VT_BOOL;
916     V_BOOL(&arg) = bRegister;
917     call_sink(This->doc_host.cps.wbe2, DISPID_ONTHEATERMODE, &dispparams);
918
919     return S_OK;
920 }
921
922 static HRESULT WINAPI WebBrowser_get_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL *Value)
923 {
924     WebBrowser *This = WEBBROWSER_THIS(iface);
925
926     TRACE("(%p)->(%p)\n", This, Value);
927
928     *Value = This->address_bar;
929     return S_OK;
930 }
931
932 static HRESULT WINAPI WebBrowser_put_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
933 {
934     WebBrowser *This = WEBBROWSER_THIS(iface);
935     VARIANTARG arg;
936     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
937
938     TRACE("(%p)->(%x)\n", This, Value);
939
940     This->address_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;
941
942     /* In opposition to InternetExplorer, all we should do here is
943      * inform the embedder about the address bar change. */
944
945     V_VT(&arg) = VT_BOOL;
946     V_BOOL(&arg) = Value;
947     call_sink(This->doc_host.cps.wbe2, DISPID_ONADDRESSBAR, &dispparams);
948
949     return S_OK;
950 }
951
952 static HRESULT WINAPI WebBrowser_get_Resizable(IWebBrowser2 *iface, VARIANT_BOOL *Value)
953 {
954     WebBrowser *This = WEBBROWSER_THIS(iface);
955
956     TRACE("(%p)->(%p)\n", This, Value);
957
958     /* It's InternetExplorer object's method. We have nothing to do here. */
959     return E_NOTIMPL;
960 }
961
962 static HRESULT WINAPI WebBrowser_put_Resizable(IWebBrowser2 *iface, VARIANT_BOOL Value)
963 {
964     WebBrowser *This = WEBBROWSER_THIS(iface);
965     VARIANTARG arg;
966     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
967
968     TRACE("(%p)->(%x)\n", This, Value);
969
970     /* In opposition to InternetExplorer, all we should do here is
971      * inform the embedder about the resizable change. */
972
973     V_VT(&arg) = VT_BOOL;
974     V_BOOL(&arg) = Value;
975     call_sink(This->doc_host.cps.wbe2, DISPID_WINDOWSETRESIZABLE, &dispparams);
976
977     return S_OK;
978 }
979
980 #undef WEBBROWSER_THIS
981
982 static const IWebBrowser2Vtbl WebBrowser2Vtbl =
983 {
984     WebBrowser_QueryInterface,
985     WebBrowser_AddRef,
986     WebBrowser_Release,
987     WebBrowser_GetTypeInfoCount,
988     WebBrowser_GetTypeInfo,
989     WebBrowser_GetIDsOfNames,
990     WebBrowser_Invoke,
991     WebBrowser_GoBack,
992     WebBrowser_GoForward,
993     WebBrowser_GoHome,
994     WebBrowser_GoSearch,
995     WebBrowser_Navigate,
996     WebBrowser_Refresh,
997     WebBrowser_Refresh2,
998     WebBrowser_Stop,
999     WebBrowser_get_Application,
1000     WebBrowser_get_Parent,
1001     WebBrowser_get_Container,
1002     WebBrowser_get_Document,
1003     WebBrowser_get_TopLevelContainer,
1004     WebBrowser_get_Type,
1005     WebBrowser_get_Left,
1006     WebBrowser_put_Left,
1007     WebBrowser_get_Top,
1008     WebBrowser_put_Top,
1009     WebBrowser_get_Width,
1010     WebBrowser_put_Width,
1011     WebBrowser_get_Height,
1012     WebBrowser_put_Height,
1013     WebBrowser_get_LocationName,
1014     WebBrowser_get_LocationURL,
1015     WebBrowser_get_Busy,
1016     WebBrowser_Quit,
1017     WebBrowser_ClientToWindow,
1018     WebBrowser_PutProperty,
1019     WebBrowser_GetProperty,
1020     WebBrowser_get_Name,
1021     WebBrowser_get_HWND,
1022     WebBrowser_get_FullName,
1023     WebBrowser_get_Path,
1024     WebBrowser_get_Visible,
1025     WebBrowser_put_Visible,
1026     WebBrowser_get_StatusBar,
1027     WebBrowser_put_StatusBar,
1028     WebBrowser_get_StatusText,
1029     WebBrowser_put_StatusText,
1030     WebBrowser_get_ToolBar,
1031     WebBrowser_put_ToolBar,
1032     WebBrowser_get_MenuBar,
1033     WebBrowser_put_MenuBar,
1034     WebBrowser_get_FullScreen,
1035     WebBrowser_put_FullScreen,
1036     WebBrowser_Navigate2,
1037     WebBrowser_QueryStatusWB,
1038     WebBrowser_ExecWB,
1039     WebBrowser_ShowBrowserBar,
1040     WebBrowser_get_ReadyState,
1041     WebBrowser_get_Offline,
1042     WebBrowser_put_Offline,
1043     WebBrowser_get_Silent,
1044     WebBrowser_put_Silent,
1045     WebBrowser_get_RegisterAsBrowser,
1046     WebBrowser_put_RegisterAsBrowser,
1047     WebBrowser_get_RegisterAsDropTarget,
1048     WebBrowser_put_RegisterAsDropTarget,
1049     WebBrowser_get_TheaterMode,
1050     WebBrowser_put_TheaterMode,
1051     WebBrowser_get_AddressBar,
1052     WebBrowser_put_AddressBar,
1053     WebBrowser_get_Resizable,
1054     WebBrowser_put_Resizable
1055 };
1056
1057 #define SERVPROV_THIS(iface) DEFINE_THIS(WebBrowser, OleObject, iface)
1058 /*
1059  *  IServiceProvider interface.
1060  */
1061 static HRESULT WINAPI WebBrowser_IServiceProvider_QueryInterface(IServiceProvider *iface,
1062             REFIID riid, LPVOID *ppv)
1063 {
1064     WebBrowser *This = SERVPROV_THIS(iface);
1065
1066     if (ppv == NULL)
1067         return E_POINTER;
1068     *ppv = NULL;
1069
1070     if(IsEqualGUID(&IID_IUnknown, riid)) {
1071         *ppv = WEBBROWSER(This);
1072         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
1073     }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
1074         *ppv = WEBBROWSER(This);
1075         TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
1076     }
1077
1078     if(*ppv) {
1079         IUnknown_AddRef((IUnknown*)*ppv);
1080         return S_OK;
1081     }
1082
1083     FIXME("(%p)->(%s %p) interface not supported\n", This, debugstr_guid(riid), ppv);
1084     return E_NOINTERFACE;
1085 }
1086
1087 static ULONG WINAPI WebBrowser_IServiceProvider_AddRef(IServiceProvider *iface)
1088 {
1089     WebBrowser *This = SERVPROV_THIS(iface);
1090     return IWebBrowser_AddRef(WEBBROWSER(This));
1091 }
1092
1093 static ULONG WINAPI WebBrowser_IServiceProvider_Release(IServiceProvider *iface)
1094 {
1095     WebBrowser *This = SERVPROV_THIS(iface);
1096     return IWebBrowser_Release(WEBBROWSER(This));
1097 }
1098
1099 static HRESULT STDMETHODCALLTYPE WebBrowser_IServiceProvider_QueryService(IServiceProvider *iface,
1100             REFGUID guidService, REFIID riid, void **ppv)
1101 {
1102     WebBrowser *This = SERVPROV_THIS(iface);
1103     static const IID IID_IBrowserService2 =
1104         {0x68BD21CC,0x438B,0x11d2,{0xA5,0x60,0x00,0xA0,0xC,0x2D,0xBF,0xE8}};
1105
1106     if(*ppv)
1107         ppv = NULL;
1108
1109     if(IsEqualGUID(&IID_IBrowserService2, riid)) {
1110         TRACE("(%p)->(IID_IBrowserService2 return E_FAIL)\n", This);
1111         return E_FAIL;
1112     }
1113
1114     FIXME("(%p)->(%s, %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
1115
1116     return E_NOINTERFACE;
1117 }
1118
1119 #undef SERVPROV_THIS
1120
1121 static const IServiceProviderVtbl ServiceProviderVtbl =
1122 {
1123     WebBrowser_IServiceProvider_QueryInterface,
1124     WebBrowser_IServiceProvider_AddRef,
1125     WebBrowser_IServiceProvider_Release,
1126     WebBrowser_IServiceProvider_QueryService
1127 };
1128
1129 static void WINAPI DocHostContainer_GetDocObjRect(DocHost* This, RECT* rc)
1130 {
1131     GetClientRect(This->frame_hwnd, rc);
1132 }
1133
1134 static HRESULT WINAPI DocHostContainer_SetStatusText(DocHost* This, LPCWSTR text)
1135 {
1136     return E_NOTIMPL;
1137 }
1138
1139 static void WINAPI DocHostContainer_SetURL(DocHost* This, LPCWSTR url)
1140 {
1141
1142 }
1143
1144 static const IDocHostContainerVtbl DocHostContainerVtbl = {
1145     DocHostContainer_GetDocObjRect,
1146     DocHostContainer_SetStatusText,
1147     DocHostContainer_SetURL
1148 };
1149
1150 static HRESULT WebBrowser_Create(INT version, IUnknown *pOuter, REFIID riid, void **ppv)
1151 {
1152     WebBrowser *ret;
1153     HRESULT hres;
1154
1155     TRACE("(%p %s %p) version=%d\n", pOuter, debugstr_guid(riid), ppv, version);
1156
1157     ret = heap_alloc_zero(sizeof(WebBrowser));
1158
1159     ret->lpWebBrowser2Vtbl = &WebBrowser2Vtbl;
1160     ret->lpServiceProviderVtbl = &ServiceProviderVtbl;
1161     ret->ref = 1;
1162     ret->version = version;
1163
1164     DocHost_Init(&ret->doc_host, (IDispatch*)WEBBROWSER2(ret), &DocHostContainerVtbl);
1165
1166     ret->visible = VARIANT_TRUE;
1167     ret->menu_bar = VARIANT_TRUE;
1168     ret->address_bar = VARIANT_TRUE;
1169     ret->status_bar = VARIANT_TRUE;
1170     ret->tool_bar = VARIANT_TRUE;
1171
1172     WebBrowser_OleObject_Init(ret);
1173     WebBrowser_ViewObject_Init(ret);
1174     WebBrowser_DataObject_Init(ret);
1175     WebBrowser_Persist_Init(ret);
1176     WebBrowser_ClassInfo_Init(ret);
1177
1178     HlinkFrame_Init(&ret->hlink_frame, (IUnknown*)WEBBROWSER2(ret), &ret->doc_host);
1179
1180     SHDOCVW_LockModule();
1181
1182     hres = IWebBrowser_QueryInterface(WEBBROWSER(ret), riid, ppv);
1183
1184     IWebBrowser2_Release(WEBBROWSER(ret));
1185     return hres;
1186 }
1187
1188 HRESULT WebBrowserV1_Create(IUnknown *pOuter, REFIID riid, void **ppv)
1189 {
1190     return WebBrowser_Create(1, pOuter, riid, ppv);
1191 }
1192
1193 HRESULT WebBrowserV2_Create(IUnknown *pOuter, REFIID riid, void **ppv)
1194 {
1195     return WebBrowser_Create(2, pOuter, riid, ppv);
1196 }