wineps: Add a DC function structure and export it.
[wine] / dlls / shdocvw / client.c
1 /*
2  * Copyright 2005 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * 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 #include <stdio.h>
20
21 #include "wine/debug.h"
22 #include "shdocvw.h"
23 #include "mshtmdid.h"
24 #include "idispids.h"
25
26 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
27
28 static inline DocHost *impl_from_IOleClientSite(IOleClientSite *iface)
29 {
30     return CONTAINING_RECORD(iface, DocHost, IOleClientSite_iface);
31 }
32
33 static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
34 {
35     DocHost *This = impl_from_IOleClientSite(iface);
36
37     if(IsEqualGUID(&IID_IUnknown, riid)) {
38         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
39         *ppv = &This->IOleClientSite_iface;
40     }else if(IsEqualGUID(&IID_IOleClientSite, riid)) {
41         TRACE("(%p)->(IID_IOleClientSite %p)\n", This, ppv);
42         *ppv = &This->IOleClientSite_iface;
43     }else if(IsEqualGUID(&IID_IOleWindow, riid)) {
44         TRACE("(%p)->(IID_IOleWindow %p)\n", This, ppv);
45         *ppv = &This->IOleInPlaceSiteEx_iface;
46     }else if(IsEqualGUID(&IID_IOleInPlaceSite, riid)) {
47         TRACE("(%p)->(IID_IOleInPlaceSite %p)\n", This, ppv);
48         *ppv = &This->IOleInPlaceSiteEx_iface;
49     }else if(IsEqualGUID(&IID_IOleInPlaceSiteEx, riid)) {
50         TRACE("(%p)->(IID_IOleInPlaceSiteEx %p)\n", This, ppv);
51         *ppv = &This->IOleInPlaceSiteEx_iface;
52     }else if(IsEqualGUID(&IID_IDocHostUIHandler, riid)) {
53         TRACE("(%p)->(IID_IDocHostUIHandler %p)\n", This, ppv);
54         *ppv = &This->IDocHostUIHandler2_iface;
55     }else if(IsEqualGUID(&IID_IDocHostUIHandler2, riid)) {
56         TRACE("(%p)->(IID_IDocHostUIHandler2 %p)\n", This, ppv);
57         *ppv = &This->IDocHostUIHandler2_iface;
58     }else if(IsEqualGUID(&IID_IOleDocumentSite, riid)) {
59         TRACE("(%p)->(IID_IOleDocumentSite %p)\n", This, ppv);
60         *ppv = &This->IOleDocumentSite_iface;
61     }else if(IsEqualGUID(&IID_IOleControlSite, riid)) {
62         TRACE("(%p)->(IID_IOleControlSite %p)\n", This, ppv);
63         *ppv = &This->IOleControlSite_iface;
64     }else if(IsEqualGUID(&IID_IOleCommandTarget, riid)) {
65         TRACE("(%p)->(IID_IOleCommandTarget %p)\n", This, ppv);
66         *ppv = &This->IOleCommandTarget_iface;
67     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
68         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
69         *ppv = &This->IDispatch_iface;
70     }else if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
71         TRACE("(%p)->(IID_IPropertyNotifySink %p)\n", This, ppv);
72         *ppv = &This->IPropertyNotifySink_iface;
73     }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
74         TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
75         *ppv = &This->IServiceProvider_iface;
76     }else {
77         *ppv = NULL;
78         WARN("Unsupported interface %s\n", debugstr_guid(riid));
79         return E_NOINTERFACE;
80     }
81
82     IOleClientSite_AddRef((IUnknown*)*ppv);
83     return S_OK;
84 }
85
86 static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface)
87 {
88     DocHost *This = impl_from_IOleClientSite(iface);
89     return This->container_vtbl->addref(This);
90 }
91
92 static ULONG WINAPI ClientSite_Release(IOleClientSite *iface)
93 {
94     DocHost *This = impl_from_IOleClientSite(iface);
95     return This->container_vtbl->release(This);
96 }
97
98 static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface)
99 {
100     DocHost *This = impl_from_IOleClientSite(iface);
101     FIXME("(%p)\n", This);
102     return E_NOTIMPL;
103 }
104
105 static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign,
106                                             DWORD dwWhichMoniker, IMoniker **ppmk)
107 {
108     DocHost *This = impl_from_IOleClientSite(iface);
109     FIXME("(%p)->(%d %d %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
110     return E_NOTIMPL;
111 }
112
113 static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
114 {
115     DocHost *This = impl_from_IOleClientSite(iface);
116     FIXME("(%p)->(%p)\n", This, ppContainer);
117     return E_NOTIMPL;
118 }
119
120 static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface)
121 {
122     DocHost *This = impl_from_IOleClientSite(iface);
123     FIXME("(%p)\n", This);
124     return E_NOTIMPL;
125 }
126
127 static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
128 {
129     DocHost *This = impl_from_IOleClientSite(iface);
130     FIXME("(%p)->(%x)\n", This, fShow);
131     return E_NOTIMPL;
132 }
133
134 static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface)
135 {
136     DocHost *This = impl_from_IOleClientSite(iface);
137     FIXME("(%p)\n", This);
138     return E_NOTIMPL;
139 }
140
141 static const IOleClientSiteVtbl OleClientSiteVtbl = {
142     ClientSite_QueryInterface,
143     ClientSite_AddRef,
144     ClientSite_Release,
145     ClientSite_SaveObject,
146     ClientSite_GetMoniker,
147     ClientSite_GetContainer,
148     ClientSite_ShowObject,
149     ClientSite_OnShowWindow,
150     ClientSite_RequestNewObjectLayout
151 };
152
153 static inline DocHost *impl_from_IOleInPlaceSiteEx(IOleInPlaceSiteEx *iface)
154 {
155     return CONTAINING_RECORD(iface, DocHost, IOleInPlaceSiteEx_iface);
156 }
157
158 static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSiteEx *iface, REFIID riid, void **ppv)
159 {
160     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
161     return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
162 }
163
164 static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSiteEx *iface)
165 {
166     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
167     return IOleClientSite_AddRef(&This->IOleClientSite_iface);
168 }
169
170 static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSiteEx *iface)
171 {
172     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
173     return IOleClientSite_Release(&This->IOleClientSite_iface);
174 }
175
176 static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSiteEx *iface, HWND *phwnd)
177 {
178     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
179
180     TRACE("(%p)->(%p)\n", This, phwnd);
181
182     *phwnd = This->hwnd;
183     return S_OK;
184 }
185
186 static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSiteEx *iface, BOOL fEnterMode)
187 {
188     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
189     FIXME("(%p)->(%x)\n", This, fEnterMode);
190     return E_NOTIMPL;
191 }
192
193 static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSiteEx *iface)
194 {
195     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
196
197     TRACE("(%p)\n", This);
198
199     /* Nothing to do here */
200     return S_OK;
201 }
202
203 static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSiteEx *iface)
204 {
205     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
206
207     TRACE("(%p)\n", This);
208
209     /* Nothing to do here */
210     return S_OK;
211 }
212
213 static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSiteEx *iface)
214 {
215     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
216     FIXME("(%p)\n", This);
217     return E_NOTIMPL;
218 }
219
220 static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSiteEx *iface,
221         IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
222         LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
223 {
224     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
225
226     TRACE("(%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect,
227           lprcClipRect, lpFrameInfo);
228
229     IOleInPlaceFrame_AddRef(&This->IOleInPlaceFrame_iface);
230     *ppFrame = &This->IOleInPlaceFrame_iface;
231     *ppDoc = NULL;
232
233     GetClientRect(This->hwnd, lprcPosRect);
234     *lprcClipRect = *lprcPosRect;
235
236     lpFrameInfo->fMDIApp = FALSE;
237     lpFrameInfo->hwndFrame = This->frame_hwnd;
238     lpFrameInfo->haccel = NULL;
239     lpFrameInfo->cAccelEntries = 0; /* FIXME: should be 5 */
240
241     return S_OK;
242 }
243
244 static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSiteEx *iface, SIZE scrollExtent)
245 {
246     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
247     FIXME("(%p)->({%d %d})\n", This, scrollExtent.cx, scrollExtent.cy);
248     return E_NOTIMPL;
249 }
250
251 static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSiteEx *iface, BOOL fUndoable)
252 {
253     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
254     FIXME("(%p)->(%x)\n", This, fUndoable);
255     return E_NOTIMPL;
256 }
257
258 static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSiteEx *iface)
259 {
260     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
261
262     TRACE("(%p)\n", This);
263
264     /* Nothing to do here */
265     return S_OK;
266 }
267
268 static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSiteEx *iface)
269 {
270     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
271     FIXME("(%p)\n", This);
272     return E_NOTIMPL;
273 }
274
275 static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSiteEx *iface)
276 {
277     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
278     FIXME("(%p)\n", This);
279     return E_NOTIMPL;
280 }
281
282 static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSiteEx *iface,
283                                                   LPCRECT lprcPosRect)
284 {
285     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
286     FIXME("(%p)->(%p)\n", This, lprcPosRect);
287     return E_NOTIMPL;
288 }
289
290 static HRESULT WINAPI InPlaceSite_OnInPlaceActivateEx(IOleInPlaceSiteEx *iface,
291                                                      BOOL *pfNoRedraw, DWORD dwFlags)
292 {
293     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
294
295     TRACE("(%p)->(%p, %x)\n", This, pfNoRedraw, dwFlags);
296
297     /* FIXME: Avoid redraw, when possible */
298     pfNoRedraw = FALSE;
299
300     if (dwFlags) {
301         FIXME("dwFlags not supported (%x)\n", dwFlags);
302     }
303
304     /* Nothing to do here */
305     return S_OK;
306 }
307
308 static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivateEx(IOleInPlaceSiteEx *iface, BOOL fNoRedraw)
309 {
310     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
311
312     TRACE("(%p)->(%x)\n", This, fNoRedraw);
313
314     if (fNoRedraw) {
315         FIXME("fNoRedraw (%x) ignored\n", fNoRedraw);
316     }
317
318     /* Nothing to do here */
319     return S_OK;
320 }
321
322 static HRESULT WINAPI InPlaceSite_RequestUIActivate(IOleInPlaceSiteEx *iface)
323 {
324     DocHost *This = impl_from_IOleInPlaceSiteEx(iface);
325     TRACE("(%p)\n", This);
326
327     /* OnUIActivate is always possible */
328     return S_OK;
329 }
330
331 static const IOleInPlaceSiteExVtbl OleInPlaceSiteExVtbl = {
332     InPlaceSite_QueryInterface,
333     InPlaceSite_AddRef,
334     InPlaceSite_Release,
335     InPlaceSite_GetWindow,
336     InPlaceSite_ContextSensitiveHelp,
337     InPlaceSite_CanInPlaceActivate,
338     InPlaceSite_OnInPlaceActivate,
339     InPlaceSite_OnUIActivate,
340     InPlaceSite_GetWindowContext,
341     InPlaceSite_Scroll,
342     InPlaceSite_OnUIDeactivate,
343     InPlaceSite_OnInPlaceDeactivate,
344     InPlaceSite_DiscardUndoState,
345     InPlaceSite_DeactivateAndUndo,
346     InPlaceSite_OnPosRectChange,
347     /* OleInPlaceSiteEx */
348     InPlaceSite_OnInPlaceActivateEx,
349     InPlaceSite_OnInPlaceDeactivateEx,
350     InPlaceSite_RequestUIActivate
351 };
352
353 static inline DocHost *impl_from_IOleDocumentSite(IOleDocumentSite *iface)
354 {
355     return CONTAINING_RECORD(iface, DocHost, IOleDocumentSite_iface);
356 }
357
358 static HRESULT WINAPI OleDocumentSite_QueryInterface(IOleDocumentSite *iface,
359                                                      REFIID riid, void **ppv)
360 {
361     DocHost *This = impl_from_IOleDocumentSite(iface);
362     return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
363 }
364
365 static ULONG WINAPI OleDocumentSite_AddRef(IOleDocumentSite *iface)
366 {
367     DocHost *This = impl_from_IOleDocumentSite(iface);
368     return IOleClientSite_AddRef(&This->IOleClientSite_iface);
369 }
370
371 static ULONG WINAPI OleDocumentSite_Release(IOleDocumentSite *iface)
372 {
373     DocHost *This = impl_from_IOleDocumentSite(iface);
374     return IOleClientSite_Release(&This->IOleClientSite_iface);
375 }
376
377 static HRESULT WINAPI OleDocumentSite_ActivateMe(IOleDocumentSite *iface,
378                                                  IOleDocumentView *pViewToActivate)
379 {
380     DocHost *This = impl_from_IOleDocumentSite(iface);
381     IOleDocument *oledoc;
382     RECT rect;
383     HRESULT hres;
384
385     TRACE("(%p)->(%p)\n", This, pViewToActivate);
386
387     hres = IUnknown_QueryInterface(This->document, &IID_IOleDocument, (void**)&oledoc);
388     if(FAILED(hres))
389         return hres;
390
391     IOleDocument_CreateView(oledoc, (IOleInPlaceSite*) &This->IOleInPlaceSiteEx_iface, NULL, 0, &This->view);
392     IOleDocument_Release(oledoc);
393
394     GetClientRect(This->hwnd, &rect);
395     IOleDocumentView_SetRect(This->view, &rect);
396
397     hres = IOleDocumentView_Show(This->view, TRUE);
398
399     return hres;
400 }
401
402 static const IOleDocumentSiteVtbl OleDocumentSiteVtbl = {
403     OleDocumentSite_QueryInterface,
404     OleDocumentSite_AddRef,
405     OleDocumentSite_Release,
406     OleDocumentSite_ActivateMe
407 };
408
409 static inline DocHost *impl_from_IOleControlSite(IOleControlSite *iface)
410 {
411     return CONTAINING_RECORD(iface, DocHost, IOleControlSite_iface);
412 }
413
414 static HRESULT WINAPI ControlSite_QueryInterface(IOleControlSite *iface, REFIID riid, void **ppv)
415 {
416     DocHost *This = impl_from_IOleControlSite(iface);
417     return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
418 }
419
420 static ULONG WINAPI ControlSite_AddRef(IOleControlSite *iface)
421 {
422     DocHost *This = impl_from_IOleControlSite(iface);
423     return IOleClientSite_AddRef(&This->IOleClientSite_iface);
424 }
425
426 static ULONG WINAPI ControlSite_Release(IOleControlSite *iface)
427 {
428     DocHost *This = impl_from_IOleControlSite(iface);
429     return IOleClientSite_Release(&This->IOleClientSite_iface);
430 }
431
432 static HRESULT WINAPI ControlSite_OnControlInfoChanged(IOleControlSite *iface)
433 {
434     DocHost *This = impl_from_IOleControlSite(iface);
435     FIXME("(%p)\n", This);
436     return E_NOTIMPL;
437 }
438
439 static HRESULT WINAPI ControlSite_LockInPlaceActive(IOleControlSite *iface, BOOL fLock)
440 {
441     DocHost *This = impl_from_IOleControlSite(iface);
442     FIXME("(%p)->(%d)\n", This, fLock);
443     return E_NOTIMPL;
444 }
445
446 static HRESULT WINAPI ControlSite_GetExtendedControl(IOleControlSite *iface, IDispatch **ppDisp)
447 {
448     DocHost *This = impl_from_IOleControlSite(iface);
449     FIXME("(%p)->(%p)\n", This, ppDisp);
450     return E_NOTIMPL;
451 }
452
453 static HRESULT WINAPI ControlSite_TransformCoords(IOleControlSite *iface, POINTL *pPtlHimetric,
454                                                   POINTF *pPtfContainer, DWORD dwFlags)
455 {
456     DocHost *This = impl_from_IOleControlSite(iface);
457     FIXME("(%p)->(%p, %p, %08x)\n", This, pPtlHimetric, pPtfContainer, dwFlags);
458     return E_NOTIMPL;
459 }
460
461 static HRESULT WINAPI ControlSite_TranslateAccelerator(IOleControlSite *iface, MSG *pMsg,
462                                                        DWORD grfModifiers)
463 {
464     DocHost *This = impl_from_IOleControlSite(iface);
465     IOleObject *wb_obj;
466     IOleClientSite *clientsite;
467     IOleControlSite *controlsite;
468     HRESULT hr;
469
470     TRACE("(%p)->(%p, %08x)\n", This, pMsg, grfModifiers);
471
472     hr = IDispatch_QueryInterface(This->disp, &IID_IOleObject, (void**)&wb_obj);
473     if(SUCCEEDED(hr)) {
474         hr = IOleObject_GetClientSite(wb_obj, &clientsite);
475         if(SUCCEEDED(hr)) {
476             hr = IOleClientSite_QueryInterface(clientsite, &IID_IOleControlSite, (void**)&controlsite);
477             if(SUCCEEDED(hr)) {
478                 hr = IOleControlSite_TranslateAccelerator(controlsite, pMsg, grfModifiers);
479                 IOleControlSite_Release(controlsite);
480             }
481             IOleClientSite_Release(clientsite);
482         }
483         IOleObject_Release(wb_obj);
484     }
485
486     if(FAILED(hr))
487         return S_FALSE;
488     else
489         return hr;
490 }
491
492 static HRESULT WINAPI ControlSite_OnFocus(IOleControlSite *iface, BOOL fGotFocus)
493 {
494     DocHost *This = impl_from_IOleControlSite(iface);
495     FIXME("(%p)->(%d)\n", This, fGotFocus);
496     return E_NOTIMPL;
497 }
498
499 static HRESULT WINAPI ControlSite_ShowPropertyFrame(IOleControlSite *iface)
500 {
501     DocHost *This = impl_from_IOleControlSite(iface);
502     FIXME("(%p)\n", This);
503     return E_NOTIMPL;
504 }
505
506 static IOleControlSiteVtbl OleControlSiteVtbl = {
507     ControlSite_QueryInterface,
508     ControlSite_AddRef,
509     ControlSite_Release,
510     ControlSite_OnControlInfoChanged,
511     ControlSite_LockInPlaceActive,
512     ControlSite_GetExtendedControl,
513     ControlSite_TransformCoords,
514     ControlSite_TranslateAccelerator,
515     ControlSite_OnFocus,
516     ControlSite_ShowPropertyFrame
517 };
518
519 static inline DocHost *impl_from_IDispatch(IDispatch *iface)
520 {
521     return CONTAINING_RECORD(iface, DocHost, IDispatch_iface);
522 }
523
524 static HRESULT WINAPI ClDispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
525 {
526     DocHost *This = impl_from_IDispatch(iface);
527     return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
528 }
529
530 static ULONG WINAPI ClDispatch_AddRef(IDispatch *iface)
531 {
532     DocHost *This = impl_from_IDispatch(iface);
533     return IOleClientSite_AddRef(&This->IOleClientSite_iface);
534 }
535
536 static ULONG WINAPI ClDispatch_Release(IDispatch *iface)
537 {
538     DocHost *This = impl_from_IDispatch(iface);
539     return IOleClientSite_Release(&This->IOleClientSite_iface);
540 }
541
542 static HRESULT WINAPI ClDispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
543 {
544     DocHost *This = impl_from_IDispatch(iface);
545
546     TRACE("(%p)->(%p)\n", This, pctinfo);
547
548     return E_NOTIMPL;
549 }
550
551 static HRESULT WINAPI ClDispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid,
552                                              ITypeInfo **ppTInfo)
553 {
554     DocHost *This = impl_from_IDispatch(iface);
555
556     TRACE("(%p)->(%u %d %p)\n", This, iTInfo, lcid, ppTInfo);
557
558     return E_NOTIMPL;
559 }
560
561 static HRESULT WINAPI ClDispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
562                                                UINT cNames, LCID lcid, DISPID *rgDispId)
563 {
564     DocHost *This = impl_from_IDispatch(iface);
565
566     TRACE("(%p)->(%s %p %u %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
567           lcid, rgDispId);
568
569     return E_NOTIMPL;
570 }
571
572 static const char *debugstr_dispid(DISPID dispid)
573 {
574     static char buf[16];
575
576 #define CASE_DISPID(did) case did: return #did
577     switch(dispid) {
578         CASE_DISPID(DISPID_AMBIENT_USERMODE);
579         CASE_DISPID(DISPID_AMBIENT_DLCONTROL);
580         CASE_DISPID(DISPID_AMBIENT_USERAGENT);
581         CASE_DISPID(DISPID_AMBIENT_PALETTE);
582         CASE_DISPID(DISPID_AMBIENT_OFFLINEIFNOTCONNECTED);
583         CASE_DISPID(DISPID_AMBIENT_SILENT);
584     }
585 #undef CASE_DISPID
586
587     sprintf(buf, "%d", dispid);
588     return buf;
589 }
590
591 static HRESULT WINAPI ClDispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid,
592                                         LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
593                                         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
594 {
595     DocHost *This = impl_from_IDispatch(iface);
596
597     TRACE("(%p)->(%s %s %d %04x %p %p %p %p)\n", This, debugstr_dispid(dispIdMember),
598           debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
599
600     switch(dispIdMember) {
601     case DISPID_AMBIENT_USERMODE:
602     case DISPID_AMBIENT_DLCONTROL:
603     case DISPID_AMBIENT_USERAGENT:
604     case DISPID_AMBIENT_PALETTE:
605         if(!This->client_disp)
606             return E_FAIL;
607         return IDispatch_Invoke(This->client_disp, dispIdMember, riid, lcid, wFlags,
608                                 pDispParams, pVarResult, pExcepInfo, puArgErr);
609     case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
610         V_VT(pVarResult) = VT_BOOL;
611         V_BOOL(pVarResult) = This->offline;
612         return S_OK;
613     case DISPID_AMBIENT_SILENT:
614         V_VT(pVarResult) = VT_BOOL;
615         V_BOOL(pVarResult) = This->offline;
616         return S_OK;
617     }
618
619     FIXME("unhandled dispid %d\n", dispIdMember);
620     return E_NOTIMPL;
621 }
622
623 static const IDispatchVtbl DispatchVtbl = {
624     ClDispatch_QueryInterface,
625     ClDispatch_AddRef,
626     ClDispatch_Release,
627     ClDispatch_GetTypeInfoCount,
628     ClDispatch_GetTypeInfo,
629     ClDispatch_GetIDsOfNames,
630     ClDispatch_Invoke
631 };
632
633 static inline DocHost *impl_from_IServiceProvider(IServiceProvider *iface)
634 {
635     return CONTAINING_RECORD(iface, DocHost, IServiceProvider_iface);
636 }
637
638 static HRESULT WINAPI ClServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid,
639                                                        void **ppv)
640 {
641     DocHost *This = impl_from_IServiceProvider(iface);
642     return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
643 }
644
645 static ULONG WINAPI ClServiceProvider_AddRef(IServiceProvider *iface)
646 {
647     DocHost *This = impl_from_IServiceProvider(iface);
648     return IOleClientSite_AddRef(&This->IOleClientSite_iface);
649 }
650
651 static ULONG WINAPI ClServiceProvider_Release(IServiceProvider *iface)
652 {
653     DocHost *This = impl_from_IServiceProvider(iface);
654     return IOleClientSite_Release(&This->IOleClientSite_iface);
655 }
656
657 static HRESULT WINAPI ClServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
658                                                      REFIID riid, void **ppv)
659 {
660     DocHost *This = impl_from_IServiceProvider(iface);
661
662     if(IsEqualGUID(&IID_IHlinkFrame, guidService)) {
663         TRACE("(%p)->(IID_IHlinkFrame %s %p)\n", This, debugstr_guid(riid), ppv);
664         return IDispatch_QueryInterface(This->disp, riid, ppv);
665     }
666
667     if(IsEqualGUID(&IID_IWebBrowserApp, guidService)) {
668         TRACE("IWebBrowserApp service\n");
669         return IDispatch_QueryInterface(This->disp, riid, ppv);
670     }
671
672     if(IsEqualGUID(&IID_IShellBrowser, guidService)) {
673         IShellBrowser *sb;
674         HRESULT hres;
675
676         TRACE("(%p)->(IID_IShellBrowser %s %p)\n", This, debugstr_guid(riid), ppv);
677
678         hres = ShellBrowser_Create(&sb);
679         if(FAILED(hres))
680             return hres;
681
682         hres = IShellBrowser_QueryInterface(sb, riid, ppv);
683         IShellBrowser_Release(sb);
684         return hres;
685     }
686
687     FIXME("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
688
689     return E_NOINTERFACE;
690 }
691
692 static const IServiceProviderVtbl ServiceProviderVtbl = {
693     ClServiceProvider_QueryInterface,
694     ClServiceProvider_AddRef,
695     ClServiceProvider_Release,
696     ClServiceProvider_QueryService
697 };
698
699 void DocHost_ClientSite_Init(DocHost *This)
700 {
701     This->IOleClientSite_iface.lpVtbl    = &OleClientSiteVtbl;
702     This->IOleInPlaceSiteEx_iface.lpVtbl = &OleInPlaceSiteExVtbl;
703     This->IOleDocumentSite_iface.lpVtbl  = &OleDocumentSiteVtbl;
704     This->IOleControlSite_iface.lpVtbl   = &OleControlSiteVtbl;
705     This->IDispatch_iface.lpVtbl         = &DispatchVtbl;
706     This->IServiceProvider_iface.lpVtbl  = &ServiceProviderVtbl;
707 }
708
709 void DocHost_ClientSite_Release(DocHost *This)
710 {
711     if(This->view)
712         IOleDocumentView_Release(This->view);
713 }