oleobject.c 26.7 KB
Newer Older
1
/*
2
 * Implementation of IOleObject interfaces for WebBrowser control
3 4 5 6 7 8
 *
 * - IOleObject
 * - IOleInPlaceObject
 * - IOleControl
 *
 * Copyright 2001 John R. Sheets (for CodeWeavers)
9
 * Copyright 2005 Jacek Caban
10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * 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
23
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 25 26 27 28
 */

#include <string.h>
#include "wine/debug.h"
#include "shdocvw.h"
29
#include "htiframe.h"
30
#include "idispids.h"
31 32 33

WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);

34 35 36
/* shlwapi.dll */
HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent);

37 38
static ATOM shell_embedding_atom = 0;

Jacek Caban's avatar
Jacek Caban committed
39 40
static LRESULT resize_window(WebBrowser *This, LONG width, LONG height)
{
41 42
    if(This->doc_host.hwnd)
        SetWindowPos(This->doc_host.hwnd, NULL, 0, 0, width, height,
Jacek Caban's avatar
Jacek Caban committed
43 44 45 46 47
                     SWP_NOZORDER | SWP_NOACTIVATE);

    return 0;
}

48 49
static LRESULT WINAPI shell_embedding_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Jacek Caban's avatar
Jacek Caban committed
50 51 52 53 54 55 56 57 58 59 60 61 62 63
    WebBrowser *This;

    static const WCHAR wszTHIS[] = {'T','H','I','S',0};

    if(msg == WM_CREATE) {
        This = *(WebBrowser**)lParam;
        SetPropW(hwnd, wszTHIS, This);
    }else {
        This = GetPropW(hwnd, wszTHIS);
    }

    switch(msg) {
    case WM_SIZE:
        return resize_window(This, LOWORD(lParam), HIWORD(lParam));
64 65
    case WM_DOCHOSTTASK:
        return process_dochost_task(&This->doc_host, lParam);
Jacek Caban's avatar
Jacek Caban committed
66 67
    }

68
    return DefWindowProcW(hwnd, msg, wParam, lParam);
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
}

static void create_shell_embedding_hwnd(WebBrowser *This)
{
    IOleInPlaceSite *inplace;
    HWND parent = NULL;
    HRESULT hres;

    static const WCHAR wszShellEmbedding[] =
        {'S','h','e','l','l',' ','E','m','b','e','d','d','i','n','g',0};

    if(!shell_embedding_atom) {
        static WNDCLASSEXW wndclass = {
            sizeof(wndclass),
            CS_DBLCLKS,
            shell_embedding_proc,
            0, 0 /* native uses 8 */, NULL, NULL, NULL,
            (HBRUSH)COLOR_WINDOWFRAME, NULL,
            wszShellEmbedding,
            NULL
        };
        wndclass.hInstance = shdocvw_hinstance;

        RegisterClassExW(&wndclass);
    }

    hres = IOleClientSite_QueryInterface(This->client, &IID_IOleInPlaceSite, (void**)&inplace);
    if(SUCCEEDED(hres)) {
        IOleInPlaceSite_GetWindow(inplace, &parent);
        IOleInPlaceSite_Release(inplace);
    }

101
    This->doc_host.frame_hwnd = This->shell_embedding_hwnd = CreateWindowExW(
102 103
            WS_EX_WINDOWEDGE,
            wszShellEmbedding, wszShellEmbedding,
104 105
            WS_CLIPSIBLINGS | WS_CLIPCHILDREN
            | (parent ? WS_CHILD | WS_TABSTOP : WS_POPUP | WS_MAXIMIZEBOX),
106 107
            0, 0, 0, 0, parent,
            NULL, shdocvw_hinstance, This);
108 109

    TRACE("parent=%p hwnd=%p\n", parent, This->shell_embedding_hwnd);
110 111
}

