webbrowser.c 37.5 KB
Newer Older
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 8 9 10 11 12 13 14 15 16 17 18
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * 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 23
#include "ieframe.h"

24
#include "exdispid.h"
25
#include "mshtml.h"
26

27 28
#include "wine/debug.h"

29
WINE_DEFAULT_DEBUG_CHANNEL(ieframe);
30

31 32
static inline WebBrowser *impl_from_IWebBrowser2(IWebBrowser2 *iface)
{
33
    return CONTAINING_RECORD(iface, WebBrowser, IWebBrowser2_iface);
34
}
35

36
static HRESULT WINAPI WebBrowser_QueryInterface(IWebBrowser2 *iface, REFIID riid, LPVOID *ppv)
37
{
38
    WebBrowser *This = impl_from_IWebBrowser2(iface);
39 40 41 42 43 44 45

    if (ppv == NULL)
        return E_POINTER;
    *ppv = NULL;

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
46
        *ppv = &This->IWebBrowser2_iface;
47
    }else if(IsEqualGUID(&IID_IDispatch, riid)) {
48
        TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
49
        *ppv = &This->IWebBrowser2_iface;
50 51
    }else if(IsEqualGUID(&IID_IWebBrowser, riid)) {
        TRACE("(%p)->(IID_IWebBrowser %p)\n", This, ppv);
52
        *ppv = &This->IWebBrowser2_iface;
53 54
    }else if(IsEqualGUID(&IID_IWebBrowserApp, riid)) {
        TRACE("(%p)->(IID_IWebBrowserApp %p)\n", This, ppv);
55
        *ppv = &This->IWebBrowser2_iface;
56 57
    }else if(IsEqualGUID(&IID_IWebBrowser2, riid)) {
        TRACE("(%p)->(IID_IWebBrowser2 %p)\n", This, ppv);
58
        *ppv = &This->IWebBrowser2_iface;
59
    }else if(IsEqualGUID(&IID_IOleObject, riid)) {
60
        TRACE("(%p)->(IID_IOleObject %p)\n", This, ppv);
61
        *ppv = &This->IOleObject_iface;
62 63
    }else if(IsEqualGUID(&IID_IOleWindow, riid)) {
        TRACE("(%p)->(IID_IOleWindow %p)\n", This, ppv);
64
        *ppv = &This->IOleInPlaceObject_iface;
65 66
    }else if(IsEqualGUID (&IID_IOleInPlaceObject, riid)) {
        TRACE("(%p)->(IID_IOleInPlaceObject %p)\n", This, ppv);
67
        *ppv = &This->IOleInPlaceObject_iface;
68 69
    }else if(IsEqualGUID(&IID_IOleControl, riid)) {
        TRACE("(%p)->(IID_IOleControl %p)\n", This, ppv);
70
        *ppv = &This->IOleControl_iface;
71 72
    }else if(IsEqualGUID(&IID_IPersist, riid)) {
        TRACE("(%p)->(IID_IPersist %p)\n", This, ppv);
73
        *ppv = &This->IPersistStorage_iface;
74 75
    }else if(IsEqualGUID(&IID_IPersistStorage, riid)) {
        TRACE("(%p)->(IID_IPersistStorage %p)\n", This, ppv);
76
        *ppv = &This->IPersistStorage_iface;
77 78
    }else if(IsEqualGUID(&IID_IPersistMemory, riid)) {
        TRACE("(%p)->(IID_IPersistStorage %p)\n", This, ppv);
79
        *ppv = &This->IPersistMemory_iface;
80
    }else if(IsEqualGUID (&IID_IPersistStreamInit, riid)) {
81
        TRACE("(%p)->(IID_IPersistStreamInit %p)\n", This, ppv);
82
        *ppv = &This->IPersistStreamInit_iface;
83
    }else if(IsEqualGUID(&IID_IProvideClassInfo, riid)) {
84
        TRACE("(%p)->(IID_IProvideClassInfo %p)\n", This, ppv);
85
        *ppv = &This->IProvideClassInfo2_iface;
86
    }else if(IsEqualGUID(&IID_IProvideClassInfo2, riid)) {
87
        TRACE("(%p)->(IID_IProvideClassInfo2 %p)\n", This, ppv);
88
        *ppv = &This->IProvideClassInfo2_iface;
89
    }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
90
        TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
91
        *ppv = &This->doc_host.cps.IConnectionPointContainer_iface;
92 93
    }else if(IsEqualGUID(&IID_IViewObject, riid)) {
        TRACE("(%p)->(IID_IViewObject %p)\n", This, ppv);
94
        *ppv = &This->IViewObject2_iface;
95 96
    }else if(IsEqualGUID(&IID_IViewObject2, riid)) {
        TRACE("(%p)->(IID_IViewObject2 %p)\n", This, ppv);
97
        *ppv = &This->IViewObject2_iface;
98 99
    }else if(IsEqualGUID(&IID_IOleInPlaceActiveObject, riid)) {
        TRACE("(%p)->(IID_IOleInPlaceActiveObject %p)\n", This, ppv);
100
        *ppv = &This->IOleInPlaceActiveObject_iface;
101 102
    }else if(IsEqualGUID(&IID_IOleCommandTarget, riid)) {
        TRACE("(%p)->(IID_IOleCommandTarget %p)\n", This, ppv);
103
        *ppv = &This->IOleCommandTarget_iface;
104
    }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
105
        *ppv = &This->IServiceProvider_iface;
106
        TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
