oleobj.c 35.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright 2005 Jacek Caban
 *
 * 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
16
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 18 19 20 21 22 23 24 25 26 27 28 29
 */

#include "config.h"

#include <stdarg.h>
#include <stdio.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
30
#include "shlguid.h"
31
#include "shdeprecated.h"
32 33
#include "mshtmdid.h"
#include "idispids.h"
34 35 36 37 38 39 40

#include "wine/debug.h"

#include "mshtml_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

41 42
#define DOCHOST_DOCCANNAVIGATE  0

43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
typedef struct {
    IEnumUnknown IEnumUnknown_iface;
    LONG ref;
} EnumUnknown;

static inline EnumUnknown *impl_from_IEnumUnknown(IEnumUnknown *iface)
{
    return CONTAINING_RECORD(iface, EnumUnknown, IEnumUnknown_iface);
}

static HRESULT WINAPI EnumUnknown_QueryInterface(IEnumUnknown *iface, REFIID riid, void **ppv)
{
    EnumUnknown *This = impl_from_IEnumUnknown(iface);

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
        *ppv = &This->IEnumUnknown_iface;
    }else if(IsEqualGUID(&IID_IEnumUnknown, riid)) {
        TRACE("(%p)->(IID_IEnumUnknown %p)\n", This, ppv);
        *ppv = &This->IEnumUnknown_iface;
    }else {
        WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
        *ppv = NULL;
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI EnumUnknown_AddRef(IEnumUnknown *iface)
{
    EnumUnknown *This = impl_from_IEnumUnknown(iface);
    LONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI EnumUnknown_Release(IEnumUnknown *iface)
{
    EnumUnknown *This = impl_from_IEnumUnknown(iface);
    LONG ref = InterlockedDecrement(&This->ref);

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

    if(!ref)
        heap_free(This);

    return ref;
}

static HRESULT WINAPI EnumUnknown_Next(IEnumUnknown *iface, ULONG celt, IUnknown **rgelt, ULONG *pceltFetched)
{
    EnumUnknown *This = impl_from_IEnumUnknown(iface);

    TRACE("(%p)->(%u %p %p)\n", This, celt, rgelt, pceltFetched);

    /* FIXME: It's not clear if we should ever return something here */
    if(pceltFetched)
        *pceltFetched = 0;
    return S_FALSE;
}

static HRESULT WINAPI EnumUnknown_Skip(IEnumUnknown *iface, ULONG celt)
{
    EnumUnknown *This = impl_from_IEnumUnknown(iface);
    FIXME("(%p)->(%u)\n", This, celt);
    return E_NOTIMPL;
}

static HRESULT WINAPI EnumUnknown_Reset(IEnumUnknown *iface)
{
    EnumUnknown *This = impl_from_IEnumUnknown(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI EnumUnknown_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
{
    EnumUnknown *This = impl_from_IEnumUnknown(iface);
    FIXME("(%p)->(%p)\n", This, ppenum);
    return E_NOTIMPL;
}

static const IEnumUnknownVtbl EnumUnknownVtbl = {
    EnumUnknown_QueryInterface,
    EnumUnknown_AddRef,
    EnumUnknown_Release,
    EnumUnknown_Next,
    EnumUnknown_Skip,
    EnumUnknown_Reset,
    EnumUnknown_Clone
};

139 140 141 142
/**********************************************************
 * IOleObject implementation
 */

143 144 145 146
static inline HTMLDocument *impl_from_IOleObject(IOleObject *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocument, IOleObject_iface);
}
147

148
static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
149
{
150
    HTMLDocument *This = impl_from_IOleObject(iface);
151
    return htmldoc_query_interface(This, riid, ppv);
152 153 154 155
}

static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
{
156
    HTMLDocument *This = impl_from_IOleObject(iface);
157
    return htmldoc_addref(This);
158 159 160 161
}

static ULONG WINAPI OleObject_Release(IOleObject *iface)
{
162
    HTMLDocument *This = impl_from_IOleObject(iface);
163
    return htmldoc_release(This);
164 165
}

166
static void update_hostinfo(HTMLDocumentObj *This, DOCHOSTUIINFO *hostinfo)
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
{
    nsIScrollable *scrollable;
    nsresult nsres;

    if(!This->nscontainer)
        return;

    nsres = nsIWebBrowser_QueryInterface(This->nscontainer->webbrowser, &IID_nsIScrollable, (void**)&scrollable);
    if(NS_SUCCEEDED(nsres)) {
        nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable, ScrollOrientation_Y,
                (hostinfo->dwFlags & DOCHOSTUIFLAG_SCROLL_NO) ? Scrollbar_Never : Scrollbar_Always);
        if(NS_FAILED(nsres))
            ERR("Could not set default Y scrollbar prefs: %08x\n", nsres);

        nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable, ScrollOrientation_X,
                hostinfo->dwFlags & DOCHOSTUIFLAG_SCROLL_NO ? Scrollbar_Never : Scrollbar_Auto);
        if(NS_FAILED(nsres))
            ERR("Could not set default X scrollbar prefs: %08x\n", nsres);

        nsIScrollable_Release(scrollable);
    }else {
        ERR("Could not get nsIScrollable: %08x\n", nsres);
    }
}

192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
/* Calls undocumented 84 cmd of CGID_ShellDocView */
void call_docview_84(HTMLDocumentObj *doc)
{
    IOleCommandTarget *olecmd;
    VARIANT var;
    HRESULT hres;

    if(!doc->client)
        return;

    hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd);
    if(FAILED(hres))
        return;

    VariantInit(&var);
    hres = IOleCommandTarget_Exec(olecmd, &CGID_ShellDocView, 84, 0, NULL, &var);
    IOleCommandTarget_Release(olecmd);
    if(SUCCEEDED(hres) && V_VT(&var) != VT_NULL)
        FIXME("handle result\n");
}