112
static HRESULT activate_inplace(WebBrowser *This, IOleClientSite *active_site)
113
{
114
    HWND parent_hwnd;
115 116
    HRESULT hres;

117 118 119
    if(This->inplace)
        return S_OK;

120 121 122 123 124 125 126 127 128 129 130 131
    if(!active_site)
        return E_INVALIDARG;

    hres = IOleClientSite_QueryInterface(active_site, &IID_IOleInPlaceSite,
                                         (void**)&This->inplace);
    if(FAILED(hres)) {
        WARN("Could not get IOleInPlaceSite\n");
        return hres;
    }

    hres = IOleInPlaceSite_CanInPlaceActivate(This->inplace);
    if(hres != S_OK) {
132
        WARN("CanInPlaceActivate returned: %08x\n", hres);
133 134 135 136
        IOleInPlaceSite_Release(This->inplace);
        return E_FAIL;
    }

137 138 139
    hres = IOleInPlaceSite_GetWindow(This->inplace, &parent_hwnd);
    if(SUCCEEDED(hres))
        SHSetParentHwnd(This->shell_embedding_hwnd, parent_hwnd);
140 141 142

    IOleInPlaceSite_OnInPlaceActivate(This->inplace);

143
    IOleInPlaceSite_GetWindowContext(This->inplace, &This->doc_host.frame, &This->uiwindow,
144 145 146 147 148 149 150 151 152 153 154 155 156 157
                                     &This->pos_rect, &This->clip_rect,
                                     &This->frameinfo);

    SetWindowPos(This->shell_embedding_hwnd, NULL,
                 This->pos_rect.left, This->pos_rect.top,
                 This->pos_rect.right-This->pos_rect.left,
                 This->pos_rect.bottom-This->pos_rect.top,
                 SWP_NOZORDER | SWP_SHOWWINDOW);

    if(This->client) {
        IOleClientSite_ShowObject(This->client);
        IOleClientSite_GetContainer(This->client, &This->container);
    }

158 159
    if(This->doc_host.frame)
        IOleInPlaceFrame_GetWindow(This->doc_host.frame, &This->frame_hwnd);
160 161 162 163

    return S_OK;
}

164
static HRESULT activate_ui(WebBrowser *This, IOleClientSite *active_site)
165 166 167 168 169
{
    HRESULT hres;

    static const WCHAR wszitem[] = {'i','t','e','m',0};

170
    if(This->inplace)
171 172 173
    {
        if(This->shell_embedding_hwnd)
            ShowWindow(This->shell_embedding_hwnd, SW_SHOW);
174
        return S_OK;
175
    }
176

177
    hres = activate_inplace(This, active_site);
178 179 180 181 182
    if(FAILED(hres))
        return hres;

    IOleInPlaceSite_OnUIActivate(This->inplace);

183 184
    if(This->doc_host.frame)
        IOleInPlaceFrame_SetActiveObject(This->doc_host.frame, ACTIVEOBJ(This), wszitem);
185 186 187
    if(This->uiwindow)
        IOleInPlaceUIWindow_SetActiveObject(This->uiwindow, ACTIVEOBJ(This), wszitem);

188 189
    if(This->doc_host.frame)
        IOleInPlaceFrame_SetMenu(This->doc_host.frame, NULL, NULL, This->shell_embedding_hwnd);
190

191 192
    SetFocus(This->shell_embedding_hwnd);

193 194 195
    return S_OK;
}

196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
static HRESULT get_client_disp_property(IOleClientSite *client, DISPID dispid, VARIANT *res)
{
    IDispatch *disp = NULL;
    DISPPARAMS dispparams = {NULL, 0};
    HRESULT hres;

    VariantInit(res);

    if(!client)
        return S_OK;

    hres = IOleClientSite_QueryInterface(client, &IID_IDispatch, (void**)&disp);
    if(FAILED(hres)) {
        TRACE("Could not get IDispatch\n");
        return hres;
    }

    hres = IDispatch_Invoke(disp, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
            DISPATCH_PROPERTYGET, &dispparams, res, NULL, NULL);

    IDispatch_Release(disp);

    return hres;
}

221 222 223 224 225 226 227 228 229 230 231 232 233 234
static HRESULT on_offlineconnected_change(WebBrowser *This)
{
    VARIANT offline;

    get_client_disp_property(This->client, DISPID_AMBIENT_OFFLINEIFNOTCONNECTED, &offline);

    if(V_VT(&offline) == VT_BOOL)
        IWebBrowser2_put_Offline(WEBBROWSER2(This), V_BOOL(&offline));
    else if(V_VT(&offline) != VT_EMPTY)
        WARN("wrong V_VT(silent) %d\n", V_VT(&offline));

    return S_OK;
}

