client.c 22.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright 2005 Jacek Caban for CodeWeavers
 *
 * 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
#include <stdio.h>

21 22
#include "ieframe.h"

23 24
#include "mshtmdid.h"
#include "idispids.h"
25

26 27
#include "wine/debug.h"

28
WINE_DEFAULT_DEBUG_CHANNEL(ieframe);
29

30 31
static inline DocHost *impl_from_IOleClientSite(IOleClientSite *iface)
{
32
    return CONTAINING_RECORD(iface, DocHost, IOleClientSite_iface);
33
}
34 35 36

static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
{
37
    DocHost *This = impl_from_IOleClientSite(iface);
38 39 40

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
41
        *ppv = &This->IOleClientSite_iface;
42 43
    }else if(IsEqualGUID(&IID_IOleClientSite, riid)) {
        TRACE("(%p)->(IID_IOleClientSite %p)\n", This, ppv);
44
        *ppv = &This->IOleClientSite_iface;
45 46
    }else if(IsEqualGUID(&IID_IOleWindow, riid)) {
        TRACE("(%p)->(IID_IOleWindow %p)\n", This, ppv);
47
        *ppv = &This->IOleInPlaceSiteEx_iface;
48 49
    }else if(IsEqualGUID(&IID_IOleInPlaceSite, riid)) {
        TRACE("(%p)->(IID_IOleInPlaceSite %p)\n", This, ppv);
50 51 52 53
        *ppv = &This->IOleInPlaceSiteEx_iface;
    }else if(IsEqualGUID(&IID_IOleInPlaceSiteEx, riid)) {
        TRACE("(%p)->(IID_IOleInPlaceSiteEx %p)\n", This, ppv);
        *ppv = &This->IOleInPlaceSiteEx_iface;
54 55
    }else if(IsEqualGUID(&IID_IDocHostUIHandler, riid)) {
        TRACE("(%p)->(IID_IDocHostUIHandler %p)\n", This, ppv);
56
        *ppv = &This->IDocHostUIHandler2_iface;
57 58
    }else if(IsEqualGUID(&IID_IDocHostUIHandler2, riid)) {
        TRACE("(%p)->(IID_IDocHostUIHandler2 %p)\n", This, ppv);
59
        *ppv = &This->IDocHostUIHandler2_iface;
60 61
    }else if(IsEqualGUID(&IID_IOleDocumentSite, riid)) {
        TRACE("(%p)->(IID_IOleDocumentSite %p)\n", This, ppv);
62
        *ppv = &This->IOleDocumentSite_iface;
63 64 65
    }else if(IsEqualGUID(&IID_IOleControlSite, riid)) {
        TRACE("(%p)->(IID_IOleControlSite %p)\n", This, ppv);
        *ppv = &This->IOleControlSite_iface;
66 67
    }else if(IsEqualGUID(&IID_IOleCommandTarget, riid)) {
        TRACE("(%p)->(IID_IOleCommandTarget %p)\n", This, ppv);
68
        *ppv = &This->IOleCommandTarget_iface;
69 70
    }else if(IsEqualGUID(&IID_IDispatch, riid)) {
        TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
71
        *ppv = &This->IDispatch_iface;
72 73
    }else if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
        TRACE("(%p)->(IID_IPropertyNotifySink %p)\n", This, ppv);
74
        *ppv = &This->IPropertyNotifySink_iface;
75 76
    }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
        TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
77
        *ppv = &This->IServiceProvider_iface;
78 79 80 81
    }else {
        *ppv = NULL;
        WARN("Unsupported interface %s\n", debugstr_guid(riid));
        return E_NOINTERFACE;
82 83
    }

84
    IUnknown_AddRef((IUnknown*)*ppv);
85
    return S_OK;
86 87 88 89
}

static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface)
{
90
    DocHost *This = impl_from_IOleClientSite(iface);
91
    return This->container_vtbl->addref(This);
92 93 94 95
}

static ULONG WINAPI ClientSite_Release(IOleClientSite *iface)
{
96
    DocHost *This = impl_from_IOleClientSite(iface);
97
    return This->container_vtbl->release(This);
98 99 100 101
}