107
    }else if(IsEqualGUID(&IID_IDataObject, riid)) {
108
        *ppv = &This->IDataObject_iface;
109
        TRACE("(%p)->(IID_IDataObject %p)\n", This, ppv);
110 111 112 113 114 115
    }else if(IsEqualGUID(&IID_IQuickActivate, riid)) {
        TRACE("(%p)->(IID_IQuickActivate %p) returning NULL\n", This, ppv);
        return E_NOINTERFACE;
    }else if(IsEqualGUID(&IID_IRunnableObject, riid)) {
        TRACE("(%p)->(IID_IRunnableObject %p) returning NULL\n", This, ppv);
        return E_NOINTERFACE;
116 117 118 119 120 121
    }else if(IsEqualGUID(&IID_IPerPropertyBrowsing, riid)) {
        TRACE("(%p)->(IID_IPerPropertyBrowsing %p) returning NULL\n", This, ppv);
        return E_NOINTERFACE;
    }else if(IsEqualGUID(&IID_IOleCache, riid)) {
        TRACE("(%p)->(IID_IOleCache %p) returning NULL\n", This, ppv);
        return E_NOINTERFACE;
122 123 124 125 126
    }else if(IsEqualGUID(&IID_IOleInPlaceSite, riid)) {
        TRACE("(%p)->(IID_IOleInPlaceSite %p) returning NULL\n", This, ppv);
        return E_NOINTERFACE;
    }else if(IsEqualGUID(&IID_IObjectWithSite, riid)) {
        TRACE("(%p)->(IID_IObjectWithSite %p) returning NULL\n", This, ppv);
127 128 129
        return E_NOINTERFACE;
    }else if(IsEqualGUID(&IID_IViewObjectEx, riid)) {
        TRACE("(%p)->(IID_IViewObjectEx %p) returning NULL\n", This, ppv);
130
        return E_NOINTERFACE;
131 132 133
    }else if(IsEqualGUID(&IID_IOleLink, riid)) {
        TRACE("(%p)->(IID_IOleLink %p) returning NULL\n", This, ppv);
        return E_NOINTERFACE;
134 135 136 137
    }else if(IsEqualGUID(&IID_IMarshal, riid)) {
        TRACE("(%p)->(IID_IMarshal %p) returning NULL\n", This, ppv);
        return E_NOINTERFACE;
    }else if(IsEqualGUID(&IID_IStdMarshalInfo, riid)) {
138 139
        /* This is implemented since IE10 */
        WARN("(%p)->(IID_IStdMarshalInfo %p) returning NULL\n", This, ppv);
140
        return E_NOINTERFACE;
141 142
    }else if(HlinkFrame_QI(&This->hlink_frame, riid, ppv)) {
        return S_OK;
143 144 145 146 147 148 149 150
    }

    if(*ppv) {
        IUnknown_AddRef((IUnknown*)*ppv);
        return S_OK;
    }

    FIXME("(%p)->(%s %p) interface not supported\n", This, debugstr_guid(riid), ppv);
151 152 153
    return E_NOINTERFACE;
}

154
static ULONG WINAPI WebBrowser_AddRef(IWebBrowser2 *iface)
155
{
156
    WebBrowser *This = impl_from_IWebBrowser2(iface);
157
    LONG ref = InterlockedIncrement(&This->ref);
158
    TRACE("(%p) ref=%d\n", This, ref);
159
    return ref;
160 161
}

162
static ULONG WINAPI WebBrowser_Release(IWebBrowser2 *iface)
163
{
164
    WebBrowser *This = impl_from_IWebBrowser2(iface);
165 166
    LONG ref = InterlockedDecrement(&This->ref);

167
    TRACE("(%p) ref=%d\n", This, ref);
168

169
    if(!ref) {
170 171 172
        if(This->sink)
            IAdviseSink_Release(This->sink);

173 174
        if(This->doc_host.document)
            IUnknown_Release(This->doc_host.document);
175

176 177
        DocHost_Release(&This->doc_host);

178 179
        WebBrowser_OleObject_Destroy(This);

180
        heap_free(This);
181
        unlock_module();
182 183 184
    }

    return ref;
185 186 187
}

/* IDispatch methods */
188
static HRESULT WINAPI WebBrowser_GetTypeInfoCount(IWebBrowser2 *iface, UINT *pctinfo)
189
{
190
    WebBrowser *This = impl_from_IWebBrowser2(iface);
191 192 193 194 195

    TRACE("(%p)->(%p)\n", This, pctinfo);

    *pctinfo = 1;
    return S_OK;
196 197
}

198
static HRESULT WINAPI WebBrowser_GetTypeInfo(IWebBrowser2 *iface, UINT iTInfo, LCID lcid,
199 200
                                     LPTYPEINFO *ppTInfo)
{
201
    WebBrowser *This = impl_from_IWebBrowser2(iface);
202 203 204 205 206
    ITypeInfo *typeinfo;
    HRESULT hres;

    TRACE("(%p)->(%d %d %p)\n", This, iTInfo, lcid, ppTInfo);

207
    hres = get_typeinfo(IWebBrowser2_tid, &typeinfo);
208 209 210 211 212 213
    if(FAILED(hres))
        return hres;

    ITypeInfo_AddRef(typeinfo);
    *ppTInfo = typeinfo;
    return S_OK;
214 215
}

216
static HRESULT WINAPI WebBrowser_GetIDsOfNames(IWebBrowser2 *iface, REFIID riid,
217 218 219
                                       LPOLESTR *rgszNames, UINT cNames,
                                       LCID lcid, DISPID *rgDispId)
{
220
    WebBrowser *This = impl_from_IWebBrowser2(iface);
221 222 223 224 225 226
    ITypeInfo *typeinfo;
    HRESULT hres;

    TRACE("(%p)->(%s %p %d %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
          lcid, rgDispId);

227
    hres = get_typeinfo(IWebBrowser2_tid, &typeinfo);
228 229 230 231
    if(FAILED(hres))
        return hres;

    return ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
232 233
}

234
static HRESULT WINAPI WebBrowser_Invoke(IWebBrowser2 *iface, DISPID dispIdMember,
235 236 237 238
                                REFIID riid, LCID lcid, WORD wFlags,
                                DISPPARAMS *pDispParams, VARIANT *pVarResult,
                                EXCEPINFO *pExepInfo, UINT *puArgErr)
{
239
    WebBrowser *This = impl_from_IWebBrowser2(iface);
240 241 242
    ITypeInfo *typeinfo;
    HRESULT hres;

243
    TRACE("(%p)->(%d %s %d %08x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
244
            lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
245

246
    hres = get_typeinfo(IWebBrowser2_tid, &typeinfo);
247 248 249
    if(FAILED(hres))
        return hres;

250 251
    return ITypeInfo_Invoke(typeinfo, &This->IWebBrowser2_iface, dispIdMember, wFlags, pDispParams,
            pVarResult, pExepInfo, puArgErr);
252 253 254
}

/* IWebBrowser methods */
255
static HRESULT WINAPI WebBrowser_GoBack(IWebBrowser2 *iface)
256
{
257
    WebBrowser *This = impl_from_IWebBrowser2(iface);
258 259
    TRACE("(%p)\n", This);
    return go_back(&This->doc_host);
260 261
}

262
static HRESULT WINAPI WebBrowser_GoForward(IWebBrowser2 *iface)
263
{
264
    WebBrowser *This = impl_from_IWebBrowser2(iface);
265 266
    TRACE("(%p)\n", This);
    return go_forward(&This->doc_host);
267 268
}

269
static HRESULT WINAPI WebBrowser_GoHome(IWebBrowser2 *iface)
270
{
271
    WebBrowser *This = impl_from_IWebBrowser2(iface);
272 273
    TRACE("(%p)\n", This);
    return go_home(&This->doc_host);
274 275
}

276
static HRESULT WINAPI WebBrowser_GoSearch(IWebBrowser2 *iface)
277
{
278
    WebBrowser *This = impl_from_IWebBrowser2(iface);
279 280
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
281 282
}

283
static HRESULT WINAPI WebBrowser_Navigate(IWebBrowser2 *iface, BSTR szUrl,
284 285 286
                                  VARIANT *Flags, VARIANT *TargetFrameName,
                                  VARIANT *PostData, VARIANT *Headers)
{
287
    WebBrowser *This = impl_from_IWebBrowser2(iface);
288

289 290 291
    TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(szUrl), debugstr_variant(Flags),
          debugstr_variant(TargetFrameName), debugstr_variant(PostData),
          debugstr_variant(Headers));
292

293
    return navigate_url(&This->doc_host, szUrl, Flags, TargetFrameName, PostData, Headers);
294 295
}