235 236 237 238 239 240 241 242 243 244 245 246 247 248
static HRESULT on_silent_change(WebBrowser *This)
{
    VARIANT silent;

    get_client_disp_property(This->client, DISPID_AMBIENT_SILENT, &silent);

    if(V_VT(&silent) == VT_BOOL)
        IWebBrowser2_put_Silent(WEBBROWSER2(This), V_BOOL(&silent));
    else if(V_VT(&silent) != VT_EMPTY)
        WARN("wrong V_VT(silent) %d\n", V_VT(&silent));

    return S_OK;
}

249
/**********************************************************************
250
 * Implement the IOleObject interface for the WebBrowser control
251 252
 */

253
#define OLEOBJ_THIS(iface) DEFINE_THIS(WebBrowser, OleObject, iface)
254

255
static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
256
{
257 258
    WebBrowser *This = OLEOBJ_THIS(iface);
    return IWebBrowser_QueryInterface(WEBBROWSER(This), riid, ppv);
259 260
}

261
static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
262
{
263 264
    WebBrowser *This = OLEOBJ_THIS(iface);
    return IWebBrowser_AddRef(WEBBROWSER(This));
265 266
}

267
static ULONG WINAPI OleObject_Release(IOleObject *iface)
268
{
269 270
    WebBrowser *This = OLEOBJ_THIS(iface);
    return IWebBrowser_Release(WEBBROWSER(This));
271 272
}

273
static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, LPOLECLIENTSITE pClientSite)
274
{
275
    WebBrowser *This = OLEOBJ_THIS(iface);
276
    IOleContainer *container;
277
    HRESULT hres;
278 279 280 281 282 283

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

    if(This->client == pClientSite)
        return S_OK;

284 285 286
    if(This->doc_host.hwnd) {
        DestroyWindow(This->doc_host.hwnd);
        This->doc_host.hwnd = NULL;
287 288
    }
    if(This->shell_embedding_hwnd) {
289
        DestroyWindow(This->shell_embedding_hwnd);
290 291
        This->shell_embedding_hwnd = NULL;
    }
292

293 294 295 296 297
    if(This->inplace) {
        IOleInPlaceSite_Release(This->inplace);
        This->inplace = NULL;
    }

298
    if(This->doc_host.hostui) {
299
        IDocHostUIHandler_Release(This->doc_host.hostui);
300 301 302
        This->doc_host.hostui = NULL;
    }

303 304 305
    if(This->client)
        IOleClientSite_Release(This->client);

306 307
    This->client = pClientSite;

308
    if(!pClientSite) {
309
        if(This->doc_host.document)
310
            deactivate_document(&This->doc_host);
311
        return S_OK;
312
    }
313

314 315
    IOleClientSite_AddRef(pClientSite);

316 317 318
    IOleClientSite_QueryInterface(This->client, &IID_IDispatch,
                                  (void**)&This->doc_host.client_disp);

319 320
    IOleClientSite_QueryInterface(This->client, &IID_IDocHostUIHandler,
                                  (void**)&This->doc_host.hostui);
321

322 323 324 325 326 327 328 329 330 331 332 333 334 335
    hres = IOleClientSite_GetContainer(This->client, &container);
    if(SUCCEEDED(hres)) {
        ITargetContainer *target_container;

        hres = IOleContainer_QueryInterface(container, &IID_ITargetContainer,
                                            (void**)&target_container);
        if(SUCCEEDED(hres)) {
            FIXME("Unsupported ITargetContainer\n");
            ITargetContainer_Release(target_container);
        }

        IOleContainer_Release(container);
    }

336 337
    create_shell_embedding_hwnd(This);

338 339 340
    on_offlineconnected_change(This);
    on_silent_change(This);

341
    return S_OK;
342 343
}

344
static HRESULT WINAPI OleObject_GetClientSite(IOleObject *iface, LPOLECLIENTSITE *ppClientSite)
345
{
346
    WebBrowser *This = OLEOBJ_THIS(iface);
347 348 349 350 351 352 353 354 355 356 357

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

    if(!ppClientSite)
        return E_INVALIDARG;

    if(This->client)
        IOleClientSite_AddRef(This->client);
    *ppClientSite = This->client;

    return S_OK;
358 359
}

360 361
static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR szContainerApp,
        LPCOLESTR szContainerObj)
362
{
363
    WebBrowser *This = OLEOBJ_THIS(iface);
364 365 366 367 368

    TRACE("(%p)->(%s, %s)\n", This, debugstr_w(szContainerApp), debugstr_w(szContainerObj));

    /* We have nothing to do here. */
    return S_OK;
369 370
}