static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface)
{
102
    DocHost *This = impl_from_IOleClientSite(iface);
103 104 105 106 107 108 109
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign,
                                            DWORD dwWhichMoniker, IMoniker **ppmk)
{
110
    DocHost *This = impl_from_IOleClientSite(iface);
111
    FIXME("(%p)->(%d %d %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
112 113 114 115 116
    return E_NOTIMPL;
}

static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
{
117
    DocHost *This = impl_from_IOleClientSite(iface);
118 119 120 121 122 123
    FIXME("(%p)->(%p)\n", This, ppContainer);
    return E_NOTIMPL;
}

static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface)
{
124
    DocHost *This = impl_from_IOleClientSite(iface);
125 126 127 128 129 130
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
{
131
    DocHost *This = impl_from_IOleClientSite(iface);
132 133 134 135 136 137
    FIXME("(%p)->(%x)\n", This, fShow);
    return E_NOTIMPL;
}

static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface)
{
138
    DocHost *This = impl_from_IOleClientSite(iface);
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static const IOleClientSiteVtbl OleClientSiteVtbl = {
    ClientSite_QueryInterface,
    ClientSite_AddRef,
    ClientSite_Release,
    ClientSite_SaveObject,
    ClientSite_GetMoniker,
    ClientSite_GetContainer,
    ClientSite_ShowObject,
    ClientSite_OnShowWindow,
    ClientSite_RequestNewObjectLayout
};

155
static inline DocHost *impl_from_IOleInPlaceSiteEx(IOleInPlaceSiteEx *iface)
156
{
157
    return CONTAINING_RECORD(iface, DocHost, IOleInPlaceSiteEx_iface);
158
}
159

160
static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSiteEx *iface, REFIID riid, void **ppv)
161
{
162
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
163
    return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
164 165
}

166
static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSiteEx *iface)
167
{
168
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
169
    return IOleClientSite_AddRef(&This->IOleClientSite_iface);
170 171
}

172
static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSiteEx *iface)
173
{
174
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
175
    return IOleClientSite_Release(&This->IOleClientSite_iface);
176 177
}

178
static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSiteEx *iface, HWND *phwnd)
179
{
180
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
181 182 183

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

184
    *phwnd = This->hwnd;
185
    return S_OK;
186 187
}

188
static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSiteEx *iface, BOOL fEnterMode)
189
{
190
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
191 192 193 194
    FIXME("(%p)->(%x)\n", This, fEnterMode);
    return E_NOTIMPL;
}

195
static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSiteEx *iface)
196
{
197
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
198 199 200 201 202

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

    /* Nothing to do here */
    return S_OK;
203 204
}

205
static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSiteEx *iface)
206
{
207
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
208 209 210 211 212

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

    /* Nothing to do here */
    return S_OK;
213 214
}

215
static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSiteEx *iface)
216
{
217
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
218 219 220 221
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

222
static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSiteEx *iface,
223 224 225
        IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
        LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
{
226
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
227 228

    TRACE("(%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect,
229
          lprcClipRect, lpFrameInfo);
230

231 232
    IOleInPlaceFrame_AddRef(&This->IOleInPlaceFrame_iface);
    *ppFrame = &This->IOleInPlaceFrame_iface;
233
    *ppDoc = NULL;
234

235
    GetClientRect(This->hwnd, lprcPosRect);
236
    *lprcClipRect = *lprcPosRect;
237 238

    lpFrameInfo->fMDIApp = FALSE;
239
    lpFrameInfo->hwndFrame = This->frame_hwnd;
240 241 242 243
    lpFrameInfo->haccel = NULL;
    lpFrameInfo->cAccelEntries = 0; /* FIXME: should be 5 */

    return S_OK;
244 245
}

246
static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSiteEx *iface, SIZE scrollExtent)
247
{
248
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
249
    FIXME("(%p)->({%d %d})\n", This, scrollExtent.cx, scrollExtent.cy);
250 251 252
    return E_NOTIMPL;
}

253
static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSiteEx *iface, BOOL fUndoable)
254
{
255
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
256 257 258 259
    FIXME("(%p)->(%x)\n", This, fUndoable);
    return E_NOTIMPL;
}

260
static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSiteEx *iface)
261
{
262
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
263 264 265 266 267

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

    /* Nothing to do here */
    return S_OK;
268 269
}