296
static HRESULT WINAPI WebBrowser_Refresh(IWebBrowser2 *iface)
297
{
298
    WebBrowser *This = impl_from_IWebBrowser2(iface);
299 300 301

    TRACE("(%p)\n", This);

302
    return refresh_document(&This->doc_host, NULL);
303 304
}

305
static HRESULT WINAPI WebBrowser_Refresh2(IWebBrowser2 *iface, VARIANT *Level)
306
{
307
    WebBrowser *This = impl_from_IWebBrowser2(iface);
308 309 310 311

    TRACE("(%p)->(%s)\n", This, debugstr_variant(Level));

    return refresh_document(&This->doc_host, Level);
312 313
}

314
static HRESULT WINAPI WebBrowser_Stop(IWebBrowser2 *iface)
315
{
316
    WebBrowser *This = impl_from_IWebBrowser2(iface);
317
    FIXME("(%p)\n", This);
318
    return S_OK;
319 320
}

321
static HRESULT WINAPI WebBrowser_get_Application(IWebBrowser2 *iface, IDispatch **ppDisp)
322
{
323
    WebBrowser *This = impl_from_IWebBrowser2(iface);
324 325 326 327 328 329

    TRACE("(%p)->(%p)\n", This, ppDisp);

    if(!ppDisp)
        return E_POINTER;

330
    *ppDisp = (IDispatch*)&This->IWebBrowser2_iface;
331 332
    IDispatch_AddRef(*ppDisp);
    return S_OK;
333 334
}

335
static HRESULT WINAPI WebBrowser_get_Parent(IWebBrowser2 *iface, IDispatch **ppDisp)
336
{
337
    WebBrowser *This = impl_from_IWebBrowser2(iface);
338 339
    FIXME("(%p)->(%p)\n", This, ppDisp);
    return E_NOTIMPL;
340 341
}

342
static HRESULT WINAPI WebBrowser_get_Container(IWebBrowser2 *iface, IDispatch **ppDisp)
343
{
344
    WebBrowser *This = impl_from_IWebBrowser2(iface);
345 346
    FIXME("(%p)->(%p)\n", This, ppDisp);
    return E_NOTIMPL;
347 348
}

349
static HRESULT WINAPI WebBrowser_get_Document(IWebBrowser2 *iface, IDispatch **ppDisp)
350
{
351
    WebBrowser *This = impl_from_IWebBrowser2(iface);
352
    IDispatch *disp = NULL;
353 354 355

    TRACE("(%p)->(%p)\n", This, ppDisp);

356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
    if(This->doc_host.document) {
        HRESULT hres;

        hres = IUnknown_QueryInterface(This->doc_host.document, &IID_IDispatch, (void**)&disp);
        if(SUCCEEDED(hres)) {
            IDispatch *html_doc;

            /* Some broken apps cast returned IDispatch to IHTMLDocument2
             * without QueryInterface call */
            hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&html_doc);
            if(SUCCEEDED(hres)) {
                IDispatch_Release(disp);
                disp = html_doc;
            }
        }
    }
372

373
    *ppDisp = disp;
374
    return S_OK;
375 376
}