371
static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD dwSaveOption)
372
{
373
    WebBrowser *This = OLEOBJ_THIS(iface);
374
    FIXME("(%p)->(%d)\n", This, dwSaveOption);
375
    return E_NOTIMPL;
376 377
}

378
static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD dwWhichMoniker, IMoniker* pmk)
379
{
380
    WebBrowser *This = OLEOBJ_THIS(iface);
381
    FIXME("(%p)->(%d, %p)\n", This, dwWhichMoniker, pmk);
382
    return E_NOTIMPL;
383 384
}

385 386
static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD dwAssign,
        DWORD dwWhichMoniker, LPMONIKER *ppmk)
387
{
388
    WebBrowser *This = OLEOBJ_THIS(iface);
389
    FIXME("(%p)->(%d, %d, %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
390
    return E_NOTIMPL;
391 392
}

393 394
static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, LPDATAOBJECT pDataObject,
        BOOL fCreation, DWORD dwReserved)
395
{
396
    WebBrowser *This = OLEOBJ_THIS(iface);
397
    FIXME("(%p)->(%p, %d, %d)\n", This, pDataObject, fCreation, dwReserved);
398
    return E_NOTIMPL;
399 400
}

401 402
static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD dwReserved,
        LPDATAOBJECT *ppDataObject)
403
{
404
    WebBrowser *This = OLEOBJ_THIS(iface);
405
    FIXME("(%p)->(%d, %p)\n", This, dwReserved, ppDataObject);
406
    return E_NOTIMPL;
407 408
}

409 410
static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, struct tagMSG* lpmsg,
        LPOLECLIENTSITE pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
411
{
412
    WebBrowser *This = OLEOBJ_THIS(iface);
413

414
    TRACE("(%p)->(%d %p %p %d %p %p)\n", This, iVerb, lpmsg, pActiveSite, lindex, hwndParent,
415
            lprcPosRect);
416

417 418
    switch (iVerb)
    {
419 420
    case OLEIVERB_SHOW:
        TRACE("OLEIVERB_SHOW\n");
421
        return activate_ui(This, pActiveSite);
422 423
    case OLEIVERB_UIACTIVATE:
        TRACE("OLEIVERB_UIACTIVATE\n");
424
        return activate_ui(This, pActiveSite);
425
    case OLEIVERB_INPLACEACTIVATE:
426
        TRACE("OLEIVERB_INPLACEACTIVATE\n");
427
        return activate_inplace(This, pActiveSite);
428 429
    case OLEIVERB_HIDE:
        TRACE("OLEIVERB_HIDE\n");
430 431
        if(This->shell_embedding_hwnd)
            ShowWindow(This->shell_embedding_hwnd, SW_HIDE);
432
        return S_OK;
433
    default:
434
        FIXME("stub for %d\n", iVerb);
435 436 437
        break;
    }

438
    return E_NOTIMPL;
439 440
}

441
static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **ppEnumOleVerb)
442
{
443 444
    WebBrowser *This = OLEOBJ_THIS(iface);
    TRACE("(%p)->(%p)\n", This, ppEnumOleVerb);
445 446 447
    return OleRegEnumVerbs(&CLSID_WebBrowser, ppEnumOleVerb);
}

448
static HRESULT WINAPI OleObject_Update(IOleObject *iface)
449
{
450 451
    WebBrowser *This = OLEOBJ_THIS(iface);
    FIXME("(%p)\n", This);
452 453 454
    return E_NOTIMPL;
}

455
static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
456
{
457 458 459
    WebBrowser *This = OLEOBJ_THIS(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
460 461
}

462
static HRESULT WINAPI OleObject_GetUserClassID(IOleObject *iface, CLSID* pClsid)
463
{
464 465 466
    WebBrowser *This = OLEOBJ_THIS(iface);
    FIXME("(%p)->(%p)\n", This, pClsid);
    return E_NOTIMPL;
467 468
}

469 470
static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD dwFormOfType,
        LPOLESTR* pszUserType)
471
{
472
    WebBrowser *This = OLEOBJ_THIS(iface);
473
    TRACE("(%p, %d, %p)\n", This, dwFormOfType, pszUserType);
474 475 476
    return OleRegGetUserType(&CLSID_WebBrowser, dwFormOfType, pszUserType);
}

477
static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
478
{
479
    WebBrowser *This = OLEOBJ_THIS(iface);
480

481
    TRACE("(%p)->(%x %p)\n", This, dwDrawAspect, psizel);
482 483

    /* Tests show that dwDrawAspect is ignored */
484
    This->extent = *psizel;
485
    return S_OK;
486 487
}