270
static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSiteEx *iface)
271
{
272
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
273 274 275 276
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

277
static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSiteEx *iface)
278
{
279
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
280 281 282 283
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

284
static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSiteEx *iface,
285 286
                                                  LPCRECT lprcPosRect)
{
287
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
288 289 290 291
    FIXME("(%p)->(%p)\n", This, lprcPosRect);
    return E_NOTIMPL;
}

292 293 294 295 296 297 298 299
static HRESULT WINAPI InPlaceSite_OnInPlaceActivateEx(IOleInPlaceSiteEx *iface,
                                                     BOOL *pfNoRedraw, DWORD dwFlags)
{
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);

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

    /* FIXME: Avoid redraw, when possible */
300
    *pfNoRedraw = FALSE;
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333

    if (dwFlags) {
        FIXME("dwFlags not supported (%x)\n", dwFlags);
    }

    /* Nothing to do here */
    return S_OK;
}

static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivateEx(IOleInPlaceSiteEx *iface, BOOL fNoRedraw)
{
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);

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

    if (fNoRedraw) {
        FIXME("fNoRedraw (%x) ignored\n", fNoRedraw);
    }

    /* Nothing to do here */
    return S_OK;
}

static HRESULT WINAPI InPlaceSite_RequestUIActivate(IOleInPlaceSiteEx *iface)
{
    DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
    TRACE("(%p)\n", This);

    /* OnUIActivate is always possible */
    return S_OK;
}

static const IOleInPlaceSiteExVtbl OleInPlaceSiteExVtbl = {
334 335 336 337 338 339 340 341 342 343 344 345 346 347
    InPlaceSite_QueryInterface,
    InPlaceSite_AddRef,
    InPlaceSite_Release,
    InPlaceSite_GetWindow,
    InPlaceSite_ContextSensitiveHelp,
    InPlaceSite_CanInPlaceActivate,
    InPlaceSite_OnInPlaceActivate,
    InPlaceSite_OnUIActivate,
    InPlaceSite_GetWindowContext,
    InPlaceSite_Scroll,
    InPlaceSite_OnUIDeactivate,
    InPlaceSite_OnInPlaceDeactivate,
    InPlaceSite_DiscardUndoState,
    InPlaceSite_DeactivateAndUndo,
348 349 350 351 352
    InPlaceSite_OnPosRectChange,
    /* OleInPlaceSiteEx */
    InPlaceSite_OnInPlaceActivateEx,
    InPlaceSite_OnInPlaceDeactivateEx,
    InPlaceSite_RequestUIActivate
353 354
};

355 356
static inline DocHost *impl_from_IOleDocumentSite(IOleDocumentSite *iface)
{
357
    return CONTAINING_RECORD(iface, DocHost, IOleDocumentSite_iface);
358
}
359 360 361 362

static HRESULT WINAPI OleDocumentSite_QueryInterface(IOleDocumentSite *iface,
                                                     REFIID riid, void **ppv)
{
363
    DocHost *This = impl_from_IOleDocumentSite(iface);
364
    return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
365 366 367 368
}

static ULONG WINAPI OleDocumentSite_AddRef(IOleDocumentSite *iface)
{
369
    DocHost *This = impl_from_IOleDocumentSite(iface);
370
    return IOleClientSite_AddRef(&This->IOleClientSite_iface);
371 372 373 374
}

static ULONG WINAPI OleDocumentSite_Release(IOleDocumentSite *iface)
{
375
    DocHost *This = impl_from_IOleDocumentSite(iface);
376
    return IOleClientSite_Release(&This->IOleClientSite_iface);
377 378 379 380 381
}

static HRESULT WINAPI OleDocumentSite_ActivateMe(IOleDocumentSite *iface,
                                                 IOleDocumentView *pViewToActivate)
{
382
    DocHost *This = impl_from_IOleDocumentSite(iface);
383 384 385 386 387 388 389 390 391 392
    IOleDocument *oledoc;
    RECT rect;
    HRESULT hres;

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

    hres = IUnknown_QueryInterface(This->document, &IID_IOleDocument, (void**)&oledoc);
    if(FAILED(hres))
        return hres;

393
    hres = IOleDocument_CreateView(oledoc, (IOleInPlaceSite*) &This->IOleInPlaceSiteEx_iface, NULL, 0, &This->view);
394
    IOleDocument_Release(oledoc);
395 396
    if(FAILED(hres))
        return hres;
397

398
    GetClientRect(This->hwnd, &rect);
399 400 401 402 403 404 405 406 407 408 409 410 411 412
    IOleDocumentView_SetRect(This->view, &rect);

    hres = IOleDocumentView_Show(This->view, TRUE);

    return hres;
}

