oleobj.c 37.4 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
 */

#include "config.h"

#include <stdarg.h>
#include <stdio.h>
23
#include <assert.h>
24 25 26 27 28 29 30

#define COBJMACROS

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

#include "wine/debug.h"

#include "mshtml_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

42 43
#define DOCHOST_DOCCANNAVIGATE  0

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 139
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
};

140 141 142 143
/**********************************************************
 * IOleObject implementation
 */

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

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

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

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

167
static void update_hostinfo(HTMLDocumentObj *This, DOCHOSTUIINFO *hostinfo)
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
{
    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);
    }
}

193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
/* 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");
}

214
void set_document_navigation(HTMLDocumentObj *doc, BOOL doc_can_navigate)
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
{
    VARIANT var;

    if(!doc->client_cmdtrg)
        return;

    if(doc_can_navigate) {
        V_VT(&var) = VT_UNKNOWN;
        V_UNKNOWN(&var) = (IUnknown*)&doc->basedoc.window->base.IHTMLWindow2_iface;
    }

    IOleCommandTarget_Exec(doc->client_cmdtrg, &CGID_DocHostCmdPriv, DOCHOST_DOCCANNAVIGATE, 0,
            doc_can_navigate ? &var : NULL, NULL);
}

230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
static void load_settings(HTMLDocumentObj *doc)
{
    HKEY settings_key;
    DWORD val, size;
    LONG res;

    static const WCHAR ie_keyW[] = {
        'S','O','F','T','W','A','R','E','\\',
        'M','i','c','r','o','s','o','f','t','\\',
        'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r',0};
    static const WCHAR zoomW[] = {'Z','o','o','m',0};
    static const WCHAR zoom_factorW[] = {'Z','o','o','m','F','a','c','t','o','r',0};

    res = RegOpenKeyW(HKEY_CURRENT_USER, ie_keyW, &settings_key);
    if(res != ERROR_SUCCESS)
        return;

    size = sizeof(val);
    res = RegGetValueW(settings_key, zoomW, zoom_factorW, RRF_RT_REG_DWORD, NULL, &val, &size);
    RegCloseKey(settings_key);
250 251
    if(res == ERROR_SUCCESS)
        set_viewer_zoom(doc->nscontainer, (float)val/100000);
252 253
}

254 255
static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite *pClientSite)
{
256
    HTMLDocument *This = impl_from_IOleObject(iface);
257
    IOleCommandTarget *cmdtrg = NULL;
258
    IOleWindow *ole_window;
259
    IBrowserService *browser_service;
260
    BOOL hostui_setup;
261
    VARIANT silent;
262
    HWND hwnd;
263 264
    HRESULT hres;

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

267
    if(pClientSite == This->doc_obj->client)
268 269
        return S_OK;

270 271 272
    if(This->doc_obj->client) {
        IOleClientSite_Release(This->doc_obj->client);
        This->doc_obj->client = NULL;
273
        This->doc_obj->usermode = UNKNOWN_USERMODE;
274
    }
275

276 277 278 279 280
    if(This->doc_obj->client_cmdtrg) {
        IOleCommandTarget_Release(This->doc_obj->client_cmdtrg);
        This->doc_obj->client_cmdtrg = NULL;
    }

281
    if(This->doc_obj->hostui && !This->doc_obj->custom_hostui) {
282 283
        IDocHostUIHandler_Release(This->doc_obj->hostui);
        This->doc_obj->hostui = NULL;
284
    }
285

286 287 288 289 290
    if(This->doc_obj->doc_object_service) {
        IDocObjectService_Release(This->doc_obj->doc_object_service);
        This->doc_obj->doc_object_service = NULL;
    }

291 292 293 294 295
    if(This->doc_obj->webbrowser) {
        IUnknown_Release(This->doc_obj->webbrowser);
        This->doc_obj->webbrowser = NULL;
    }

296 297 298 299 300 301 302 303 304 305
    if(This->doc_obj->browser_service) {
        IUnknown_Release(This->doc_obj->browser_service);
        This->doc_obj->browser_service = NULL;
    }

    if(This->doc_obj->travel_log) {
        ITravelLog_Release(This->doc_obj->travel_log);
        This->doc_obj->travel_log = NULL;
    }

306
    memset(&This->doc_obj->hostinfo, 0, sizeof(DOCHOSTUIINFO));
307

308
    if(!pClientSite)
309 310
        return S_OK;

311 312 313
    IOleClientSite_AddRef(pClientSite);
    This->doc_obj->client = pClientSite;

314 315
    hostui_setup = This->doc_obj->hostui_setup;

316 317 318 319 320
    if(!This->doc_obj->hostui) {
        IDocHostUIHandler *uihandler;

        This->doc_obj->custom_hostui = FALSE;

321
        hres = IOleClientSite_QueryInterface(pClientSite, &IID_IDocHostUIHandler, (void**)&uihandler);
322 323 324 325 326
        if(SUCCEEDED(hres))
            This->doc_obj->hostui = uihandler;
    }

    if(This->doc_obj->hostui) {
327 328
        DOCHOSTUIINFO hostinfo;
        LPOLESTR key_path = NULL, override_key_path = NULL;
329
        IDocHostUIHandler2 *uihandler2;
330

331 332
        memset(&hostinfo, 0, sizeof(DOCHOSTUIINFO));
        hostinfo.cbSize = sizeof(DOCHOSTUIINFO);
333
        hres = IDocHostUIHandler_GetHostInfo(This->doc_obj->hostui, &hostinfo);
334
        if(SUCCEEDED(hres)) {
335
            TRACE("hostinfo = {%u %08x %08x %s %s}\n",
336 337
                    hostinfo.cbSize, hostinfo.dwFlags, hostinfo.dwDoubleClick,
                    debugstr_w(hostinfo.pchHostCss), debugstr_w(hostinfo.pchHostNS));
338
            update_hostinfo(This->doc_obj, &hostinfo);
339
            This->doc_obj->hostinfo = hostinfo;
340
        }
341

342
        if(!hostui_setup) {
343
            hres = IDocHostUIHandler_GetOptionKeyPath(This->doc_obj->hostui, &key_path, 0);
Jacek Caban's avatar
Jacek Caban committed
344 345 346
            if(hres == S_OK && key_path) {
                if(key_path[0]) {
                    /* FIXME: use key_path */