488
static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
489
{
490
    WebBrowser *This = OLEOBJ_THIS(iface);
491

492
    TRACE("(%p)->(%x, %p)\n", This, dwDrawAspect, psizel);
493 494

    /* Tests show that dwDrawAspect is ignored */
495
    *psizel = This->extent;
496
    return S_OK;
497 498
}

499 500
static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *pAdvSink,
        DWORD* pdwConnection)
501
{
502 503 504
    WebBrowser *This = OLEOBJ_THIS(iface);
    FIXME("(%p)->(%p, %p)\n", This, pAdvSink, pdwConnection);
    return E_NOTIMPL;
505 506
}

507
static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD dwConnection)
508
{
509
    WebBrowser *This = OLEOBJ_THIS(iface);
510
    FIXME("(%p)->(%d)\n", This, dwConnection);
511
    return E_NOTIMPL;
512 513
}

514
static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **ppenumAdvise)
515
{
516 517
    WebBrowser *This = OLEOBJ_THIS(iface);
    FIXME("(%p)->(%p)\n", This, ppenumAdvise);
518 519 520
    return S_OK;
}

521
static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD dwAspect, DWORD *pdwStatus)
522
{
523
    WebBrowser *This = OLEOBJ_THIS(iface);
524

525
    TRACE("(%p)->(%x, %p)\n", This, dwAspect, pdwStatus);
526

527 528
    *pdwStatus = OLEMISC_SETCLIENTSITEFIRST|OLEMISC_ACTIVATEWHENVISIBLE|OLEMISC_INSIDEOUT
        |OLEMISC_CANTLINKINSIDE|OLEMISC_RECOMPOSEONRESIZE;
529 530 531 532

    return S_OK;
}

533
static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE* pLogpal)
534
{
535 536 537
    WebBrowser *This = OLEOBJ_THIS(iface);
    FIXME("(%p)->(%p)\n", This, pLogpal);
    return E_NOTIMPL;
538 539
}

540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567
#undef OLEOBJ_THIS

static const IOleObjectVtbl OleObjectVtbl =
{
    OleObject_QueryInterface,
    OleObject_AddRef,
    OleObject_Release,
    OleObject_SetClientSite,
    OleObject_GetClientSite,
    OleObject_SetHostNames,
    OleObject_Close,
    OleObject_SetMoniker,
    OleObject_GetMoniker,
    OleObject_InitFromData,
    OleObject_GetClipboardData,
    OleObject_DoVerb,
    OleObject_EnumVerbs,
    OleObject_Update,
    OleObject_IsUpToDate,
    OleObject_GetUserClassID,
    OleObject_GetUserType,
    OleObject_SetExtent,
    OleObject_GetExtent,
    OleObject_Advise,
    OleObject_Unadvise,
    OleObject_EnumAdvise,
    OleObject_GetMiscStatus,
    OleObject_SetColorScheme
568 569 570 571 572 573
};

/**********************************************************************
 * Implement the IOleInPlaceObject interface
 */

574
#define INPLACEOBJ_THIS(iface) DEFINE_THIS(WebBrowser, OleInPlaceObject, iface)
575

576 577 578 579 580
static HRESULT WINAPI OleInPlaceObject_QueryInterface(IOleInPlaceObject *iface,
        REFIID riid, LPVOID *ppobj)
{
    WebBrowser *This = INPLACEOBJ_THIS(iface);
    return IWebBrowser_QueryInterface(WEBBROWSER(This), riid, ppobj);
581 582
}

583
static ULONG WINAPI OleInPlaceObject_AddRef(IOleInPlaceObject *iface)
584
{
585 586
    WebBrowser *This = INPLACEOBJ_THIS(iface);
    return IWebBrowser_AddRef(WEBBROWSER(This));
587 588
}

589
static ULONG WINAPI OleInPlaceObject_Release(IOleInPlaceObject *iface)
590
{
591 592
    WebBrowser *This = INPLACEOBJ_THIS(iface);
    return IWebBrowser_Release(WEBBROWSER(This));
593 594
}

595
static HRESULT WINAPI OleInPlaceObject_GetWindow(IOleInPlaceObject *iface, HWND* phwnd)
596
{
597 598
    WebBrowser *This = INPLACEOBJ_THIS(iface);

599
    TRACE("(%p)->(%p)\n", This, phwnd);
600

601
    *phwnd = This->shell_embedding_hwnd;
602 603 604
    return S_OK;
}