377
static HRESULT WINAPI WebBrowser_get_TopLevelContainer(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
378
{
379
    WebBrowser *This = impl_from_IWebBrowser2(iface);
380 381
    FIXME("(%p)->(%p)\n", This, pBool);
    return E_NOTIMPL;
382 383
}

384
static HRESULT WINAPI WebBrowser_get_Type(IWebBrowser2 *iface, BSTR *Type)
385
{
386
    WebBrowser *This = impl_from_IWebBrowser2(iface);
387 388
    FIXME("(%p)->(%p)\n", This, Type);
    return E_NOTIMPL;
389 390
}

391
static HRESULT WINAPI WebBrowser_get_Left(IWebBrowser2 *iface, LONG *pl)
392
{
393
    WebBrowser *This = impl_from_IWebBrowser2(iface);
394 395 396 397 398

    TRACE("(%p)->(%p)\n", This, pl);

    *pl = This->pos_rect.left;
    return S_OK;
399 400
}

401
static HRESULT WINAPI WebBrowser_put_Left(IWebBrowser2 *iface, LONG Left)
402
{
403
    WebBrowser *This = impl_from_IWebBrowser2(iface);
404 405
    RECT rect;

406
    TRACE("(%p)->(%d)\n", This, Left);
407 408 409 410

    if(!This->inplace)
        return E_UNEXPECTED;

411
    rect = This->pos_rect;
412 413
    rect.left = Left;

414 415
    /* We don't really change the window position here.
     * We just notify the embedder that he should do so. */
416
    return IOleInPlaceSiteEx_OnPosRectChange(This->inplace, &rect);
417 418
}

419
static HRESULT WINAPI WebBrowser_get_Top(IWebBrowser2 *iface, LONG *pl)
420
{
421
    WebBrowser *This = impl_from_IWebBrowser2(iface);
422 423 424 425 426

    TRACE("(%p)->(%p)\n", This, pl);

    *pl = This->pos_rect.top;
    return S_OK;
427 428
}

429
static HRESULT WINAPI WebBrowser_put_Top(IWebBrowser2 *iface, LONG Top)
430
{
431
    WebBrowser *This = impl_from_IWebBrowser2(iface);
432 433
    RECT rect;

434
    TRACE("(%p)->(%d)\n", This, Top);
435 436 437 438

    if(!This->inplace)
        return E_UNEXPECTED;

439
    rect = This->pos_rect;
440 441
    rect.top = Top;

442 443
    /* We don't really change the window position here.
     * We just notify the embedder that he should do so. */
444
    return IOleInPlaceSiteEx_OnPosRectChange(This->inplace, &rect);
445 446
}

447
static HRESULT WINAPI WebBrowser_get_Width(IWebBrowser2 *iface, LONG *pl)
448
{
449
    WebBrowser *This = impl_from_IWebBrowser2(iface);
450 451 452 453 454

    TRACE("(%p)->(%p)\n", This, pl);

    *pl = This->pos_rect.right - This->pos_rect.left;
    return S_OK;
455 456
}

457
static HRESULT WINAPI WebBrowser_put_Width(IWebBrowser2 *iface, LONG Width)
458
{
459
    WebBrowser *This = impl_from_IWebBrowser2(iface);
460 461
    RECT rect;

462
    TRACE("(%p)->(%d)\n", This, Width);
463 464 465 466

    if(!This->inplace)
        return E_UNEXPECTED;

467
    rect = This->pos_rect;
468
    rect.right = rect.left+Width;
469

470 471
    /* We don't really change the window size here.
     * We just notify the embedder that he should do so. */
472
   return IOleInPlaceSiteEx_OnPosRectChange(This->inplace, &rect);
473 474
}

475
static HRESULT WINAPI WebBrowser_get_Height(IWebBrowser2 *iface, LONG *pl)
476
{
477
    WebBrowser *This = impl_from_IWebBrowser2(iface);
478 479 480 481 482

    TRACE("(%p)->(%p)\n", This, pl);

    *pl = This->pos_rect.bottom - This->pos_rect.top;
    return S_OK;
483 484
}

485
static HRESULT WINAPI WebBrowser_put_Height(IWebBrowser2 *iface, LONG Height)
486
{
487
    WebBrowser *This = impl_from_IWebBrowser2(iface);
488 489
    RECT rect;

490
    TRACE("(%p)->(%d)\n", This, Height);
491 492 493 494

    if(!This->inplace)
        return E_UNEXPECTED;

495
    rect = This->pos_rect;
496 497
    rect.bottom = rect.top+Height;

498 499
    /* We don't really change the window size here.
     * We just notify the embedder that he should do so. */
500
    return IOleInPlaceSiteEx_OnPosRectChange(This->inplace, &rect);
501 502
}

503
static HRESULT WINAPI WebBrowser_get_LocationName(IWebBrowser2 *iface, BSTR *LocationName)
504
{
505
    WebBrowser *This = impl_from_IWebBrowser2(iface);
506 507
    FIXME("(%p)->(%p)\n", This, LocationName);
    return E_NOTIMPL;
508 509
}

510
static HRESULT WINAPI WebBrowser_get_LocationURL(IWebBrowser2 *iface, BSTR *LocationURL)
511
{
512
    WebBrowser *This = impl_from_IWebBrowser2(iface);
513

514
    TRACE("(%p)->(%p)\n", This, LocationURL);
515

516
    return get_location_url(&This->doc_host, LocationURL);
517 518
}

519
static HRESULT WINAPI WebBrowser_get_Busy(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
520
{
521
    WebBrowser *This = impl_from_IWebBrowser2(iface);
522 523 524 525 526

    TRACE("(%p)->(%p)\n", This, pBool);

    *pBool = This->doc_host.busy;
    return S_OK;
527 528
}

529 530
static HRESULT WINAPI WebBrowser_Quit(IWebBrowser2 *iface)
{
531
    WebBrowser *This = impl_from_IWebBrowser2(iface);
532 533 534 535 536

    TRACE("(%p)\n", This);

    /* It's a InternetExplorer specific method, we have nothing to do here. */
    return E_FAIL;
537
}
538

539 540
static HRESULT WINAPI WebBrowser_ClientToWindow(IWebBrowser2 *iface, int *pcx, int *pcy)
{
541
    WebBrowser *This = impl_from_IWebBrowser2(iface);
542 543 544 545 546 547
    FIXME("(%p)->(%p %p)\n", This, pcx, pcy);
    return E_NOTIMPL;
}

static HRESULT WINAPI WebBrowser_PutProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT vtValue)
{
548
    WebBrowser *This = impl_from_IWebBrowser2(iface);
549
    FIXME("(%p)->(%s %s)\n", This, debugstr_w(szProperty), debugstr_variant(&vtValue));
550 551 552 553 554
    return E_NOTIMPL;
}

static HRESULT WINAPI WebBrowser_GetProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT *pvtValue)
{
555
    WebBrowser *This = impl_from_IWebBrowser2(iface);
556
    FIXME("(%p)->(%s %s)\n", This, debugstr_w(szProperty), debugstr_variant(pvtValue));
557 558 559 560 561
    return E_NOTIMPL;
}

static HRESULT WINAPI WebBrowser_get_Name(IWebBrowser2 *iface, BSTR *Name)
{
562
    static const WCHAR sName[] = {'M','i','c','r','o','s','o','f','t',' ','W','e','b',
563
                                  ' ','B','r','o','w','s','e','r',' ','C','o','n','t','r','o','l',0};
564
    WebBrowser *This = impl_from_IWebBrowser2(iface);
565 566 567 568 569 570

    TRACE("(%p)->(%p)\n", This, Name);

    *Name = SysAllocString(sName);

    return S_OK;
571 572
}

573
static HRESULT WINAPI WebBrowser_get_HWND(IWebBrowser2 *iface, SHANDLE_PTR *pHWND)
574
{
575
    WebBrowser *This = impl_from_IWebBrowser2(iface);
576 577 578

    TRACE("(%p)->(%p)\n", This, pHWND);

579
    /* WebBrowser control never has a frame window (in opposition to InternetExplorer) */
580 581
    *pHWND = 0;
    return E_FAIL;
582 583 584 585
}

static HRESULT WINAPI WebBrowser_get_FullName(IWebBrowser2 *iface, BSTR *FullName)
{
586
    WebBrowser *This = impl_from_IWebBrowser2(iface);
587 588 589 590 591 592
    FIXME("(%p)->(%p)\n", This, FullName);
    return E_NOTIMPL;
}

static HRESULT WINAPI WebBrowser_get_Path(IWebBrowser2 *iface, BSTR *Path)
{
593
    WebBrowser *This = impl_from_IWebBrowser2(iface);
594 595 596 597 598 599
    FIXME("(%p)->(%p)\n", This, Path);
    return E_NOTIMPL;
}