213 214
static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite *pClientSite)
{
215
    HTMLDocument *This = impl_from_IOleObject(iface);
216
    IOleCommandTarget *cmdtrg = NULL;
217
    IOleWindow *ole_window;
218
    BOOL hostui_setup;
219
    VARIANT silent;
220
    HWND hwnd;
221 222
    HRESULT hres;

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

225
    if(pClientSite == This->doc_obj->client)
226 227
        return S_OK;

228 229 230
    if(This->doc_obj->client) {
        IOleClientSite_Release(This->doc_obj->client);
        This->doc_obj->client = NULL;
231
        This->doc_obj->usermode = UNKNOWN_USERMODE;
232
    }
233

234
    if(This->doc_obj->hostui && !This->doc_obj->custom_hostui) {
235 236
        IDocHostUIHandler_Release(This->doc_obj->hostui);
        This->doc_obj->hostui = NULL;
237
    }
238

239 240 241 242 243
    if(This->doc_obj->doc_object_service) {
        IDocObjectService_Release(This->doc_obj->doc_object_service);
        This->doc_obj->doc_object_service = NULL;
    }

244
    memset(&This->doc_obj->hostinfo, 0, sizeof(DOCHOSTUIINFO));
245
    This->doc_obj->is_webbrowser = FALSE;
246

247
    if(!pClientSite)
248 249
        return S_OK;

250 251 252
    IOleClientSite_AddRef(pClientSite);
    This->doc_obj->client = pClientSite;

253 254
    hostui_setup = This->doc_obj->hostui_setup;

255 256 257 258 259 260 261 262 263 264 265
    if(!This->doc_obj->hostui) {
        IDocHostUIHandler *uihandler;

        This->doc_obj->custom_hostui = FALSE;

        hres = IOleObject_QueryInterface(pClientSite, &IID_IDocHostUIHandler, (void**)&uihandler);
        if(SUCCEEDED(hres))
            This->doc_obj->hostui = uihandler;
    }

    if(This->doc_obj->hostui) {
266 267
        DOCHOSTUIINFO hostinfo;
        LPOLESTR key_path = NULL, override_key_path = NULL;
268
        IDocHostUIHandler2 *uihandler2;
269

270 271
        memset(&hostinfo, 0, sizeof(DOCHOSTUIINFO));
        hostinfo.cbSize = sizeof(DOCHOSTUIINFO);
272
        hres = IDocHostUIHandler_GetHostInfo(This->doc_obj->hostui, &hostinfo);
273
        if(SUCCEEDED(hres)) {
274
            TRACE("hostinfo = {%u %08x %08x %s %s}\n",
275 276
                    hostinfo.cbSize, hostinfo.dwFlags, hostinfo.dwDoubleClick,
                    debugstr_w(hostinfo.pchHostCss), debugstr_w(hostinfo.pchHostNS));
277
            update_hostinfo(This->doc_obj, &hostinfo);
278
            This->doc_obj->hostinfo = hostinfo;
279
        }
280

281
        if(!hostui_setup) {
282
            hres = IDocHostUIHandler_GetOptionKeyPath(This->doc_obj->hostui, &key_path, 0);
Jacek Caban's avatar
Jacek Caban committed
283 284 285 286 287 288 289
            if(hres == S_OK && key_path) {
                if(key_path[0]) {
                    /* FIXME: use key_path */
                    TRACE("key_path = %s\n", debugstr_w(key_path));
                }
                CoTaskMemFree(key_path);
            }
290

291 292
            hres = IDocHostUIHandler_QueryInterface(This->doc_obj->hostui, &IID_IDocHostUIHandler2,
                    (void**)&uihandler2);
Jacek Caban's avatar
Jacek Caban committed
293
            if(SUCCEEDED(hres)) {
294
                hres = IDocHostUIHandler2_GetOverrideKeyPath(uihandler2, &override_key_path, 0);
Jacek Caban's avatar
Jacek Caban committed
295 296 297 298 299 300 301
                if(hres == S_OK && override_key_path && override_key_path[0]) {
                    if(override_key_path[0]) {
                        /*FIXME: use override_key_path */
                        TRACE("override_key_path = %s\n", debugstr_w(override_key_path));
                    }
                    CoTaskMemFree(override_key_path);
                }
302
                IDocHostUIHandler2_Release(uihandler2);
Jacek Caban's avatar
Jacek Caban committed
303 304
            }

305
            This->doc_obj->hostui_setup = TRUE;
306 307 308
        }
    }

Jacek Caban's avatar
Jacek Caban committed
309 310
    /* Native calls here GetWindow. What is it for?
     * We don't have anything to do with it here (yet). */
311 312 313 314
    hres = IOleClientSite_QueryInterface(pClientSite, &IID_IOleWindow, (void**)&ole_window);
    if(SUCCEEDED(hres)) {
        IOleWindow_GetWindow(ole_window, &hwnd);
        IOleWindow_Release(ole_window);
Jacek Caban's avatar
Jacek Caban committed
315 316
    }

317 318 319 320 321
    hres = IOleClientSite_QueryInterface(pClientSite, &IID_IOleCommandTarget, (void**)&cmdtrg);
    if(SUCCEEDED(hres)) {
        VARIANT var;
        OLECMD cmd = {OLECMDID_SETPROGRESSTEXT, 0};

322
        if(!hostui_setup) {
323 324 325
            IDocObjectService *doc_object_service;
            IBrowserService *browser_service;
            IWebBrowser2 *wb;
326

327
            V_VT(&var) = VT_UNKNOWN;
328
            V_UNKNOWN(&var) = (IUnknown*)&This->window->base.IHTMLWindow2_iface;
329
            IOleCommandTarget_Exec(cmdtrg, &CGID_DocHostCmdPriv, DOCHOST_DOCCANNAVIGATE, 0, &var, NULL);
330

331 332
            hres = do_query_service((IUnknown*)pClientSite, &IID_IShellBrowser,
                    &IID_IBrowserService, (void**)&browser_service);
333
            if(SUCCEEDED(hres)) {
334 335
                hres = IBrowserService_QueryInterface(browser_service,
                        &IID_IDocObjectService, (void**)&doc_object_service);
336
                if(SUCCEEDED(hres)) {
337 338 339 340 341 342 343
                    This->doc_obj->doc_object_service = doc_object_service;

                    /*
                     * Some embedding routines, esp. in regards to use of IDocObjectService, differ if
                     * embedder supports IWebBrowserApp.
                     */
                    hres = do_query_service((IUnknown*)pClientSite, &IID_IWebBrowserApp, &IID_IWebBrowser2, (void**)&wb);
344
                    if(SUCCEEDED(hres)) {
345 346
                        This->doc_obj->is_webbrowser = TRUE;
                        IWebBrowser2_Release(wb);
347 348
                    }

349 350 351
                    IBrowserService_Release(browser_service);
                }
            }
352 353
        }

354 355
        call_docview_84(This->doc_obj);

356 357 358 359
        IOleCommandTarget_QueryStatus(cmdtrg, NULL, 1, &cmd, NULL);

        V_VT(&var) = VT_I4;
        V_I4(&var) = 0;
360 361 362 363
        IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSMAX,
                OLECMDEXECOPT_DONTPROMPTUSER, &var, NULL);
        IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSPOS, 
                OLECMDEXECOPT_DONTPROMPTUSER, &var, NULL);