605 606
static HRESULT WINAPI OleInPlaceObject_ContextSensitiveHelp(IOleInPlaceObject *iface,
        BOOL fEnterMode)
607
{
608 609 610
    WebBrowser *This = INPLACEOBJ_THIS(iface);
    FIXME("(%p)->(%x)\n", This, fEnterMode);
    return E_NOTIMPL;
611 612
}

613
static HRESULT WINAPI OleInPlaceObject_InPlaceDeactivate(IOleInPlaceObject *iface)
614
{
615 616 617
    WebBrowser *This = INPLACEOBJ_THIS(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
618 619
}

620
static HRESULT WINAPI OleInPlaceObject_UIDeactivate(IOleInPlaceObject *iface)
621
{
622 623 624
    WebBrowser *This = INPLACEOBJ_THIS(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
625 626
}

627 628
static HRESULT WINAPI OleInPlaceObject_SetObjectRects(IOleInPlaceObject *iface,
        LPCRECT lprcPosRect, LPCRECT lprcClipRect)
629
{
630
    WebBrowser *This = INPLACEOBJ_THIS(iface);
631 632 633

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

634
    This->pos_rect = *lprcPosRect;
635 636

    if(lprcClipRect)
637
        This->clip_rect = *lprcClipRect;
638

639 640 641 642
    if(This->shell_embedding_hwnd) {
        SetWindowPos(This->shell_embedding_hwnd, NULL,
                     lprcPosRect->left, lprcPosRect->top,
                     lprcPosRect->right-lprcPosRect->left,
Jacek Caban's avatar
Jacek Caban committed
643
                     lprcPosRect->bottom-lprcPosRect->top,
644 645 646 647
                     SWP_NOZORDER | SWP_NOACTIVATE);
    }

    return S_OK;
648 649
}

650
static HRESULT WINAPI OleInPlaceObject_ReactivateAndUndo(IOleInPlaceObject *iface)
651
{
652 653 654
    WebBrowser *This = INPLACEOBJ_THIS(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
655 656
}

657
#undef INPLACEOBJ_THIS
658

659 660 661 662 663 664 665 666 667 668 669
static const IOleInPlaceObjectVtbl OleInPlaceObjectVtbl =
{
    OleInPlaceObject_QueryInterface,
    OleInPlaceObject_AddRef,
    OleInPlaceObject_Release,
    OleInPlaceObject_GetWindow,
    OleInPlaceObject_ContextSensitiveHelp,
    OleInPlaceObject_InPlaceDeactivate,
    OleInPlaceObject_UIDeactivate,
    OleInPlaceObject_SetObjectRects,
    OleInPlaceObject_ReactivateAndUndo
670 671 672 673 674 675
};

/**********************************************************************
 * Implement the IOleControl interface
 */

676
#define CONTROL_THIS(iface) DEFINE_THIS(WebBrowser, OleControl, iface)
677

678 679 680 681 682
static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface,
        REFIID riid, LPVOID *ppobj)
{
    WebBrowser *This = CONTROL_THIS(iface);
    return IWebBrowser_QueryInterface(WEBBROWSER(This), riid, ppobj);
683 684
}

685
static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
686
{
687 688
    WebBrowser *This = CONTROL_THIS(iface);
    return IWebBrowser_AddRef(WEBBROWSER(This));
689 690
}

691
static ULONG WINAPI OleControl_Release(IOleControl *iface)
692
{
693 694
    WebBrowser *This = CONTROL_THIS(iface);
    return IWebBrowser_Release(WEBBROWSER(This));
695 696
}

697
static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, LPCONTROLINFO pCI)
698
{
699
    WebBrowser *This = CONTROL_THIS(iface);
700 701 702 703

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

    /* Tests show that this function should be not implemented */
704
    return E_NOTIMPL;
705 706
}

707
static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, struct tagMSG *pMsg)
708
{
709 710 711
    WebBrowser *This = CONTROL_THIS(iface);
    FIXME("(%p)->(%p)\n", This, pMsg);
    return E_NOTIMPL;
712 713
}

714
static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispID)
715
{
716
    WebBrowser *This = CONTROL_THIS(iface);
717 718 719 720

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

    switch(dispID) {
721 722
    case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
        return on_offlineconnected_change(This);
723 724 725 726 727
    case DISPID_AMBIENT_SILENT:
        return on_silent_change(This);
    }

    FIXME("Unknown dispID %d\n", dispID);
728
    return E_NOTIMPL;
729 730
}