static HRESULT WINAPI WebBrowser_get_Visible(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
{
600
    WebBrowser *This = impl_from_IWebBrowser2(iface);
601 602 603 604 605

    TRACE("(%p)->(%p)\n", This, pBool);

    *pBool = This->visible;
    return S_OK;
606 607 608 609
}

static HRESULT WINAPI WebBrowser_put_Visible(IWebBrowser2 *iface, VARIANT_BOOL Value)
{
610
    WebBrowser *This = impl_from_IWebBrowser2(iface);
611 612 613 614 615 616 617 618 619
    VARIANTARG arg;
    DISPPARAMS dispparams = {&arg, NULL, 1, 0};

    TRACE("(%p)->(%x)\n", This, Value);

    This->visible = Value;

    V_VT(&arg) = VT_BOOL;
    V_BOOL(&arg) = Value;
620
    call_sink(This->doc_host.cps.wbe2, DISPID_ONVISIBLE, &dispparams);
621 622

    return S_OK;
623 624 625 626
}

static HRESULT WINAPI WebBrowser_get_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
{
627
    WebBrowser *This = impl_from_IWebBrowser2(iface);
628 629 630 631 632

    TRACE("(%p)->(%p)\n", This, pBool);

    *pBool = This->status_bar;
    return S_OK;
633 634 635 636
}

static HRESULT WINAPI WebBrowser_put_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
{
637
    WebBrowser *This = impl_from_IWebBrowser2(iface);
638 639 640 641 642
    VARIANTARG arg;
    DISPPARAMS dispparams = {&arg, NULL, 1, 0};

    TRACE("(%p)->(%x)\n", This, Value);

643
    This->status_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;
644

645 646 647
    /* In opposition to InternetExplorer, all we should do here is
     * inform the embedder about the status bar change. */

648 649
    V_VT(&arg) = VT_BOOL;
    V_BOOL(&arg) = Value;
650
    call_sink(This->doc_host.cps.wbe2, DISPID_ONSTATUSBAR, &dispparams);
651 652

    return S_OK;
653 654 655 656
}

static HRESULT WINAPI WebBrowser_get_StatusText(IWebBrowser2 *iface, BSTR *StatusText)
{
657
    WebBrowser *This = impl_from_IWebBrowser2(iface);
658 659 660 661 662 663
    FIXME("(%p)->(%p)\n", This, StatusText);
    return E_NOTIMPL;
}

static HRESULT WINAPI WebBrowser_put_StatusText(IWebBrowser2 *iface, BSTR StatusText)
{
664
    WebBrowser *This = impl_from_IWebBrowser2(iface);
665 666 667 668 669 670
    FIXME("(%p)->(%s)\n", This, debugstr_w(StatusText));
    return E_NOTIMPL;
}

static HRESULT WINAPI WebBrowser_get_ToolBar(IWebBrowser2 *iface, int *Value)
{
671
    WebBrowser *This = impl_from_IWebBrowser2(iface);
672 673 674 675 676

    TRACE("(%p)->(%p)\n", This, Value);

    *Value = This->tool_bar;
    return S_OK;
677 678 679 680
}

static HRESULT WINAPI WebBrowser_put_ToolBar(IWebBrowser2 *iface, int Value)
{
681
    WebBrowser *This = impl_from_IWebBrowser2(iface);
682 683 684 685 686 687 688
    VARIANTARG arg;
    DISPPARAMS dispparams = {&arg, NULL, 1, 0};

    TRACE("(%p)->(%x)\n", This, Value);

    This->tool_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;

689 690 691
    /* In opposition to InternetExplorer, all we should do here is
     * inform the embedder about the tool bar change. */

692
    V_VT(&arg) = VT_BOOL;
693
    V_BOOL(&arg) = This->tool_bar;
694
    call_sink(This->doc_host.cps.wbe2, DISPID_ONTOOLBAR, &dispparams);
695 696

    return S_OK;
697 698 699 700
}

static HRESULT WINAPI WebBrowser_get_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL *Value)
{
701
    WebBrowser *This = impl_from_IWebBrowser2(iface);
702 703 704 705 706

    TRACE("(%p)->(%p)\n", This, Value);

    *Value = This->menu_bar;
    return S_OK;
707 708 709 710
}

static HRESULT WINAPI WebBrowser_put_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
{
711
    WebBrowser *This = impl_from_IWebBrowser2(iface);
712 713 714 715 716
    VARIANTARG arg;
    DISPPARAMS dispparams = {&arg, NULL, 1, 0};

    TRACE("(%p)->(%x)\n", This, Value);

717
    This->menu_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;
718

719 720 721
    /* In opposition to InternetExplorer, all we should do here is
     * inform the embedder about the menu bar change. */

722 723
    V_VT(&arg) = VT_BOOL;
    V_BOOL(&arg) = Value;
724
    call_sink(This->doc_host.cps.wbe2, DISPID_ONMENUBAR, &dispparams);
725 726

    return S_OK;
727 728 729 730
}

static HRESULT WINAPI WebBrowser_get_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL *pbFullScreen)
{
731
    WebBrowser *This = impl_from_IWebBrowser2(iface);
732 733 734 735 736

    TRACE("(%p)->(%p)\n", This, pbFullScreen);

    *pbFullScreen = This->full_screen;
    return S_OK;
737 738 739 740
}

static HRESULT WINAPI WebBrowser_put_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL bFullScreen)
{
741
    WebBrowser *This = impl_from_IWebBrowser2(iface);
742 743 744 745 746
    VARIANTARG arg;
    DISPPARAMS dispparams = {&arg, NULL, 1, 0};

    /* In opposition to InternetExplorer, all we should do here is
     * inform the embedder about the fullscreen change. */
747 748 749 750

    TRACE("(%p)->(%x)\n", This, bFullScreen);

    This->full_screen = bFullScreen ? VARIANT_TRUE : VARIANT_FALSE;
751 752 753 754 755

    V_VT(&arg) = VT_BOOL;
    V_BOOL(&arg) = bFullScreen;
    call_sink(This->doc_host.cps.wbe2, DISPID_ONFULLSCREEN, &dispparams);

756
    return S_OK;
757 758 759 760 761
}

static HRESULT WINAPI WebBrowser_Navigate2(IWebBrowser2 *iface, VARIANT *URL, VARIANT *Flags,
        VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
{
762
    WebBrowser *This = impl_from_IWebBrowser2(iface);
763
    LPCWSTR url;
764

765 766
    TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_variant(URL), debugstr_variant(Flags),
          debugstr_variant(TargetFrameName), debugstr_variant(PostData), debugstr_variant(Headers));
767 768 769 770

    if(!This->client)
        return E_FAIL;

771 772
    if(!URL)
        return S_OK;
773

774 775 776 777 778 779 780 781 782
    switch (V_VT(URL))
    {
    case VT_BSTR:
        url = V_BSTR(URL);
        break;
    case VT_BSTR|VT_BYREF:
        url = *V_BSTRREF(URL);
        break;
    default:
783
        FIXME("Unsupported V_VT(URL) %d\n", V_VT(URL));
784
        return E_INVALIDARG;
785 786
    }

787
    return navigate_url(&This->doc_host, url, Flags, TargetFrameName, PostData, Headers);
788 789 790 791
}