347
                    FIXME("key_path = %s\n", debugstr_w(key_path));
Jacek Caban's avatar
Jacek Caban committed
348 349 350
                }
                CoTaskMemFree(key_path);
            }
351

352 353
            hres = IDocHostUIHandler_QueryInterface(This->doc_obj->hostui, &IID_IDocHostUIHandler2,
                    (void**)&uihandler2);
Jacek Caban's avatar
Jacek Caban committed
354
            if(SUCCEEDED(hres)) {
355
                hres = IDocHostUIHandler2_GetOverrideKeyPath(uihandler2, &override_key_path, 0);
356
                if(hres == S_OK && override_key_path) {
Jacek Caban's avatar
Jacek Caban committed
357 358
                    if(override_key_path[0]) {
                        /*FIXME: use override_key_path */
359
                        FIXME("override_key_path = %s\n", debugstr_w(override_key_path));
Jacek Caban's avatar
Jacek Caban committed
360 361 362
                    }
                    CoTaskMemFree(override_key_path);
                }
363
                IDocHostUIHandler2_Release(uihandler2);
Jacek Caban's avatar
Jacek Caban committed
364 365
            }

366
            This->doc_obj->hostui_setup = TRUE;
367 368 369
        }
    }

370 371
    load_settings(This->doc_obj);

Jacek Caban's avatar
Jacek Caban committed
372 373
    /* Native calls here GetWindow. What is it for?
     * We don't have anything to do with it here (yet). */
374 375 376 377
    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
378 379
    }

