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