static HRESULT WINAPI WebBrowser_QueryStatusWB(IWebBrowser2 *iface, OLECMDID cmdID, OLECMDF *pcmdf)
{
792
    WebBrowser *This = impl_from_IWebBrowser2(iface);
793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811
    IOleCommandTarget *target = NULL;
    OLECMD ole_command[1];
    HRESULT hres;

    TRACE("(%p)->(%d %p)\n", This, cmdID, pcmdf);

    if (!pcmdf)
        return E_POINTER;
    ole_command[0].cmdID = cmdID;
    ole_command[0].cmdf = *pcmdf;

    if (This->container)
    {
        hres = IOleContainer_QueryInterface(This->container, &IID_IOleCommandTarget, (LPVOID*)&target);
        if(FAILED(hres))
            target = NULL;
    }
    if (!target && This->doc_host.document)
    {
812
        hres = IUnknown_QueryInterface(This->doc_host.document, &IID_IOleCommandTarget, (LPVOID*)&target);
813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830
        if(FAILED(hres))
            target = NULL;
    }

    if (!target)
        return E_UNEXPECTED;

    hres = IOleCommandTarget_QueryStatus(target, NULL, 1, ole_command, NULL);
    if (SUCCEEDED(hres))
        *pcmdf = ole_command[0].cmdf;
    if (hres == OLECMDERR_E_NOTSUPPORTED)
    {
        *pcmdf = 0;
        hres = S_OK;
    }
    IOleCommandTarget_Release(target);

    return hres;
831 832 833 834 835
}

static HRESULT WINAPI WebBrowser_ExecWB(IWebBrowser2 *iface, OLECMDID cmdID,
        OLECMDEXECOPT cmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
{
836
    WebBrowser *This = impl_from_IWebBrowser2(iface);
837 838 839 840 841 842 843 844 845 846 847 848 849
    IOleCommandTarget *target = NULL;
    HRESULT hres;

    TRACE("(%p)->(%d %d %s %p)\n", This, cmdID, cmdexecopt, debugstr_variant(pvaIn), pvaOut);

    if(This->container)
    {
        hres = IOleContainer_QueryInterface(This->container, &IID_IOleCommandTarget, (LPVOID*)&target);
        if(FAILED(hres))
            target = NULL;
    }
    if(!target && This->doc_host.document)
    {
850
        hres = IUnknown_QueryInterface(This->doc_host.document, &IID_IOleCommandTarget, (LPVOID*)&target);
851 852 853 854 855 856 857 858 859 860 861
        if(FAILED(hres))
            target = NULL;
    }

    if(!target)
        return E_UNEXPECTED;

    hres = IOleCommandTarget_Exec(target, NULL, cmdID, cmdexecopt, pvaIn, pvaOut);
    IOleCommandTarget_Release(target);

    return hres;
862 863 864 865 866
}

static HRESULT WINAPI WebBrowser_ShowBrowserBar(IWebBrowser2 *iface, VARIANT *pvaClsid,
        VARIANT *pvarShow, VARIANT *pvarSize)
{
867
    WebBrowser *This = impl_from_IWebBrowser2(iface);
868 869
    FIXME("(%p)->(%s %s %s)\n", This, debugstr_variant(pvaClsid), debugstr_variant(pvarShow),
          debugstr_variant(pvarSize));
870 871 872 873 874
    return E_NOTIMPL;
}

static HRESULT WINAPI WebBrowser_get_ReadyState(IWebBrowser2 *iface, READYSTATE *lpReadyState)
{
875
    WebBrowser *This = impl_from_IWebBrowser2(iface);
876

877 878 879
    TRACE("(%p)->(%p)\n", This, lpReadyState);

    *lpReadyState = This->doc_host.ready_state;
880
    return S_OK;
881 882 883 884
}

static HRESULT WINAPI WebBrowser_get_Offline(IWebBrowser2 *iface, VARIANT_BOOL *pbOffline)
{
885
    WebBrowser *This = impl_from_IWebBrowser2(iface);
886 887 888

    TRACE("(%p)->(%p)\n", This, pbOffline);

889
    *pbOffline = This->doc_host.offline;
890
    return S_OK;
891 892 893 894
}

static HRESULT WINAPI WebBrowser_put_Offline(IWebBrowser2 *iface, VARIANT_BOOL bOffline)
{
895
    WebBrowser *This = impl_from_IWebBrowser2(iface);
896 897 898

    TRACE("(%p)->(%x)\n", This, bOffline);

899
    This->doc_host.offline = bOffline ? VARIANT_TRUE : VARIANT_FALSE;
900
    return S_OK;
901 902 903 904
}

static HRESULT WINAPI WebBrowser_get_Silent(IWebBrowser2 *iface, VARIANT_BOOL *pbSilent)
{
905
    WebBrowser *This = impl_from_IWebBrowser2(iface);
906 907 908

    TRACE("(%p)->(%p)\n", This, pbSilent);

909
    *pbSilent = This->doc_host.silent;
910
    return S_OK;
911 912 913 914
}

static HRESULT WINAPI WebBrowser_put_Silent(IWebBrowser2 *iface, VARIANT_BOOL bSilent)
{
915
    WebBrowser *This = impl_from_IWebBrowser2(iface);
916 917 918

    TRACE("(%p)->(%x)\n", This, bSilent);

919
    This->doc_host.silent = bSilent ? VARIANT_TRUE : VARIANT_FALSE;
920
    return S_OK;
921 922 923 924 925
}

static HRESULT WINAPI WebBrowser_get_RegisterAsBrowser(IWebBrowser2 *iface,
        VARIANT_BOOL *pbRegister)
{
926
    WebBrowser *This = impl_from_IWebBrowser2(iface);
927

928
    FIXME("(%p)->(%p)\n", This, pbRegister);
929 930 931

    *pbRegister = This->register_browser;
    return S_OK;
932 933 934 935 936
}

static HRESULT WINAPI WebBrowser_put_RegisterAsBrowser(IWebBrowser2 *iface,
        VARIANT_BOOL bRegister)
{
937
    WebBrowser *This = impl_from_IWebBrowser2(iface);
938

939
    FIXME("(%p)->(%x)\n", This, bRegister);
940 941 942

    This->register_browser = bRegister ? VARIANT_TRUE : VARIANT_FALSE;
    return S_OK;
943 944 945 946 947
}

static HRESULT WINAPI WebBrowser_get_RegisterAsDropTarget(IWebBrowser2 *iface,
        VARIANT_BOOL *pbRegister)
{
948
    WebBrowser *This = impl_from_IWebBrowser2(iface);
949

950
    FIXME("(%p)->(%p)\n", This, pbRegister);
951 952 953 954

    if(!pbRegister)
        return E_INVALIDARG;

955 956
    *pbRegister=0;
    return S_OK;
957 958 959 960 961
}

static HRESULT WINAPI WebBrowser_put_RegisterAsDropTarget(IWebBrowser2 *iface,
        VARIANT_BOOL bRegister)
{
962
    WebBrowser *This = impl_from_IWebBrowser2(iface);
963
    FIXME("(%p)->(%x)\n", This, bRegister);
964
    return S_OK;
965 966 967 968
}

static HRESULT WINAPI WebBrowser_get_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL *pbRegister)
{
969
    WebBrowser *This = impl_from_IWebBrowser2(iface);
970 971 972 973 974

    TRACE("(%p)->(%p)\n", This, pbRegister);

    *pbRegister = This->theater_mode;
    return S_OK;
975 976 977 978
}