364 365 366 367

        IOleCommandTarget_Release(cmdtrg);
    }

368
    if(This->doc_obj->usermode == UNKNOWN_USERMODE)
369
        IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface, DISPID_AMBIENT_USERMODE);
370

371 372
    IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface,
            DISPID_AMBIENT_OFFLINEIFNOTCONNECTED);
373

374
    hres = get_client_disp_property(This->doc_obj->client, DISPID_AMBIENT_SILENT, &silent);
375 376
    if(SUCCEEDED(hres)) {
        if(V_VT(&silent) != VT_BOOL)
377
            WARN("silent = %s\n", debugstr_variant(&silent));
378 379 380 381
        else if(V_BOOL(&silent))
            FIXME("silent == true\n");
    }

382 383
    IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface, DISPID_AMBIENT_USERAGENT);
    IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface, DISPID_AMBIENT_PALETTE);
384

385 386 387 388 389
    return S_OK;
}

static HRESULT WINAPI OleObject_GetClientSite(IOleObject *iface, IOleClientSite **ppClientSite)
{
390
    HTMLDocument *This = impl_from_IOleObject(iface);
391

392 393 394 395 396
    TRACE("(%p)->(%p)\n", This, ppClientSite);

    if(!ppClientSite)
        return E_INVALIDARG;

397 398 399
    if(This->doc_obj->client)
        IOleClientSite_AddRef(This->doc_obj->client);
    *ppClientSite = This->doc_obj->client;
400 401 402 403 404 405

    return S_OK;
}

static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
{
406
    HTMLDocument *This = impl_from_IOleObject(iface);
407 408 409 410 411 412
    FIXME("(%p)->(%s %s)\n", This, debugstr_w(szContainerApp), debugstr_w(szContainerObj));
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD dwSaveOption)
{
413
    HTMLDocument *This = impl_from_IOleObject(iface);
Jacek Caban's avatar
Jacek Caban committed
414

415
    TRACE("(%p)->(%08x)\n", This, dwSaveOption);
416 417 418 419

    if(dwSaveOption == OLECLOSE_PROMPTSAVE)
        FIXME("OLECLOSE_PROMPTSAVE not implemented\n");

420
    if(This->doc_obj->in_place_active)
421
        IOleInPlaceObjectWindowless_InPlaceDeactivate(&This->IOleInPlaceObjectWindowless_iface);
Jacek Caban's avatar
Jacek Caban committed
422

423
    HTMLDocument_LockContainer(This->doc_obj, FALSE);
424 425 426

    if(This->advise_holder)
        IOleAdviseHolder_SendOnClose(This->advise_holder);
Jacek Caban's avatar
Jacek Caban committed
427 428
    
    return S_OK;
429 430 431 432
}