380 381 382 383 384 385 386 387 388 389 390 391 392 393
    hres = do_query_service((IUnknown*)pClientSite, &IID_IShellBrowser,
            &IID_IBrowserService, (void**)&browser_service);
    if(SUCCEEDED(hres)) {
        ITravelLog *travel_log;

        This->doc_obj->browser_service = (IUnknown*)browser_service;

        hres = IBrowserService_GetTravelLog(browser_service, &travel_log);
        if(SUCCEEDED(hres))
            This->doc_obj->travel_log = travel_log;
    }else {
        browser_service = NULL;
    }

394 395 396 397 398
    hres = IOleClientSite_QueryInterface(pClientSite, &IID_IOleCommandTarget, (void**)&cmdtrg);
    if(SUCCEEDED(hres)) {
        VARIANT var;
        OLECMD cmd = {OLECMDID_SETPROGRESSTEXT, 0};

399 400
        This->doc_obj->client_cmdtrg = cmdtrg;

401
        if(!hostui_setup) {
402 403
            IDocObjectService *doc_object_service;
            IWebBrowser2 *wb;
404

405
            set_document_navigation(This->doc_obj, TRUE);
406

407
            if(browser_service) {
408 409
                hres = IBrowserService_QueryInterface(browser_service,
                        &IID_IDocObjectService, (void**)&doc_object_service);
410
                if(SUCCEEDED(hres)) {
411 412 413 414 415 416 417
                    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);
418 419
                    if(SUCCEEDED(hres))
                        This->doc_obj->webbrowser = (IUnknown*)wb;
420 421
                }
            }
422 423
        }

424 425
        call_docview_84(This->doc_obj);

426 427 428 429
        IOleCommandTarget_QueryStatus(cmdtrg, NULL, 1, &cmd, NULL);

        V_VT(&var) = VT_I4;
        V_I4(&var) = 0;
430 431 432 433
        IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSMAX,
                OLECMDEXECOPT_DONTPROMPTUSER, &var, NULL);
        IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSPOS, 
                OLECMDEXECOPT_DONTPROMPTUSER, &var, NULL);
434 435
    }

436
    if(This->doc_obj->usermode == UNKNOWN_USERMODE)
437
        IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface, DISPID_AMBIENT_USERMODE);
438

439 440
    IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface,
            DISPID_AMBIENT_OFFLINEIFNOTCONNECTED);
441

442
    hres = get_client_disp_property(This->doc_obj->client, DISPID_AMBIENT_SILENT, &silent);
443 444
    if(SUCCEEDED(hres)) {
        if(V_VT(&silent) != VT_BOOL)
445
            WARN("silent = %s\n", debugstr_variant(&silent));
446 447 448 449
        else if(V_BOOL(&silent))
            FIXME("silent == true\n");
    }

450 451
    IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface, DISPID_AMBIENT_USERAGENT);
    IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface, DISPID_AMBIENT_PALETTE);
452

453 454 455 456 457
    return S_OK;
}

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

460 461 462 463 464
    TRACE("(%p)->(%p)\n", This, ppClientSite);

    if(!ppClientSite)
        return E_INVALIDARG;

465 466 467
    if(This->doc_obj->client)
        IOleClientSite_AddRef(This->doc_obj->client);
    *ppClientSite = This->doc_obj->client;
468 469 470 471 472 473

    return S_OK;
}

static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
{
474
    HTMLDocument *This = impl_from_IOleObject(iface);
475 476 477 478 479 480
    FIXME("(%p)->(%s %s)\n", This, debugstr_w(szContainerApp), debugstr_w(szContainerObj));
    return E_NOTIMPL;
}

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

483
    TRACE("(%p)->(%08x)\n", This, dwSaveOption);
484 485 486 487

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

488
    if(This->doc_obj->in_place_active)
489
        IOleInPlaceObjectWindowless_InPlaceDeactivate(&This->IOleInPlaceObjectWindowless_iface);
Jacek Caban's avatar
Jacek Caban committed
490

491
    HTMLDocument_LockContainer(This->doc_obj, FALSE);
492 493 494

    if(This->advise_holder)
        IOleAdviseHolder_SendOnClose(This->advise_holder);