static HRESULT WINAPI WebBrowser_put_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL bRegister)
{
979
    WebBrowser *This = impl_from_IWebBrowser2(iface);
980 981 982 983 984 985 986 987 988 989 990 991 992 993 994
    VARIANTARG arg;
    DISPPARAMS dispparams = {&arg, NULL, 1, 0};

    TRACE("(%p)->(%x)\n", This, bRegister);

    This->theater_mode = bRegister ? VARIANT_TRUE : VARIANT_FALSE;

    /* In opposition to InternetExplorer, all we should do here is
     * inform the embedder about the theater mode change. */

    V_VT(&arg) = VT_BOOL;
    V_BOOL(&arg) = bRegister;
    call_sink(This->doc_host.cps.wbe2, DISPID_ONTHEATERMODE, &dispparams);

    return S_OK;
995 996 997 998
}

static HRESULT WINAPI WebBrowser_get_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL *Value)
{
999
    WebBrowser *This = impl_from_IWebBrowser2(iface);
1000 1001 1002 1003 1004

    TRACE("(%p)->(%p)\n", This, Value);

    *Value = This->address_bar;
    return S_OK;
1005 1006 1007 1008
}

static HRESULT WINAPI WebBrowser_put_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
{
1009
    WebBrowser *This = impl_from_IWebBrowser2(iface);
1010 1011 1012 1013 1014
    VARIANTARG arg;
    DISPPARAMS dispparams = {&arg, NULL, 1, 0};

    TRACE("(%p)->(%x)\n", This, Value);

1015
    This->address_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;
1016

1017 1018 1019
    /* In opposition to InternetExplorer, all we should do here is
     * inform the embedder about the address bar change. */

1020 1021
    V_VT(&arg) = VT_BOOL;
    V_BOOL(&arg) = Value;
1022
    call_sink(This->doc_host.cps.wbe2, DISPID_ONADDRESSBAR, &dispparams);
1023 1024

    return S_OK;
1025 1026 1027 1028
}

static HRESULT WINAPI WebBrowser_get_Resizable(IWebBrowser2 *iface, VARIANT_BOOL *Value)
{
1029
    WebBrowser *This = impl_from_IWebBrowser2(iface);
1030 1031 1032 1033

    TRACE("(%p)->(%p)\n", This, Value);

    /* It's InternetExplorer object's method. We have nothing to do here. */
1034 1035 1036 1037 1038
    return E_NOTIMPL;
}

static HRESULT WINAPI WebBrowser_put_Resizable(IWebBrowser2 *iface, VARIANT_BOOL Value)
{
1039
    WebBrowser *This = impl_from_IWebBrowser2(iface);
1040 1041
    VARIANTARG arg;
    DISPPARAMS dispparams = {&arg, NULL, 1, 0};
1042 1043 1044

    TRACE("(%p)->(%x)\n", This, Value);

1045 1046 1047 1048 1049 1050 1051
    /* In opposition to InternetExplorer, all we should do here is
     * inform the embedder about the resizable change. */

    V_VT(&arg) = VT_BOOL;
    V_BOOL(&arg) = Value;
    call_sink(This->doc_host.cps.wbe2, DISPID_WINDOWSETRESIZABLE, &dispparams);

1052
    return S_OK;
1053 1054 1055
}

static const IWebBrowser2Vtbl WebBrowser2Vtbl =
1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087
{
    WebBrowser_QueryInterface,
    WebBrowser_AddRef,
    WebBrowser_Release,
    WebBrowser_GetTypeInfoCount,
    WebBrowser_GetTypeInfo,
    WebBrowser_GetIDsOfNames,
    WebBrowser_Invoke,
    WebBrowser_GoBack,
    WebBrowser_GoForward,
    WebBrowser_GoHome,
    WebBrowser_GoSearch,
    WebBrowser_Navigate,
    WebBrowser_Refresh,
    WebBrowser_Refresh2,
    WebBrowser_Stop,
    WebBrowser_get_Application,
    WebBrowser_get_Parent,
    WebBrowser_get_Container,
    WebBrowser_get_Document,
    WebBrowser_get_TopLevelContainer,
    WebBrowser_get_Type,
    WebBrowser_get_Left,
    WebBrowser_put_Left,
    WebBrowser_get_Top,
    WebBrowser_put_Top,
    WebBrowser_get_Width,
    WebBrowser_put_Width,
    WebBrowser_get_Height,
    WebBrowser_put_Height,
    WebBrowser_get_LocationName,
    WebBrowser_get_LocationURL,
1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127
    WebBrowser_get_Busy,
    WebBrowser_Quit,
    WebBrowser_ClientToWindow,
    WebBrowser_PutProperty,
    WebBrowser_GetProperty,
    WebBrowser_get_Name,
    WebBrowser_get_HWND,
    WebBrowser_get_FullName,
    WebBrowser_get_Path,
    WebBrowser_get_Visible,
    WebBrowser_put_Visible,
    WebBrowser_get_StatusBar,
    WebBrowser_put_StatusBar,
    WebBrowser_get_StatusText,
    WebBrowser_put_StatusText,
    WebBrowser_get_ToolBar,
    WebBrowser_put_ToolBar,
    WebBrowser_get_MenuBar,
    WebBrowser_put_MenuBar,
    WebBrowser_get_FullScreen,
    WebBrowser_put_FullScreen,
    WebBrowser_Navigate2,
    WebBrowser_QueryStatusWB,
    WebBrowser_ExecWB,
    WebBrowser_ShowBrowserBar,
    WebBrowser_get_ReadyState,
    WebBrowser_get_Offline,
    WebBrowser_put_Offline,
    WebBrowser_get_Silent,
    WebBrowser_put_Silent,
    WebBrowser_get_RegisterAsBrowser,
    WebBrowser_put_RegisterAsBrowser,
    WebBrowser_get_RegisterAsDropTarget,
    WebBrowser_put_RegisterAsDropTarget,
    WebBrowser_get_TheaterMode,
    WebBrowser_put_TheaterMode,
    WebBrowser_get_AddressBar,
    WebBrowser_put_AddressBar,
    WebBrowser_get_Resizable,
    WebBrowser_put_Resizable
1128 1129
};