static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD dwWhichMoniker, IMoniker *pmk)
{
433
    HTMLDocument *This = impl_from_IOleObject(iface);
434
    FIXME("(%p %d %p)->()\n", This, dwWhichMoniker, pmk);
435 436 437 438 439
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
{
440
    HTMLDocument *This = impl_from_IOleObject(iface);
441
    FIXME("(%p)->(%d %d %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
442 443 444 445 446 447
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, IDataObject *pDataObject, BOOL fCreation,
                                        DWORD dwReserved)
{
448
    HTMLDocument *This = impl_from_IOleObject(iface);
449
    FIXME("(%p)->(%p %x %d)\n", This, pDataObject, fCreation, dwReserved);
450 451 452 453 454
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD dwReserved, IDataObject **ppDataObject)
{
455
    HTMLDocument *This = impl_from_IOleObject(iface);
456
    FIXME("(%p)->(%d %p)\n", This, dwReserved, ppDataObject);
457 458 459 460 461 462
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite,
                                        LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
{
463
    HTMLDocument *This = impl_from_IOleObject(iface);
464 465 466
    IOleDocumentSite *pDocSite;
    HRESULT hres;

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

469
    if(iVerb != OLEIVERB_SHOW && iVerb != OLEIVERB_UIACTIVATE && iVerb != OLEIVERB_INPLACEACTIVATE) { 
470
        FIXME("iVerb = %d not supported\n", iVerb);
471 472 473 474
        return E_NOTIMPL;
    }

    if(!pActiveSite)
475
        pActiveSite = This->doc_obj->client;
476 477 478

    hres = IOleClientSite_QueryInterface(pActiveSite, &IID_IOleDocumentSite, (void**)&pDocSite);
    if(SUCCEEDED(hres)) {
479
        HTMLDocument_LockContainer(This->doc_obj, TRUE);
480

481
        /* FIXME: Create new IOleDocumentView. See CreateView for more info. */
482
        hres = IOleDocumentSite_ActivateMe(pDocSite, &This->IOleDocumentView_iface);
483 484
        IOleDocumentSite_Release(pDocSite);
    }else {
485
        hres = IOleDocumentView_UIActivate(&This->IOleDocumentView_iface, TRUE);
486 487 488
        if(SUCCEEDED(hres)) {
            if(lprcPosRect) {
                RECT rect; /* We need to pass rect as not const pointer */
489
                rect = *lprcPosRect;
490
                IOleDocumentView_SetRect(&This->IOleDocumentView_iface, &rect);
491
            }
492
            IOleDocumentView_Show(&This->IOleDocumentView_iface, TRUE);
493 494 495 496
        }
    }

    return hres;
497 498 499 500
}

static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **ppEnumOleVerb)
{
501
    HTMLDocument *This = impl_from_IOleObject(iface);
502 503 504 505 506 507
    FIXME("(%p)->(%p)\n", This, ppEnumOleVerb);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_Update(IOleObject *iface)
{
508
    HTMLDocument *This = impl_from_IOleObject(iface);
509 510 511 512 513 514
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
{
515
    HTMLDocument *This = impl_from_IOleObject(iface);
516 517 518 519 520 521
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetUserClassID(IOleObject *iface, CLSID *pClsid)
{
522
    HTMLDocument *This = impl_from_IOleObject(iface);
523

524 525 526 527 528
    TRACE("(%p)->(%p)\n", This, pClsid);

    if(!pClsid)
        return E_INVALIDARG;

529
    *pClsid = CLSID_HTMLDocument;
530 531 532 533 534
    return S_OK;
}

static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD dwFormOfType, LPOLESTR *pszUserType)
{
535
    HTMLDocument *This = impl_from_IOleObject(iface);
536
    FIXME("(%p)->(%d %p)\n", This, dwFormOfType, pszUserType);
537 538 539 540 541
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
{
542
    HTMLDocument *This = impl_from_IOleObject(iface);
543
    FIXME("(%p)->(%d %p)\n", This, dwDrawAspect, psizel);
544 545 546 547 548
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
{
549
    HTMLDocument *This = impl_from_IOleObject(iface);
550
    FIXME("(%p)->(%d %p)\n", This, dwDrawAspect, psizel);
551 552 553 554 555
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *pAdvSink, DWORD *pdwConnection)
{
556
    HTMLDocument *This = impl_from_IOleObject(iface);
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573
    TRACE("(%p)->(%p %p)\n", This, pAdvSink, pdwConnection);

    if(!pdwConnection)
        return E_INVALIDARG;

    if(!pAdvSink) {
        *pdwConnection = 0;
        return E_INVALIDARG;
    }

    if(!This->advise_holder) {
        CreateOleAdviseHolder(&This->advise_holder);
        if(!This->advise_holder)
            return E_OUTOFMEMORY;
    }

    return IOleAdviseHolder_Advise(This->advise_holder, pAdvSink, pdwConnection);
574 575 576 577
}

static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD dwConnection)
{
578
    HTMLDocument *This = impl_from_IOleObject(iface);
579 580 581 582 583 584
    TRACE("(%p)->(%d)\n", This, dwConnection);

    if(!This->advise_holder)
        return OLE_E_NOCONNECTION;

    return IOleAdviseHolder_Unadvise(This->advise_holder, dwConnection);
585 586 587 588
}

static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **ppenumAdvise)
{
589
    HTMLDocument *This = impl_from_IOleObject(iface);
590 591 592 593 594 595 596

    if(!This->advise_holder) {
        *ppenumAdvise = NULL;
        return S_OK;
    }

    return IOleAdviseHolder_EnumAdvise(This->advise_holder, ppenumAdvise);
597 598 599 600
}

static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD dwAspect, DWORD *pdwStatus)
{
601
    HTMLDocument *This = impl_from_IOleObject(iface);
602
    FIXME("(%p)->(%d %p)\n", This, dwAspect, pdwStatus);
603 604 605 606 607
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE *pLogpal)
{
608
    HTMLDocument *This = impl_from_IOleObject(iface);
609 610 611 612
    FIXME("(%p)->(%p)\n", This, pLogpal);
    return E_NOTIMPL;
}

613
static const IOleObjectVtbl OleObjectVtbl = {
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643
    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
};

/**********************************************************
 * IOleDocument implementation
 */

644 645 646 647
static inline HTMLDocument *impl_from_IOleDocument(IOleDocument *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocument, IOleDocument_iface);
}
648

649
static HRESULT WINAPI OleDocument_QueryInterface(IOleDocument *iface, REFIID riid, void **ppv)
650
{
651
    HTMLDocument *This = impl_from_IOleDocument(iface);
652
    return htmldoc_query_interface(This, riid, ppv);
653 654 655 656
}

static ULONG WINAPI OleDocument_AddRef(IOleDocument *iface)
{
657
    HTMLDocument *This = impl_from_IOleDocument(iface);
658
    return htmldoc_addref(This);
659 660 661 662
}

static ULONG WINAPI OleDocument_Release(IOleDocument *iface)
{
663
    HTMLDocument *This = impl_from_IOleDocument(iface);
664
    return htmldoc_release(This);
665 666 667 668 669
}

static HRESULT WINAPI OleDocument_CreateView(IOleDocument *iface, IOleInPlaceSite *pIPSite, IStream *pstm,
                                   DWORD dwReserved, IOleDocumentView **ppView)
{
670
    HTMLDocument *This = impl_from_IOleDocument(iface);
671 672
    HRESULT hres;

673
    TRACE("(%p)->(%p %p %d %p)\n", This, pIPSite, pstm, dwReserved, ppView);
674 675 676 677 678 679 680 681 682 683 684 685

    if(!ppView)
        return E_INVALIDARG;

    /* FIXME:
     * Windows implementation creates new IOleDocumentView when function is called for the
     * first time and returns E_FAIL when it is called for the second time, but it doesn't matter
     * if the application uses returned interfaces, passed to ActivateMe or returned by
     * QueryInterface, so there is no reason to create new interface. This needs more testing.
     */

    if(pIPSite) {
686
        hres = IOleDocumentView_SetInPlaceSite(&This->IOleDocumentView_iface, pIPSite);
687 688 689 690 691 692 693
        if(FAILED(hres))
            return hres;
    }

    if(pstm)
        FIXME("pstm is not supported\n");

694 695
    IOleDocumentView_AddRef(&This->IOleDocumentView_iface);
    *ppView = &This->IOleDocumentView_iface;
696
    return S_OK;
697 698 699 700
}

static HRESULT WINAPI OleDocument_GetDocMiscStatus(IOleDocument *iface, DWORD *pdwStatus)
{
701
    HTMLDocument *This = impl_from_IOleDocument(iface);
702 703 704 705 706 707 708
    FIXME("(%p)->(%p)\n", This, pdwStatus);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleDocument_EnumViews(IOleDocument *iface, IEnumOleDocumentViews **ppEnum,
                                   IOleDocumentView **ppView)
{
709
    HTMLDocument *This = impl_from_IOleDocument(iface);
710 711 712 713
    FIXME("(%p)->(%p %p)\n", This, ppEnum, ppView);
    return E_NOTIMPL;
}

714
static const IOleDocumentVtbl OleDocumentVtbl = {
715 716 717 718 719 720 721 722
    OleDocument_QueryInterface,
    OleDocument_AddRef,
    OleDocument_Release,
    OleDocument_CreateView,
    OleDocument_GetDocMiscStatus,
    OleDocument_EnumViews
};

723 724 725 726
/**********************************************************
 * IOleControl implementation
 */

727 728 729 730
static inline HTMLDocument *impl_from_IOleControl(IOleControl *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocument, IOleControl_iface);
}
731 732 733

static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **ppv)
{
734
    HTMLDocument *This = impl_from_IOleControl(iface);
735
    return htmldoc_query_interface(This, riid, ppv);
736 737 738 739
}

static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
{
740
    HTMLDocument *This = impl_from_IOleControl(iface);
741
    return htmldoc_addref(This);
742 743 744 745
}

static ULONG WINAPI OleControl_Release(IOleControl *iface)
{
746
    HTMLDocument *This = impl_from_IOleControl(iface);
747
    return htmldoc_release(This);
748 749 750 751
}

static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, CONTROLINFO *pCI)
{
752
    HTMLDocument *This = impl_from_IOleControl(iface);
753 754 755 756 757 758
    FIXME("(%p)->(%p)\n", This, pCI);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, MSG *pMsg)
{
759
    HTMLDocument *This = impl_from_IOleControl(iface);
760 761 762 763
    FIXME("(%p)->(%p)\n", This, pMsg);
    return E_NOTIMPL;
}