Jacek Caban's avatar
Jacek Caban committed
495 496
    
    return S_OK;
497 498 499 500
}

static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD dwWhichMoniker, IMoniker *pmk)
{
501
    HTMLDocument *This = impl_from_IOleObject(iface);
502
    FIXME("(%p %d %p)->()\n", This, dwWhichMoniker, pmk);
503 504 505 506 507
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
{
508
    HTMLDocument *This = impl_from_IOleObject(iface);
509
    FIXME("(%p)->(%d %d %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
510 511 512 513 514 515
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, IDataObject *pDataObject, BOOL fCreation,
                                        DWORD dwReserved)
{
516
    HTMLDocument *This = impl_from_IOleObject(iface);
517
    FIXME("(%p)->(%p %x %d)\n", This, pDataObject, fCreation, dwReserved);
518 519 520 521 522
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD dwReserved, IDataObject **ppDataObject)
{
523
    HTMLDocument *This = impl_from_IOleObject(iface);
524
    FIXME("(%p)->(%d %p)\n", This, dwReserved, ppDataObject);
525 526 527 528 529 530
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite,
                                        LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
{
531
    HTMLDocument *This = impl_from_IOleObject(iface);
532 533 534
    IOleDocumentSite *pDocSite;
    HRESULT hres;

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

537
    if(iVerb != OLEIVERB_SHOW && iVerb != OLEIVERB_UIACTIVATE && iVerb != OLEIVERB_INPLACEACTIVATE) { 
538
        FIXME("iVerb = %d not supported\n", iVerb);
539 540 541 542
        return E_NOTIMPL;
    }

    if(!pActiveSite)
543
        pActiveSite = This->doc_obj->client;
544 545 546

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

549
        /* FIXME: Create new IOleDocumentView. See CreateView for more info. */
550
        hres = IOleDocumentSite_ActivateMe(pDocSite, &This->IOleDocumentView_iface);
551 552
        IOleDocumentSite_Release(pDocSite);
    }else {
553
        hres = IOleDocumentView_UIActivate(&This->IOleDocumentView_iface, TRUE);
554 555 556
        if(SUCCEEDED(hres)) {
            if(lprcPosRect) {
                RECT rect; /* We need to pass rect as not const pointer */
557
                rect = *lprcPosRect;
558
                IOleDocumentView_SetRect(&This->IOleDocumentView_iface, &rect);
559
            }
560
            IOleDocumentView_Show(&This->IOleDocumentView_iface, TRUE);
561 562 563 564
        }
    }

    return hres;
565 566 567 568
}

static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **ppEnumOleVerb)
{
569
    HTMLDocument *This = impl_from_IOleObject(iface);
570 571 572 573 574 575
    FIXME("(%p)->(%p)\n", This, ppEnumOleVerb);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_Update(IOleObject *iface)
{
576
    HTMLDocument *This = impl_from_IOleObject(iface);
577 578 579 580 581 582
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
{
583
    HTMLDocument *This = impl_from_IOleObject(iface);
584 585 586 587 588 589
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

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

592 593 594 595 596
    TRACE("(%p)->(%p)\n", This, pClsid);

    if(!pClsid)
        return E_INVALIDARG;

597
    *pClsid = CLSID_HTMLDocument;
598 599 600 601 602
    return S_OK;
}

static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD dwFormOfType, LPOLESTR *pszUserType)
{
603
    HTMLDocument *This = impl_from_IOleObject(iface);
604
    FIXME("(%p)->(%d %p)\n", This, dwFormOfType, pszUserType);
605 606 607 608 609
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
{
610
    HTMLDocument *This = impl_from_IOleObject(iface);
611
    FIXME("(%p)->(%d %p)\n", This, dwDrawAspect, psizel);
612 613 614 615 616
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
{
617
    HTMLDocument *This = impl_from_IOleObject(iface);
618
    FIXME("(%p)->(%d %p)\n", This, dwDrawAspect, psizel);
619 620 621 622 623
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *pAdvSink, DWORD *pdwConnection)
{
624
    HTMLDocument *This = impl_from_IOleObject(iface);
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
    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);
642 643 644 645
}

static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD dwConnection)
{
646
    HTMLDocument *This = impl_from_IOleObject(iface);
647 648 649 650 651 652
    TRACE("(%p)->(%d)\n", This, dwConnection);

    if(!This->advise_holder)
        return OLE_E_NOCONNECTION;

    return IOleAdviseHolder_Unadvise(This->advise_holder, dwConnection);
653 654 655 656
}

static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **ppenumAdvise)
{
657
    HTMLDocument *This = impl_from_IOleObject(iface);
658 659 660 661 662 663 664

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

    return IOleAdviseHolder_EnumAdvise(This->advise_holder, ppenumAdvise);
665 666 667 668
}

static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD dwAspect, DWORD *pdwStatus)
{
669
    HTMLDocument *This = impl_from_IOleObject(iface);
670
    FIXME("(%p)->(%d %p)\n", This, dwAspect, pdwStatus);
671 672 673 674 675
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE *pLogpal)
{
676
    HTMLDocument *This = impl_from_IOleObject(iface);
677 678 679 680
    FIXME("(%p)->(%p)\n", This, pLogpal);
    return E_NOTIMPL;
}