731
static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL bFreeze)
732
{
733 734 735
    WebBrowser *This = CONTROL_THIS(iface);
    FIXME("(%p)->(%x)\n", This, bFreeze);
    return E_NOTIMPL;
736 737
}

738
#undef CONTROL_THIS
739

740
static const IOleControlVtbl OleControlVtbl =
741
{
742 743 744 745 746 747 748
    OleControl_QueryInterface,
    OleControl_AddRef,
    OleControl_Release,
    OleControl_GetControlInfo,
    OleControl_OnMnemonic,
    OleControl_OnAmbientPropertyChange,
    OleControl_FreezeEvents
749 750
};

751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840
#define ACTIVEOBJ_THIS(iface) DEFINE_THIS(WebBrowser, OleInPlaceActiveObject, iface)

static HRESULT WINAPI InPlaceActiveObject_QueryInterface(IOleInPlaceActiveObject *iface,
                                                            REFIID riid, void **ppv)
{
    WebBrowser *This = ACTIVEOBJ_THIS(iface);
    return IWebBrowser2_QueryInterface(WEBBROWSER2(This), riid, ppv);
}

static ULONG WINAPI InPlaceActiveObject_AddRef(IOleInPlaceActiveObject *iface)
{
    WebBrowser *This = ACTIVEOBJ_THIS(iface);
    return IWebBrowser2_AddRef(WEBBROWSER2(This));
}

static ULONG WINAPI InPlaceActiveObject_Release(IOleInPlaceActiveObject *iface)
{
    WebBrowser *This = ACTIVEOBJ_THIS(iface);
    return IWebBrowser2_Release(WEBBROWSER2(This));
}

static HRESULT WINAPI InPlaceActiveObject_GetWindow(IOleInPlaceActiveObject *iface,
                                                    HWND *phwnd)
{
    WebBrowser *This = ACTIVEOBJ_THIS(iface);
    return IOleInPlaceObject_GetWindow(INPLACEOBJ(This), phwnd);
}

static HRESULT WINAPI InPlaceActiveObject_ContextSensitiveHelp(IOleInPlaceActiveObject *iface,
                                                               BOOL fEnterMode)
{
    WebBrowser *This = ACTIVEOBJ_THIS(iface);
    return IOleInPlaceObject_ContextSensitiveHelp(INPLACEOBJ(This), fEnterMode);
}

static HRESULT WINAPI InPlaceActiveObject_TranslateAccelerator(IOleInPlaceActiveObject *iface,
                                                               LPMSG lpmsg)
{
    WebBrowser *This = ACTIVEOBJ_THIS(iface);
    FIXME("(%p)->(%p)\n", This, lpmsg);
    return E_NOTIMPL;
}

static HRESULT WINAPI InPlaceActiveObject_OnFrameWindowActivate(IOleInPlaceActiveObject *iface,
                                                                BOOL fActivate)
{
    WebBrowser *This = ACTIVEOBJ_THIS(iface);
    FIXME("(%p)->(%x)\n", This, fActivate);
    return E_NOTIMPL;
}

static HRESULT WINAPI InPlaceActiveObject_OnDocWindowActivate(IOleInPlaceActiveObject *iface,
                                                              BOOL fActivate)
{
    WebBrowser *This = ACTIVEOBJ_THIS(iface);
    FIXME("(%p)->(%x)\n", This, fActivate);
    return E_NOTIMPL;
}

static HRESULT WINAPI InPlaceActiveObject_ResizeBorder(IOleInPlaceActiveObject *iface,
        LPCRECT lprcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fFrameWindow)
{
    WebBrowser *This = ACTIVEOBJ_THIS(iface);
    FIXME("(%p)->(%p %p %x)\n", This, lprcBorder, pUIWindow, fFrameWindow);
    return E_NOTIMPL;
}

static HRESULT WINAPI InPlaceActiveObject_EnableModeless(IOleInPlaceActiveObject *iface,
                                                         BOOL fEnable)
{
    WebBrowser *This = ACTIVEOBJ_THIS(iface);
    FIXME("(%p)->(%x)\n", This, fEnable);
    return E_NOTIMPL;
}

#undef ACTIVEOBJ_THIS