764
HRESULT get_client_disp_property(IOleClientSite *client, DISPID dispid, VARIANT *res)
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
{
    IDispatch *disp = NULL;
    DISPPARAMS dispparams = {NULL, 0};
    UINT err;
    HRESULT hres;

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

    VariantInit(res);

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

    IDispatch_Release(disp);

    return hres;
}

static HRESULT on_change_dlcontrol(HTMLDocument *This)
{
    VARIANT res;
    HRESULT hres;
    
792
    hres = get_client_disp_property(This->doc_obj->client, DISPID_AMBIENT_DLCONTROL, &res);
793
    if(SUCCEEDED(hres))
794
        FIXME("unsupported dlcontrol %08x\n", V_I4(&res));
795 796 797 798

    return S_OK;
}

799 800
static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispID)
{
801
    HTMLDocument *This = impl_from_IOleControl(iface);
802
    IOleClientSite *client;
803 804 805
    VARIANT res;
    HRESULT hres;

806 807 808
    client = This->doc_obj->client;
    if(!client) {
        TRACE("client = NULL\n");
809 810 811 812 813 814
        return S_OK;
    }

    switch(dispID) {
    case DISPID_AMBIENT_USERMODE:
        TRACE("(%p)->(DISPID_AMBIENT_USERMODE)\n", This);
815
        hres = get_client_disp_property(client, DISPID_AMBIENT_USERMODE, &res);
816 817 818 819
        if(FAILED(hres))
            return S_OK;

        if(V_VT(&res) == VT_BOOL) {
820
            if(V_BOOL(&res)) {
821
                This->doc_obj->usermode = BROWSEMODE;
822
            }else {
823
                FIXME("edit mode is not supported\n");
824
                This->doc_obj->usermode = EDITMODE;
825 826
            }
        }else {
827
            FIXME("usermode=%s\n", debugstr_variant(&res));
828 829 830 831 832 833 834 835
        }
        return S_OK;
    case DISPID_AMBIENT_DLCONTROL:
        TRACE("(%p)->(DISPID_AMBIENT_DLCONTROL)\n", This);
        return on_change_dlcontrol(This);
    case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
        TRACE("(%p)->(DISPID_AMBIENT_OFFLINEIFNOTCONNECTED)\n", This);
        on_change_dlcontrol(This);
836
        hres = get_client_disp_property(client, DISPID_AMBIENT_OFFLINEIFNOTCONNECTED, &res);
837 838 839 840 841 842 843 844 845
        if(FAILED(hres))
            return S_OK;

        if(V_VT(&res) == VT_BOOL) {
            if(V_BOOL(&res)) {
                FIXME("offline connection is not supported\n");
                hres = E_FAIL;
            }
        }else {
846
            FIXME("offlineconnected=%s\n", debugstr_variant(&res));
847 848 849 850 851
        }
        return S_OK;
    case DISPID_AMBIENT_SILENT:
        TRACE("(%p)->(DISPID_AMBIENT_SILENT)\n", This);
        on_change_dlcontrol(This);
852
        hres = get_client_disp_property(client, DISPID_AMBIENT_SILENT, &res);
853 854 855 856 857 858 859 860 861
        if(FAILED(hres))
            return S_OK;

        if(V_VT(&res) == VT_BOOL) {
            if(V_BOOL(&res)) {
                FIXME("silent mode is not supported\n");
                hres = E_FAIL;
            }
        }else {
862
            FIXME("silent=%s\n", debugstr_variant(&res));
863 864 865 866
        }
        return S_OK;
    case DISPID_AMBIENT_USERAGENT:
        TRACE("(%p)->(DISPID_AMBIENT_USERAGENT)\n", This);
867
        hres = get_client_disp_property(client, DISPID_AMBIENT_USERAGENT, &res);
868 869 870 871 872 873 874 875
        if(FAILED(hres))
            return S_OK;

        FIXME("not supported AMBIENT_USERAGENT\n");
        hres = E_FAIL;
        return S_OK;
    case DISPID_AMBIENT_PALETTE:
        TRACE("(%p)->(DISPID_AMBIENT_PALETTE)\n", This);
876
        hres = get_client_disp_property(client, DISPID_AMBIENT_PALETTE, &res);
877 878 879 880 881 882 883 884
        if(FAILED(hres))
            return S_OK;

        FIXME("not supported AMBIENT_PALETTE\n");
        hres = E_FAIL;
        return S_OK;
    }

885
    FIXME("(%p) unsupported dispID=%d\n", This, dispID);
886
    return E_FAIL;
887 888 889 890
}