681
static const IOleObjectVtbl OleObjectVtbl = {
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711
    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
 */

712 713 714 715
static inline HTMLDocument *impl_from_IOleDocument(IOleDocument *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocument, IOleDocument_iface);
}
716

717
static HRESULT WINAPI OleDocument_QueryInterface(IOleDocument *iface, REFIID riid, void **ppv)
718
{
719
    HTMLDocument *This = impl_from_IOleDocument(iface);
720
    return htmldoc_query_interface(This, riid, ppv);
721 722 723 724
}

static ULONG WINAPI OleDocument_AddRef(IOleDocument *iface)
{
725
    HTMLDocument *This = impl_from_IOleDocument(iface);
726
    return htmldoc_addref(This);
727 728 729 730
}

static ULONG WINAPI OleDocument_Release(IOleDocument *iface)
{
731
    HTMLDocument *This = impl_from_IOleDocument(iface);
732
    return htmldoc_release(This);
733 734 735 736 737
}

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

741
    TRACE("(%p)->(%p %p %d %p)\n", This, pIPSite, pstm, dwReserved, ppView);
742 743 744 745 746 747 748 749 750 751 752 753

    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) {
754
        hres = IOleDocumentView_SetInPlaceSite(&This->IOleDocumentView_iface, pIPSite);
755 756 757 758 759 760 761
        if(FAILED(hres))
            return hres;
    }

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

762 763
    IOleDocumentView_AddRef(&This->IOleDocumentView_iface);
    *ppView = &This->IOleDocumentView_iface;
764
    return S_OK;
765 766 767 768
}

static HRESULT WINAPI OleDocument_GetDocMiscStatus(IOleDocument *iface, DWORD *pdwStatus)
{
769
    HTMLDocument *This = impl_from_IOleDocument(iface);
770 771 772 773 774 775 776
    FIXME("(%p)->(%p)\n", This, pdwStatus);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleDocument_EnumViews(IOleDocument *iface, IEnumOleDocumentViews **ppEnum,
                                   IOleDocumentView **ppView)
{
777
    HTMLDocument *This = impl_from_IOleDocument(iface);
778 779 780 781
    FIXME("(%p)->(%p %p)\n", This, ppEnum, ppView);
    return E_NOTIMPL;
}

782
static const IOleDocumentVtbl OleDocumentVtbl = {
783 784 785 786 787 788 789 790
    OleDocument_QueryInterface,
    OleDocument_AddRef,
    OleDocument_Release,
    OleDocument_CreateView,
    OleDocument_GetDocMiscStatus,
    OleDocument_EnumViews
};

791 792 793 794
/**********************************************************
 * IOleControl implementation
 */

795 796 797 798
static inline HTMLDocument *impl_from_IOleControl(IOleControl *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocument, IOleControl_iface);
}
799 800 801