static const IOleInPlaceActiveObjectVtbl OleInPlaceActiveObjectVtbl = {
    InPlaceActiveObject_QueryInterface,
    InPlaceActiveObject_AddRef,
    InPlaceActiveObject_Release,
    InPlaceActiveObject_GetWindow,
    InPlaceActiveObject_ContextSensitiveHelp,
    InPlaceActiveObject_TranslateAccelerator,
    InPlaceActiveObject_OnFrameWindowActivate,
    InPlaceActiveObject_OnDocWindowActivate,
    InPlaceActiveObject_ResizeBorder,
    InPlaceActiveObject_EnableModeless
};

Jacek Caban's avatar
Jacek Caban committed
841
#define OLECMD_THIS(iface) DEFINE_THIS(WebBrowser, OleCommandTarget, iface)
842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865

static HRESULT WINAPI WBOleCommandTarget_QueryInterface(IOleCommandTarget *iface,
        REFIID riid, void **ppv)
{
    WebBrowser *This = OLECMD_THIS(iface);
    return IWebBrowser2_QueryInterface(WEBBROWSER(This), riid, ppv);
}

static ULONG WINAPI WBOleCommandTarget_AddRef(IOleCommandTarget *iface)
{
    WebBrowser *This = OLECMD_THIS(iface);
    return IWebBrowser2_AddRef(WEBBROWSER(This));
}

static ULONG WINAPI WBOleCommandTarget_Release(IOleCommandTarget *iface)
{
    WebBrowser *This = OLECMD_THIS(iface);
    return IWebBrowser2_Release(WEBBROWSER(This));
}

static HRESULT WINAPI WBOleCommandTarget_QueryStatus(IOleCommandTarget *iface,
        const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
{
    WebBrowser *This = OLECMD_THIS(iface);
866
    FIXME("(%p)->(%s %u %p %p)\n", This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds,
867 868 869 870 871 872 873 874 875
          pCmdText);
    return E_NOTIMPL;
}

static HRESULT WINAPI WBOleCommandTarget_Exec(IOleCommandTarget *iface,
        const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn,
        VARIANT *pvaOut)
{
    WebBrowser *This = OLECMD_THIS(iface);
876
    FIXME("(%p)->(%s %d %d %p %p)\n", This, debugstr_guid(pguidCmdGroup), nCmdID,
877 878 879 880 881 882 883 884 885 886 887 888 889 890
          nCmdexecopt, pvaIn, pvaOut);
    return E_NOTIMPL;
}

#undef OLECMD_THIS

static const IOleCommandTargetVtbl OleCommandTargetVtbl = {
    WBOleCommandTarget_QueryInterface,
    WBOleCommandTarget_AddRef,
    WBOleCommandTarget_Release,
    WBOleCommandTarget_QueryStatus,
    WBOleCommandTarget_Exec
};

891 892
void WebBrowser_OleObject_Init(WebBrowser *This)
{
893 894 895 896
    This->lpOleObjectVtbl              = &OleObjectVtbl;
    This->lpOleInPlaceObjectVtbl       = &OleInPlaceObjectVtbl;
    This->lpOleControlVtbl             = &OleControlVtbl;
    This->lpOleInPlaceActiveObjectVtbl = &OleInPlaceActiveObjectVtbl;
Jacek Caban's avatar
Jacek Caban committed
897
    This->lpOleCommandTargetVtbl     = &OleCommandTargetVtbl;
898 899

    This->client = NULL;
900
    This->inplace = NULL;
901 902 903
    This->container = NULL;
    This->frame_hwnd = NULL;
    This->uiwindow = NULL;
Jacek Caban's avatar
Jacek Caban committed
904
    This->shell_embedding_hwnd = NULL;
905 906 907 908

    memset(&This->pos_rect, 0, sizeof(RECT));
    memset(&This->clip_rect, 0, sizeof(RECT));
    memset(&This->frameinfo, 0, sizeof(OLEINPLACEFRAMEINFO));
909 910 911

    This->extent.cx = 1323;
    This->extent.cy = 529;
912 913 914 915 916
}

void WebBrowser_OleObject_Destroy(WebBrowser *This)
{
    if(This->client)
917
        IOleObject_SetClientSite(OLEOBJ(This), NULL);
918 919 920 921
    if(This->container)
        IOleContainer_Release(This->container);
    if(This->uiwindow)
        IOleInPlaceUIWindow_Release(This->uiwindow);
922
}