static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL bFreeze)
{
891
    HTMLDocument *This = impl_from_IOleControl(iface);
892 893 894 895 896 897 898 899 900 901 902 903 904 905
    FIXME("(%p)->(%x)\n", This, bFreeze);
    return E_NOTIMPL;
}

static const IOleControlVtbl OleControlVtbl = {
    OleControl_QueryInterface,
    OleControl_AddRef,
    OleControl_Release,
    OleControl_GetControlInfo,
    OleControl_OnMnemonic,
    OleControl_OnAmbientPropertyChange,
    OleControl_FreezeEvents
};

906 907 908 909
/**********************************************************
 * IObjectWithSite implementation
 */

910 911 912 913
static inline HTMLDocument *impl_from_IObjectWithSite(IObjectWithSite *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocument, IObjectWithSite_iface);
}
914

915
static HRESULT WINAPI ObjectWithSite_QueryInterface(IObjectWithSite *iface, REFIID riid, void **ppv)
916
{
917
    HTMLDocument *This = impl_from_IObjectWithSite(iface);
918
    return htmldoc_query_interface(This, riid, ppv);
919 920 921 922
}

static ULONG WINAPI ObjectWithSite_AddRef(IObjectWithSite *iface)
{
923
    HTMLDocument *This = impl_from_IObjectWithSite(iface);
924
    return htmldoc_addref(This);
925 926 927 928
}