static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **ppv)
{
802
    HTMLDocument *This = impl_from_IOleControl(iface);
803
    return htmldoc_query_interface(This, riid, ppv);
804 805 806 807
}

static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
{
808
    HTMLDocument *This = impl_from_IOleControl(iface);
809
    return htmldoc_addref(This);
810 811 812 813
}

static ULONG WINAPI OleControl_Release(IOleControl *iface)
{
814
    HTMLDocument *This = impl_from_IOleControl(iface);
815
    return htmldoc_release(This);
816 817 818 819
}

static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, CONTROLINFO *pCI)
{
820
    HTMLDocument *This = impl_from_IOleControl(iface);
821 822 823 824 825 826
    FIXME("(%p)->(%p)\n", This, pCI);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, MSG *pMsg)
{
827
    HTMLDocument *This = impl_from_IOleControl(iface);
828 829 830 831
    FIXME("(%p)->(%p)\n", This, pMsg);
    return E_NOTIMPL;
}

832
HRESULT get_client_disp_property(IOleClientSite *client, DISPID dispid, VARIANT *res)
833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859
{
    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;
    
860
    hres = get_client_disp_property(This->doc_obj->client, DISPID_AMBIENT_DLCONTROL, &res);
861
    if(SUCCEEDED(hres))
862
        FIXME("unsupported dlcontrol %08x\n", V_I4(&res));
863 864 865 866

    return S_OK;
}

867 868
static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispID)
{
869
    HTMLDocument *This = impl_from_IOleControl(iface);
870
    IOleClientSite *client;
871 872 873
    VARIANT res;
    HRESULT hres;

874 875 876
    client = This->doc_obj->client;
    if(!client) {
        TRACE("client = NULL\n");
877 878 879 880 881 882
        return S_OK;
    }

    switch(dispID) {
    case DISPID_AMBIENT_USERMODE:
        TRACE("(%p)->(DISPID_AMBIENT_USERMODE)\n", This);
883
        hres = get_client_disp_property(client, DISPID_AMBIENT_USERMODE, &res);
884 885 886 887
        if(FAILED(hres))
            return S_OK;

        if(V_VT(&res) == VT_BOOL) {
888
            if(V_BOOL(&res)) {
889
                This->doc_obj->usermode = BROWSEMODE;
890
            }else {
891
                FIXME("edit mode is not supported\n");
892
                This->doc_obj->usermode = EDITMODE;
893 894
            }
        }else {
895
            FIXME("usermode=%s\n", debugstr_variant(&res));
896 897 898 899 900 901 902 903
        }
        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);
904
        hres = get_client_disp_property(client, DISPID_AMBIENT_OFFLINEIFNOTCONNECTED, &res);
905 906 907 908 909 910 911 912 913
        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 {
914
            FIXME("offlineconnected=%s\n", debugstr_variant(&res));
915 916 917 918 919
        }
        return S_OK;
    case DISPID_AMBIENT_SILENT:
        TRACE("(%p)->(DISPID_AMBIENT_SILENT)\n", This);
        on_change_dlcontrol(This);
920
        hres = get_client_disp_property(client, DISPID_AMBIENT_SILENT, &res);
921 922 923 924 925 926 927 928 929
        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 {
930
            FIXME("silent=%s\n", debugstr_variant(&res));
931 932 933 934
        }
        return S_OK;
    case DISPID_AMBIENT_USERAGENT:
        TRACE("(%p)->(DISPID_AMBIENT_USERAGENT)\n", This);
935
        hres = get_client_disp_property(client, DISPID_AMBIENT_USERAGENT, &res);
936 937 938 939 940 941 942 943
        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);
944
        hres = get_client_disp_property(client, DISPID_AMBIENT_PALETTE, &res);
945 946 947 948 949 950 951 952
        if(FAILED(hres))
            return S_OK;

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

953
    FIXME("(%p) unsupported dispID=%d\n", This, dispID);
954
    return E_FAIL;
955 956 957 958
}