1130 1131
static inline WebBrowser *impl_from_IServiceProvider(IServiceProvider *iface)
{
1132
    return CONTAINING_RECORD(iface, WebBrowser, IServiceProvider_iface);
1133 1134 1135
}

static HRESULT WINAPI WBServiceProvider_QueryInterface(IServiceProvider *iface,
1136 1137
            REFIID riid, LPVOID *ppv)
{
1138
    WebBrowser *This = impl_from_IServiceProvider(iface);
1139
    return IWebBrowser2_QueryInterface(&This->IWebBrowser2_iface, riid, ppv);
1140 1141
}

1142
static ULONG WINAPI WBServiceProvider_AddRef(IServiceProvider *iface)
1143
{
1144
    WebBrowser *This = impl_from_IServiceProvider(iface);
1145
    return IWebBrowser2_AddRef(&This->IWebBrowser2_iface);
1146 1147
}

1148
static ULONG WINAPI WBServiceProvider_Release(IServiceProvider *iface)
1149
{
1150
    WebBrowser *This = impl_from_IServiceProvider(iface);
1151
    return IWebBrowser2_Release(&This->IWebBrowser2_iface);
1152 1153
}

1154
static HRESULT STDMETHODCALLTYPE WBServiceProvider_QueryService(IServiceProvider *iface,
1155 1156
            REFGUID guidService, REFIID riid, void **ppv)
{
1157
    WebBrowser *This = impl_from_IServiceProvider(iface);
1158

1159 1160 1161 1162
    if(IsEqualGUID(&SID_SHTMLWindow, riid)) {
        TRACE("(%p)->(SID_SHTMLWindow)\n", This);
        return IHTMLWindow2_QueryInterface(&This->doc_host.html_window.IHTMLWindow2_iface, riid, ppv);
    }
1163 1164 1165

    if(IsEqualGUID(&IID_IBrowserService2, riid)) {
        TRACE("(%p)->(IID_IBrowserService2 return E_FAIL)\n", This);
1166
        *ppv = NULL;
1167 1168 1169 1170
        return E_FAIL;
    }

    FIXME("(%p)->(%s, %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
1171
    *ppv = NULL;
1172 1173 1174 1175 1176
    return E_NOINTERFACE;
}

static const IServiceProviderVtbl ServiceProviderVtbl =
{
1177 1178 1179 1180
    WBServiceProvider_QueryInterface,
    WBServiceProvider_AddRef,
    WBServiceProvider_Release,
    WBServiceProvider_QueryService
1181 1182
};

1183 1184
static inline WebBrowser *impl_from_DocHost(DocHost *iface)
{
1185
    return CONTAINING_RECORD(iface, WebBrowser, doc_host);
1186
}
1187

1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199
static ULONG WebBrowser_addref(DocHost *iface)
{
    WebBrowser *This = impl_from_DocHost(iface);
    return IWebBrowser2_AddRef(&This->IWebBrowser2_iface);
}

static ULONG WebBrowser_release(DocHost *iface)
{
    WebBrowser *This = impl_from_DocHost(iface);
    return IWebBrowser2_Release(&This->IWebBrowser2_iface);
}

1200
static void DocHostContainer_get_docobj_rect(DocHost *This, RECT *rc)
1201 1202 1203 1204
{
    GetClientRect(This->frame_hwnd, rc);
}

1205
static HRESULT DocHostContainer_set_status_text(DocHost *This, const WCHAR *text)
1206 1207 1208 1209
{
    return E_NOTIMPL;
}

1210 1211 1212 1213
static void DocHostContainer_on_command_state_change(DocHost *This, LONG command, BOOL enable)
{
}

1214
static void DocHostContainer_set_url(DocHost *This, const WCHAR *url)
1215 1216 1217 1218
{
}

static const IDocHostContainerVtbl DocHostContainerVtbl = {
1219 1220
    WebBrowser_addref,
    WebBrowser_release,
1221 1222
    DocHostContainer_get_docobj_rect,
    DocHostContainer_set_status_text,
1223
    DocHostContainer_on_command_state_change,
1224
    DocHostContainer_set_url
1225 1226
};

1227
static HRESULT create_webbrowser(int version, IUnknown *outer, REFIID riid, void **ppv)
1228 1229 1230 1231
{
    WebBrowser *ret;
    HRESULT hres;

1232
    TRACE("(%p %s %p) version=%d\n", outer, debugstr_guid(riid), ppv, version);
1233

1234
    ret = heap_alloc_zero(sizeof(WebBrowser));
1235

1236
    ret->IWebBrowser2_iface.lpVtbl = &WebBrowser2Vtbl;
1237
    ret->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
1238
    ret->ref = 1;
1239
    ret->version = version;
1240

1241
    DocHost_Init(&ret->doc_host, &ret->IWebBrowser2_iface, &DocHostContainerVtbl);
1242

1243
    ret->visible = VARIANT_TRUE;
1244
    ret->menu_bar = VARIANT_TRUE;
1245
    ret->address_bar = VARIANT_TRUE;
1246
    ret->status_bar = VARIANT_TRUE;
1247
    ret->tool_bar = VARIANT_TRUE;
1248

1249
    WebBrowser_OleObject_Init(ret);
1250
    WebBrowser_ViewObject_Init(ret);
1251
    WebBrowser_Persist_Init(ret);
1252
    WebBrowser_ClassInfo_Init(ret);
1253

1254
    HlinkFrame_Init(&ret->hlink_frame, (IUnknown*)&ret->IWebBrowser2_iface, &ret->doc_host);
1255

1256
    lock_module();
1257

1258
    hres = IWebBrowser2_QueryInterface(&ret->IWebBrowser2_iface, riid, ppv);
1259

1260
    IWebBrowser2_Release(&ret->IWebBrowser2_iface);
1261 1262
    return hres;
}
1263

1264
HRESULT WINAPI WebBrowserV1_Create(IClassFactory *iface, IUnknown *pOuter, REFIID riid, void **ppv)
1265
{
1266
    return create_webbrowser(1, pOuter, riid, ppv);
1267 1268
}

1269
HRESULT WINAPI WebBrowser_Create(IClassFactory *iface, IUnknown *pOuter, REFIID riid, void **ppv)
1270
{
1271
    return create_webbrowser(2, pOuter, riid, ppv);
1272
}