static const IOleDocumentSiteVtbl OleDocumentSiteVtbl = {
    OleDocumentSite_QueryInterface,
    OleDocumentSite_AddRef,
    OleDocumentSite_Release,
    OleDocumentSite_ActivateMe
};

413 414
static inline DocHost *impl_from_IOleControlSite(IOleControlSite *iface)
{
415
    return CONTAINING_RECORD(iface, DocHost, IOleControlSite_iface);
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468
}

static HRESULT WINAPI ControlSite_QueryInterface(IOleControlSite *iface, REFIID riid, void **ppv)
{
    DocHost *This = impl_from_IOleControlSite(iface);
    return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
}

static ULONG WINAPI ControlSite_AddRef(IOleControlSite *iface)
{
    DocHost *This = impl_from_IOleControlSite(iface);
    return IOleClientSite_AddRef(&This->IOleClientSite_iface);
}

static ULONG WINAPI ControlSite_Release(IOleControlSite *iface)
{
    DocHost *This = impl_from_IOleControlSite(iface);
    return IOleClientSite_Release(&This->IOleClientSite_iface);
}

static HRESULT WINAPI ControlSite_OnControlInfoChanged(IOleControlSite *iface)
{
    DocHost *This = impl_from_IOleControlSite(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI ControlSite_LockInPlaceActive(IOleControlSite *iface, BOOL fLock)
{
    DocHost *This = impl_from_IOleControlSite(iface);
    FIXME("(%p)->(%d)\n", This, fLock);
    return E_NOTIMPL;
}

static HRESULT WINAPI ControlSite_GetExtendedControl(IOleControlSite *iface, IDispatch **ppDisp)
{
    DocHost *This = impl_from_IOleControlSite(iface);
    FIXME("(%p)->(%p)\n", This, ppDisp);
    return E_NOTIMPL;
}

static HRESULT WINAPI ControlSite_TransformCoords(IOleControlSite *iface, POINTL *pPtlHimetric,
                                                  POINTF *pPtfContainer, DWORD dwFlags)
{
    DocHost *This = impl_from_IOleControlSite(iface);
    FIXME("(%p)->(%p, %p, %08x)\n", This, pPtlHimetric, pPtfContainer, dwFlags);
    return E_NOTIMPL;
}

static HRESULT WINAPI ControlSite_TranslateAccelerator(IOleControlSite *iface, MSG *pMsg,
                                                       DWORD grfModifiers)
{
    DocHost *This = impl_from_IOleControlSite(iface);
469 470 471 472 473 474 475
    IOleObject *wb_obj;
    IOleClientSite *clientsite;
    IOleControlSite *controlsite;
    HRESULT hr;

    TRACE("(%p)->(%p, %08x)\n", This, pMsg, grfModifiers);

476
    hr = IWebBrowser2_QueryInterface(This->wb, &IID_IOleObject, (void**)&wb_obj);
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
    if(SUCCEEDED(hr)) {
        hr = IOleObject_GetClientSite(wb_obj, &clientsite);
        if(SUCCEEDED(hr)) {
            hr = IOleClientSite_QueryInterface(clientsite, &IID_IOleControlSite, (void**)&controlsite);
            if(SUCCEEDED(hr)) {
                hr = IOleControlSite_TranslateAccelerator(controlsite, pMsg, grfModifiers);
                IOleControlSite_Release(controlsite);
            }
            IOleClientSite_Release(clientsite);
        }
        IOleObject_Release(wb_obj);
    }

    if(FAILED(hr))
        return S_FALSE;
    else
        return hr;
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
}

static HRESULT WINAPI ControlSite_OnFocus(IOleControlSite *iface, BOOL fGotFocus)
{
    DocHost *This = impl_from_IOleControlSite(iface);
    FIXME("(%p)->(%d)\n", This, fGotFocus);
    return E_NOTIMPL;
}

static HRESULT WINAPI ControlSite_ShowPropertyFrame(IOleControlSite *iface)
{
    DocHost *This = impl_from_IOleControlSite(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static IOleControlSiteVtbl OleControlSiteVtbl = {
    ControlSite_QueryInterface,
    ControlSite_AddRef,
    ControlSite_Release,
    ControlSite_OnControlInfoChanged,
    ControlSite_LockInPlaceActive,
    ControlSite_GetExtendedControl,
    ControlSite_TransformCoords,
    ControlSite_TranslateAccelerator,
    ControlSite_OnFocus,
    ControlSite_ShowPropertyFrame
};

523 524
static inline DocHost *impl_from_IDispatch(IDispatch *iface)
{
525
    return CONTAINING_RECORD(iface, DocHost, IDispatch_iface);
526
}
527 528 529

static HRESULT WINAPI ClDispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
{
530
    DocHost *This = impl_from_IDispatch(iface);
531
    return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
532 533 534 535
}

static ULONG WINAPI ClDispatch_AddRef(IDispatch *iface)
{
536
    DocHost *This = impl_from_IDispatch(iface);
537
    return IOleClientSite_AddRef(&This->IOleClientSite_iface);
538 539 540 541
}

static ULONG WINAPI ClDispatch_Release(IDispatch *iface)
{
542
    DocHost *This = impl_from_IDispatch(iface);
543
    return IOleClientSite_Release(&This->IOleClientSite_iface);
544 545 546 547
}

static HRESULT WINAPI ClDispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
{
548
    DocHost *This = impl_from_IDispatch(iface);
549 550 551

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

552 553 554 555
    return E_NOTIMPL;
}

static HRESULT WINAPI ClDispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid,
556
                                             ITypeInfo **ppTInfo)
557
{
558
    DocHost *This = impl_from_IDispatch(iface);
559

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

562 563 564 565
    return E_NOTIMPL;
}

static HRESULT WINAPI ClDispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
566
                                               UINT cNames, LCID lcid, DISPID *rgDispId)
567
{
568
    DocHost *This = impl_from_IDispatch(iface);
569

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

573 574 575
    return E_NOTIMPL;
}

576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
static const char *debugstr_dispid(DISPID dispid)
{
    static char buf[16];

#define CASE_DISPID(did) case did: return #did
    switch(dispid) {
        CASE_DISPID(DISPID_AMBIENT_USERMODE);
        CASE_DISPID(DISPID_AMBIENT_DLCONTROL);
        CASE_DISPID(DISPID_AMBIENT_USERAGENT);
        CASE_DISPID(DISPID_AMBIENT_PALETTE);
        CASE_DISPID(DISPID_AMBIENT_OFFLINEIFNOTCONNECTED);
        CASE_DISPID(DISPID_AMBIENT_SILENT);
    }
#undef CASE_DISPID

    sprintf(buf, "%d", dispid);
    return buf;
}

595
static HRESULT WINAPI ClDispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid,
596 597
                                        LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
                                        VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
598
{
599
    DocHost *This = impl_from_IDispatch(iface);
600 601 602 603 604

    TRACE("(%p)->(%s %s %d %04x %p %p %p %p)\n", This, debugstr_dispid(dispIdMember),
          debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);

    switch(dispIdMember) {
605 606 607 608 609 610 611 612
    case DISPID_AMBIENT_USERMODE:
    case DISPID_AMBIENT_DLCONTROL:
    case DISPID_AMBIENT_USERAGENT:
    case DISPID_AMBIENT_PALETTE:
        if(!This->client_disp)
            return E_FAIL;
        return IDispatch_Invoke(This->client_disp, dispIdMember, riid, lcid, wFlags,
                                pDispParams, pVarResult, pExcepInfo, puArgErr);
613 614 615 616 617 618 619 620 621 622 623
    case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
        V_VT(pVarResult) = VT_BOOL;
        V_BOOL(pVarResult) = This->offline;
        return S_OK;
    case DISPID_AMBIENT_SILENT:
        V_VT(pVarResult) = VT_BOOL;
        V_BOOL(pVarResult) = This->offline;
        return S_OK;
    }

    FIXME("unhandled dispid %d\n", dispIdMember);
624 625 626 627 628 629 630 631 632 633 634 635 636
    return E_NOTIMPL;
}

static const IDispatchVtbl DispatchVtbl = {
    ClDispatch_QueryInterface,
    ClDispatch_AddRef,
    ClDispatch_Release,
    ClDispatch_GetTypeInfoCount,
    ClDispatch_GetTypeInfo,
    ClDispatch_GetIDsOfNames,
    ClDispatch_Invoke
};

637 638
static inline DocHost *impl_from_IServiceProvider(IServiceProvider *iface)
{
639
    return CONTAINING_RECORD(iface, DocHost, IServiceProvider_iface);
640
}
641 642 643 644

static HRESULT WINAPI ClServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid,
                                                       void **ppv)
{
645
    DocHost *This = impl_from_IServiceProvider(iface);
646
    return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
647 648 649 650
}

static ULONG WINAPI ClServiceProvider_AddRef(IServiceProvider *iface)
{
651
    DocHost *This = impl_from_IServiceProvider(iface);
652
    return IOleClientSite_AddRef(&This->IOleClientSite_iface);
653 654 655 656
}

static ULONG WINAPI ClServiceProvider_Release(IServiceProvider *iface)
{
657
    DocHost *This = impl_from_IServiceProvider(iface);
658
    return IOleClientSite_Release(&This->IOleClientSite_iface);
659 660 661 662 663
}

static HRESULT WINAPI ClServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
                                                     REFIID riid, void **ppv)
{
664
    DocHost *This = impl_from_IServiceProvider(iface);
665 666 667

    if(IsEqualGUID(&IID_IHlinkFrame, guidService)) {
        TRACE("(%p)->(IID_IHlinkFrame %s %p)\n", This, debugstr_guid(riid), ppv);
668
        return IWebBrowser2_QueryInterface(This->wb, riid, ppv);
669 670
    }

671 672 673 674 675
    if(IsEqualGUID(&IID_ITargetFrame, guidService)) {
        TRACE("(%p)->(IID_ITargetFrame %s %p)\n", This, debugstr_guid(riid), ppv);
        return IWebBrowser2_QueryInterface(This->wb, riid, ppv);
    }

676 677
    if(IsEqualGUID(&IID_IWebBrowserApp, guidService)) {
        TRACE("IWebBrowserApp service\n");
678
        return IWebBrowser2_QueryInterface(This->wb, riid, ppv);
679 680
    }

681 682 683
    if(IsEqualGUID(&IID_IShellBrowser, guidService)) {
        TRACE("(%p)->(IID_IShellBrowser %s %p)\n", This, debugstr_guid(riid), ppv);

684 685
        if(!This->browser_service) {
            HRESULT hres;
686

687 688 689 690 691 692
            hres = create_browser_service(This, &This->browser_service);
            if(FAILED(hres))
                return hres;
        }

        return IShellBrowser_QueryInterface(&This->browser_service->IShellBrowser_iface, riid, ppv);
693 694
    }

695 696 697 698 699
    if(IsEqualGUID(&SID_SNewWindowManager, guidService)) {
        TRACE("SID_SNewWindowManager service\n");
        return INewWindowManager_QueryInterface(&This->nwm.INewWindowManager_iface, riid, ppv);
    }

700 701 702 703 704 705 706 707 708 709 710 711
    FIXME("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);

    return E_NOINTERFACE;
}

static const IServiceProviderVtbl ServiceProviderVtbl = {
    ClServiceProvider_QueryInterface,
    ClServiceProvider_AddRef,
    ClServiceProvider_Release,
    ClServiceProvider_QueryService
};

712
void DocHost_ClientSite_Init(DocHost *This)
713
{
714 715 716 717 718 719
    This->IOleClientSite_iface.lpVtbl    = &OleClientSiteVtbl;
    This->IOleInPlaceSiteEx_iface.lpVtbl = &OleInPlaceSiteExVtbl;
    This->IOleDocumentSite_iface.lpVtbl  = &OleDocumentSiteVtbl;
    This->IOleControlSite_iface.lpVtbl   = &OleControlSiteVtbl;
    This->IDispatch_iface.lpVtbl         = &DispatchVtbl;
    This->IServiceProvider_iface.lpVtbl  = &ServiceProviderVtbl;
720 721
}

722
void DocHost_ClientSite_Release(DocHost *This)
723
{
724 725
    if(This->browser_service)
        detach_browser_service(This->browser_service);
726 727
    if(This->view)
        IOleDocumentView_Release(This->view);
728
}