static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL bFreeze)
{
959
    HTMLDocument *This = impl_from_IOleControl(iface);
960 961 962 963 964 965 966 967 968 969 970 971 972 973
    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
};

974 975 976 977
/**********************************************************
 * IObjectWithSite implementation
 */

978 979 980 981
static inline HTMLDocument *impl_from_IObjectWithSite(IObjectWithSite *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocument, IObjectWithSite_iface);
}
982

983
static HRESULT WINAPI ObjectWithSite_QueryInterface(IObjectWithSite *iface, REFIID riid, void **ppv)
984
{
985
    HTMLDocument *This = impl_from_IObjectWithSite(iface);
986
    return htmldoc_query_interface(This, riid, ppv);
987 988 989 990
}

static ULONG WINAPI ObjectWithSite_AddRef(IObjectWithSite *iface)
{
991
    HTMLDocument *This = impl_from_IObjectWithSite(iface);
992
    return htmldoc_addref(This);
993 994 995 996
}

static ULONG WINAPI ObjectWithSite_Release(IObjectWithSite *iface)
{
997
    HTMLDocument *This = impl_from_IObjectWithSite(iface);
998
    return htmldoc_release(This);
999 1000 1001 1002
}

static HRESULT WINAPI ObjectWithSite_SetSite(IObjectWithSite *iface, IUnknown *pUnkSite)
{
1003
    HTMLDocument *This = impl_from_IObjectWithSite(iface);
1004 1005 1006 1007 1008 1009
    FIXME("(%p)->(%p)\n", This, pUnkSite);
    return E_NOTIMPL;
}

static HRESULT WINAPI ObjectWithSite_GetSite(IObjectWithSite* iface, REFIID riid, PVOID *ppvSite)
{
1010
    HTMLDocument *This = impl_from_IObjectWithSite(iface);
1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022
    FIXME("(%p)->(%p)\n", This, ppvSite);
    return E_NOTIMPL;
}

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

1023 1024 1025 1026
/**********************************************************
 * IOleContainer implementation
 */

1027 1028 1029 1030 1031 1032 1033 1034
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);
1035
    return htmldoc_query_interface(This, riid, ppv);
1036 1037 1038 1039 1040
}

static ULONG WINAPI OleContainer_AddRef(IOleContainer *iface)
{
    HTMLDocument *This = impl_from_IOleContainer(iface);
1041
    return htmldoc_addref(This);
1042 1043 1044 1045 1046
}

static ULONG WINAPI OleContainer_Release(IOleContainer *iface)
{
    HTMLDocument *This = impl_from_IOleContainer(iface);
1047
    return htmldoc_release(This);
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
}

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);
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
    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;
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091
}

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
};

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
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);
1125 1126 1127 1128 1129 1130 1131

    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;
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
}

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

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

1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203
/**********************************************************
 * 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
};

1204
void HTMLDocument_LockContainer(HTMLDocumentObj *This, BOOL fLock)
1205 1206 1207 1208
{
    IOleContainer *container;
    HRESULT hres;

1209
    if(!This->client || This->container_locked == fLock)
1210 1211 1212 1213 1214
        return;

    hres = IOleClientSite_GetContainer(This->client, &container);
    if(SUCCEEDED(hres)) {
        IOleContainer_LockContainer(container, fLock);
1215
        This->container_locked = fLock;
1216 1217 1218 1219
        IOleContainer_Release(container);
    }
}

1220 1221
void HTMLDocument_OleObj_Init(HTMLDocument *This)
{
1222
    This->IOleObject_iface.lpVtbl = &OleObjectVtbl;
1223
    This->IOleDocument_iface.lpVtbl = &OleDocumentVtbl;
1224
    This->IOleControl_iface.lpVtbl = &OleControlVtbl;
1225
    This->IObjectWithSite_iface.lpVtbl = &ObjectWithSiteVtbl;
1226
    This->IOleContainer_iface.lpVtbl = &OleContainerVtbl;
1227
    This->IObjectSafety_iface.lpVtbl = &ObjectSafetyVtbl;
1228
}