static ULONG WINAPI ObjectWithSite_Release(IObjectWithSite *iface)
{
929
    HTMLDocument *This = impl_from_IObjectWithSite(iface);
930
    return htmldoc_release(This);
931 932 933 934
}

static HRESULT WINAPI ObjectWithSite_SetSite(IObjectWithSite *iface, IUnknown *pUnkSite)
{
935
    HTMLDocument *This = impl_from_IObjectWithSite(iface);
936 937 938 939 940 941
    FIXME("(%p)->(%p)\n", This, pUnkSite);
    return E_NOTIMPL;
}

static HRESULT WINAPI ObjectWithSite_GetSite(IObjectWithSite* iface, REFIID riid, PVOID *ppvSite)
{
942
    HTMLDocument *This = impl_from_IObjectWithSite(iface);
943 944 945 946 947 948 949 950 951 952 953 954
    FIXME("(%p)->(%p)\n", This, ppvSite);
    return E_NOTIMPL;
}

static const IObjectWithSiteVtbl ObjectWithSiteVtbl = {
    ObjectWithSite_QueryInterface,
    ObjectWithSite_AddRef,
    ObjectWithSite_Release,
    ObjectWithSite_SetSite,
    ObjectWithSite_GetSite
};

955 956 957 958
/**********************************************************
 * IOleContainer implementation
 */

959 960 961 962 963 964 965 966
static inline HTMLDocument *impl_from_IOleContainer(IOleContainer *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocument, IOleContainer_iface);
}

static HRESULT WINAPI OleContainer_QueryInterface(IOleContainer *iface, REFIID riid, void **ppv)
{
    HTMLDocument *This = impl_from_IOleContainer(iface);
967
    return htmldoc_query_interface(This, riid, ppv);
968 969 970 971 972
}

static ULONG WINAPI OleContainer_AddRef(IOleContainer *iface)
{
    HTMLDocument *This = impl_from_IOleContainer(iface);
973
    return htmldoc_addref(This);
974 975 976 977 978
}

static ULONG WINAPI OleContainer_Release(IOleContainer *iface)
{
    HTMLDocument *This = impl_from_IOleContainer(iface);
979
    return htmldoc_release(This);
980 981 982 983 984 985 986 987 988 989 990 991 992
}

static HRESULT WINAPI OleContainer_ParseDisplayName(IOleContainer *iface, IBindCtx *pbc, LPOLESTR pszDisplayName,
        ULONG *pchEaten, IMoniker **ppmkOut)
{
    HTMLDocument *This = impl_from_IOleContainer(iface);
    FIXME("(%p)->(%p %s %p %p)\n", This, pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleContainer_EnumObjects(IOleContainer *iface, DWORD grfFlags, IEnumUnknown **ppenum)
{
    HTMLDocument *This = impl_from_IOleContainer(iface);
993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
    EnumUnknown *ret;

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

    ret = heap_alloc(sizeof(*ret));
    if(!ret)
        return E_OUTOFMEMORY;

    ret->IEnumUnknown_iface.lpVtbl = &EnumUnknownVtbl;
    ret->ref = 1;

    *ppenum = &ret->IEnumUnknown_iface;
    return S_OK;
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023
}

static HRESULT WINAPI OleContainer_LockContainer(IOleContainer *iface, BOOL fLock)
{
    HTMLDocument *This = impl_from_IOleContainer(iface);
    FIXME("(%p)->(%x)\n", This, fLock);
    return E_NOTIMPL;
}

static const IOleContainerVtbl OleContainerVtbl = {
    OleContainer_QueryInterface,
    OleContainer_AddRef,
    OleContainer_Release,
    OleContainer_ParseDisplayName,
    OleContainer_EnumObjects,
    OleContainer_LockContainer
};

1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056
static inline HTMLDocumentObj *impl_from_ITargetContainer(ITargetContainer *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocumentObj, ITargetContainer_iface);
}

static HRESULT WINAPI TargetContainer_QueryInterface(ITargetContainer *iface, REFIID riid, void **ppv)
{
    HTMLDocumentObj *This = impl_from_ITargetContainer(iface);
    return ICustomDoc_QueryInterface(&This->ICustomDoc_iface, riid, ppv);
}

static ULONG WINAPI TargetContainer_AddRef(ITargetContainer *iface)
{
    HTMLDocumentObj *This = impl_from_ITargetContainer(iface);
    return ICustomDoc_AddRef(&This->ICustomDoc_iface);
}

static ULONG WINAPI TargetContainer_Release(ITargetContainer *iface)
{
    HTMLDocumentObj *This = impl_from_ITargetContainer(iface);
    return ICustomDoc_Release(&This->ICustomDoc_iface);
}

static HRESULT WINAPI TargetContainer_GetFrameUrl(ITargetContainer *iface, LPWSTR *ppszFrameSrc)
{
    HTMLDocumentObj *This = impl_from_ITargetContainer(iface);
    FIXME("(%p)->(%p)\n", This, ppszFrameSrc);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetContainer_GetFramesContainer(ITargetContainer *iface, IOleContainer **ppContainer)
{
    HTMLDocumentObj *This = impl_from_ITargetContainer(iface);
1057 1058 1059 1060 1061 1062 1063

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

    /* NOTE: we should return wrapped interface here */
    IOleContainer_AddRef(&This->basedoc.IOleContainer_iface);
    *ppContainer = &This->basedoc.IOleContainer_iface;
    return S_OK;
1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
}

static const ITargetContainerVtbl TargetContainerVtbl = {
    TargetContainer_QueryInterface,
    TargetContainer_AddRef,
    TargetContainer_Release,
    TargetContainer_GetFrameUrl,
    TargetContainer_GetFramesContainer
};

void TargetContainer_Init(HTMLDocumentObj *This)
{
    This->ITargetContainer_iface.lpVtbl = &TargetContainerVtbl;
}

1079 1080 1081 1082 1083 1084 1085 1086 1087 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 1128 1129 1130 1131 1132 1133 1134 1135
/**********************************************************
 * IObjectSafety implementation
 */

static inline HTMLDocument *impl_from_IObjectSafety(IObjectSafety *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocument, IObjectSafety_iface);
}

static HRESULT WINAPI ObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
{
    HTMLDocument *This = impl_from_IObjectSafety(iface);
    return htmldoc_query_interface(This, riid, ppv);
}

static ULONG WINAPI ObjectSafety_AddRef(IObjectSafety *iface)
{
    HTMLDocument *This = impl_from_IObjectSafety(iface);
    return htmldoc_addref(This);
}

static ULONG WINAPI ObjectSafety_Release(IObjectSafety *iface)
{
    HTMLDocument *This = impl_from_IObjectSafety(iface);
    return htmldoc_release(This);
}

static HRESULT WINAPI ObjectSafety_GetInterfaceSafetyOptions(IObjectSafety *iface,
        REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
{
    HTMLDocument *This = impl_from_IObjectSafety(iface);
    FIXME("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
    return E_NOTIMPL;
}

static HRESULT WINAPI ObjectSafety_SetInterfaceSafetyOptions(IObjectSafety *iface,
        REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
{
    HTMLDocument *This = impl_from_IObjectSafety(iface);
    FIXME("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);

    if(IsEqualGUID(&IID_IPersistMoniker, riid) &&
            dwOptionSetMask==INTERFACESAFE_FOR_UNTRUSTED_DATA &&
            dwEnabledOptions==INTERFACESAFE_FOR_UNTRUSTED_DATA)
        return S_OK;

    return E_NOTIMPL;
}

static const IObjectSafetyVtbl ObjectSafetyVtbl = {
    ObjectSafety_QueryInterface,
    ObjectSafety_AddRef,
    ObjectSafety_Release,
    ObjectSafety_GetInterfaceSafetyOptions,
    ObjectSafety_SetInterfaceSafetyOptions
};

1136
void HTMLDocument_LockContainer(HTMLDocumentObj *This, BOOL fLock)
1137 1138 1139 1140
{
    IOleContainer *container;
    HRESULT hres;

1141
    if(!This->client || This->container_locked == fLock)
1142 1143 1144 1145 1146
        return;

    hres = IOleClientSite_GetContainer(This->client, &container);
    if(SUCCEEDED(hres)) {
        IOleContainer_LockContainer(container, fLock);
1147
        This->container_locked = fLock;
1148 1149 1150 1151
        IOleContainer_Release(container);
    }
}

1152 1153
void HTMLDocument_OleObj_Init(HTMLDocument *This)
{
1154
    This->IOleObject_iface.lpVtbl = &OleObjectVtbl;
1155
    This->IOleDocument_iface.lpVtbl = &OleDocumentVtbl;
1156
    This->IOleControl_iface.lpVtbl = &OleControlVtbl;
1157
    This->IObjectWithSite_iface.lpVtbl = &ObjectWithSiteVtbl;
1158
    This->IOleContainer_iface.lpVtbl = &OleContainerVtbl;
1159
    This->IObjectSafety_iface.lpVtbl = &ObjectSafetyVtbl;
1160
}