shdocvw: Added SetExtent and GetExtent implementation.
[wine] / dlls / shdocvw / oleobject.c
1 /*
2  * Implementation of IOleObject interfaces for WebBrowser control
3  *
4  * - IOleObject
5  * - IOleInPlaceObject
6  * - IOleControl
7  *
8  * Copyright 2001 John R. Sheets (for CodeWeavers)
9  * Copyright 2005 Jacek Caban
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25
26 #include <string.h>
27 #include "wine/debug.h"
28 #include "shdocvw.h"
29 #include "htiframe.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
32
33 static ATOM shell_embedding_atom = 0;
34
35 static LRESULT resize_window(WebBrowser *This, LONG width, LONG height)
36 {
37     if(This->doc_host.hwnd)
38         SetWindowPos(This->doc_host.hwnd, NULL, 0, 0, width, height,
39                      SWP_NOZORDER | SWP_NOACTIVATE);
40
41     return 0;
42 }
43
44 static LRESULT WINAPI shell_embedding_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
45 {
46     WebBrowser *This;
47
48     static const WCHAR wszTHIS[] = {'T','H','I','S',0};
49
50     if(msg == WM_CREATE) {
51         This = *(WebBrowser**)lParam;
52         SetPropW(hwnd, wszTHIS, This);
53     }else {
54         This = GetPropW(hwnd, wszTHIS);
55     }
56
57     switch(msg) {
58     case WM_SIZE:
59         return resize_window(This, LOWORD(lParam), HIWORD(lParam));
60     }
61
62     return DefWindowProcW(hwnd, msg, wParam, lParam);
63 }
64
65 static void create_shell_embedding_hwnd(WebBrowser *This)
66 {
67     IOleInPlaceSite *inplace;
68     HWND parent = NULL;
69     HRESULT hres;
70
71     static const WCHAR wszShellEmbedding[] =
72         {'S','h','e','l','l',' ','E','m','b','e','d','d','i','n','g',0};
73
74     if(!shell_embedding_atom) {
75         static WNDCLASSEXW wndclass = {
76             sizeof(wndclass),
77             CS_DBLCLKS,
78             shell_embedding_proc,
79             0, 0 /* native uses 8 */, NULL, NULL, NULL,
80             (HBRUSH)COLOR_WINDOWFRAME, NULL,
81             wszShellEmbedding,
82             NULL
83         };
84         wndclass.hInstance = shdocvw_hinstance;
85
86         RegisterClassExW(&wndclass);
87     }
88
89     hres = IOleClientSite_QueryInterface(This->client, &IID_IOleInPlaceSite, (void**)&inplace);
90     if(SUCCEEDED(hres)) {
91         IOleInPlaceSite_GetWindow(inplace, &parent);
92         IOleInPlaceSite_Release(inplace);
93     }
94
95     This->doc_host.frame_hwnd = This->shell_embedding_hwnd = CreateWindowExW(
96             WS_EX_WINDOWEDGE,
97             wszShellEmbedding, wszShellEmbedding,
98             WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_TABSTOP,
99             0, 0, 0, 0, parent,
100             NULL, shdocvw_hinstance, This);
101 }
102
103 static HRESULT activate_inplace(WebBrowser *This, IOleClientSite *active_site, HWND parent_hwnd)
104 {
105     HRESULT hres;
106
107     if(This->inplace)
108         return S_OK;
109
110     if(!active_site)
111         return E_INVALIDARG;
112
113     hres = IOleClientSite_QueryInterface(active_site, &IID_IOleInPlaceSite,
114                                          (void**)&This->inplace);
115     if(FAILED(hres)) {
116         WARN("Could not get IOleInPlaceSite\n");
117         return hres;
118     }
119
120     hres = IOleInPlaceSite_CanInPlaceActivate(This->inplace);
121     if(hres != S_OK) {
122         WARN("CanInPlaceActivate returned: %08lx\n", hres);
123         IOleInPlaceSite_Release(This->inplace);
124         return E_FAIL;
125     }
126
127     hres = IOleInPlaceSite_GetWindow(This->inplace, &This->iphwnd);
128     if(FAILED(hres))
129         This->iphwnd = parent_hwnd;
130
131     IOleInPlaceSite_OnInPlaceActivate(This->inplace);
132
133     IOleInPlaceSite_GetWindowContext(This->inplace, &This->frame, &This->uiwindow,
134                                      &This->pos_rect, &This->clip_rect,
135                                      &This->frameinfo);
136
137     SetWindowPos(This->shell_embedding_hwnd, NULL,
138                  This->pos_rect.left, This->pos_rect.top,
139                  This->pos_rect.right-This->pos_rect.left,
140                  This->pos_rect.bottom-This->pos_rect.top,
141                  SWP_NOZORDER | SWP_SHOWWINDOW);
142
143     if(This->client) {
144         IOleClientSite_ShowObject(This->client);
145         IOleClientSite_GetContainer(This->client, &This->container);
146     }
147
148     if(This->frame)
149         IOleInPlaceFrame_GetWindow(This->frame, &This->frame_hwnd);
150
151     return S_OK;
152 }
153
154 static HRESULT activate_ui(WebBrowser *This, IOleClientSite *active_site, HWND parent_hwnd)
155 {
156     HRESULT hres;
157
158     static const WCHAR wszitem[] = {'i','t','e','m',0};
159
160     if(This->inplace)
161         return S_OK;
162
163     hres = activate_inplace(This, active_site, parent_hwnd);
164     if(FAILED(hres))
165         return hres;
166
167     IOleInPlaceSite_OnUIActivate(This->inplace);
168
169     if(This->frame)
170         IOleInPlaceFrame_SetActiveObject(This->frame, ACTIVEOBJ(This), wszitem);
171     if(This->uiwindow)
172         IOleInPlaceUIWindow_SetActiveObject(This->uiwindow, ACTIVEOBJ(This), wszitem);
173
174     if(This->frame)
175         IOleInPlaceFrame_SetMenu(This->frame, NULL, NULL, This->shell_embedding_hwnd);
176
177     SetFocus(This->shell_embedding_hwnd);
178
179     return S_OK;
180 }
181
182 /**********************************************************************
183  * Implement the IOleObject interface for the WebBrowser control
184  */
185
186 #define OLEOBJ_THIS(iface) DEFINE_THIS(WebBrowser, OleObject, iface)
187
188 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
189 {
190     WebBrowser *This = OLEOBJ_THIS(iface);
191     return IWebBrowser_QueryInterface(WEBBROWSER(This), riid, ppv);
192 }
193
194 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
195 {
196     WebBrowser *This = OLEOBJ_THIS(iface);
197     return IWebBrowser_AddRef(WEBBROWSER(This));
198 }
199
200 static ULONG WINAPI OleObject_Release(IOleObject *iface)
201 {
202     WebBrowser *This = OLEOBJ_THIS(iface);
203     return IWebBrowser_Release(WEBBROWSER(This));
204 }
205
206 static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, LPOLECLIENTSITE pClientSite)
207 {
208     WebBrowser *This = OLEOBJ_THIS(iface);
209     IOleContainer *container;
210     HRESULT hres;
211
212     TRACE("(%p)->(%p)\n", This, pClientSite);
213
214     if(This->client == pClientSite)
215         return S_OK;
216
217     if(This->doc_host.hwnd) {
218         DestroyWindow(This->doc_host.hwnd);
219         This->doc_host.hwnd = NULL;
220     }
221     if(This->shell_embedding_hwnd) {
222         DestroyWindow(This->shell_embedding_hwnd);
223         This->shell_embedding_hwnd = NULL;
224     }
225
226     if(This->inplace) {
227         IOleInPlaceSite_Release(This->inplace);
228         This->inplace = NULL;
229     }
230
231     if(This->doc_host.hostui)
232         IDocHostUIHandler_Release(This->doc_host.hostui);
233     if(This->client)
234         IOleClientSite_Release(This->client);
235
236     if(!pClientSite) {
237         if(This->doc_host.document)
238             deactivate_document(&This->doc_host);
239         This->client = NULL;
240         return S_OK;
241     }
242
243     This->client = pClientSite;
244     IOleClientSite_AddRef(pClientSite);
245
246     hres = IOleClientSite_QueryInterface(This->client, &IID_IDocHostUIHandler,
247                                          (void**)&This->doc_host.hostui);
248     if(FAILED(hres))
249         This->doc_host.hostui = NULL;
250
251     hres = IOleClientSite_GetContainer(This->client, &container);
252     if(SUCCEEDED(hres)) {
253         ITargetContainer *target_container;
254
255         hres = IOleContainer_QueryInterface(container, &IID_ITargetContainer,
256                                             (void**)&target_container);
257         if(SUCCEEDED(hres)) {
258             FIXME("Unsupported ITargetContainer\n");
259             ITargetContainer_Release(target_container);
260         }
261
262         IOleContainer_Release(container);
263     }
264
265     create_shell_embedding_hwnd(This);
266
267     return S_OK;
268 }
269
270 static HRESULT WINAPI OleObject_GetClientSite(IOleObject *iface, LPOLECLIENTSITE *ppClientSite)
271 {
272     WebBrowser *This = OLEOBJ_THIS(iface);
273
274     TRACE("(%p)->(%p)\n", This, ppClientSite);
275
276     if(!ppClientSite)
277         return E_INVALIDARG;
278
279     if(This->client)
280         IOleClientSite_AddRef(This->client);
281     *ppClientSite = This->client;
282
283     return S_OK;
284 }
285
286 static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR szContainerApp,
287         LPCOLESTR szContainerObj)
288 {
289     WebBrowser *This = OLEOBJ_THIS(iface);
290     FIXME("(%p)->(%s, %s)\n", This, debugstr_w(szContainerApp), debugstr_w(szContainerObj));
291     return E_NOTIMPL;
292 }
293
294 static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD dwSaveOption)
295 {
296     WebBrowser *This = OLEOBJ_THIS(iface);
297     FIXME("(%p)->(%ld)\n", This, dwSaveOption);
298     return E_NOTIMPL;
299 }
300
301 static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD dwWhichMoniker, IMoniker* pmk)
302 {
303     WebBrowser *This = OLEOBJ_THIS(iface);
304     FIXME("(%p)->(%ld, %p)\n", This, dwWhichMoniker, pmk);
305     return E_NOTIMPL;
306 }
307
308 static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD dwAssign,
309         DWORD dwWhichMoniker, LPMONIKER *ppmk)
310 {
311     WebBrowser *This = OLEOBJ_THIS(iface);
312     FIXME("(%p)->(%ld, %ld, %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
313     return E_NOTIMPL;
314 }
315
316 static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, LPDATAOBJECT pDataObject,
317         BOOL fCreation, DWORD dwReserved)
318 {
319     WebBrowser *This = OLEOBJ_THIS(iface);
320     FIXME("(%p)->(%p, %d, %ld)\n", This, pDataObject, fCreation, dwReserved);
321     return E_NOTIMPL;
322 }
323
324 static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD dwReserved,
325         LPDATAOBJECT *ppDataObject)
326 {
327     WebBrowser *This = OLEOBJ_THIS(iface);
328     FIXME("(%p)->(%ld, %p)\n", This, dwReserved, ppDataObject);
329     return E_NOTIMPL;
330 }
331
332 static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, struct tagMSG* lpmsg,
333         LPOLECLIENTSITE pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
334 {
335     WebBrowser *This = OLEOBJ_THIS(iface);
336
337     TRACE("(%p)->(%ld %p %p %ld %p %p)\n", This, iVerb, lpmsg, pActiveSite, lindex, hwndParent,
338             lprcPosRect);
339
340     switch (iVerb)
341     {
342     case OLEIVERB_SHOW:
343         TRACE("OLEIVERB_SHOW\n");
344         return activate_ui(This, pActiveSite, hwndParent);
345     case OLEIVERB_UIACTIVATE:
346         TRACE("OLEIVERB_UIACTIVATE\n");
347         return activate_ui(This, pActiveSite, hwndParent);
348     case OLEIVERB_INPLACEACTIVATE:
349         TRACE("OLEIVERB_INPLACEACTIVATE\n");
350         return activate_inplace(This, pActiveSite, hwndParent);
351     default:
352         FIXME("stub for %ld\n", iVerb);
353         break;
354     }
355
356     return E_NOTIMPL;
357 }
358
359 static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **ppEnumOleVerb)
360 {
361     WebBrowser *This = OLEOBJ_THIS(iface);
362     TRACE("(%p)->(%p)\n", This, ppEnumOleVerb);
363     return OleRegEnumVerbs(&CLSID_WebBrowser, ppEnumOleVerb);
364 }
365
366 static HRESULT WINAPI OleObject_Update(IOleObject *iface)
367 {
368     WebBrowser *This = OLEOBJ_THIS(iface);
369     FIXME("(%p)\n", This);
370     return E_NOTIMPL;
371 }
372
373 static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
374 {
375     WebBrowser *This = OLEOBJ_THIS(iface);
376     FIXME("(%p)\n", This);
377     return E_NOTIMPL;
378 }
379
380 static HRESULT WINAPI OleObject_GetUserClassID(IOleObject *iface, CLSID* pClsid)
381 {
382     WebBrowser *This = OLEOBJ_THIS(iface);
383     FIXME("(%p)->(%p)\n", This, pClsid);
384     return E_NOTIMPL;
385 }
386
387 static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD dwFormOfType,
388         LPOLESTR* pszUserType)
389 {
390     WebBrowser *This = OLEOBJ_THIS(iface);
391     TRACE("(%p, %ld, %p)\n", This, dwFormOfType, pszUserType);
392     return OleRegGetUserType(&CLSID_WebBrowser, dwFormOfType, pszUserType);
393 }
394
395 static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
396 {
397     WebBrowser *This = OLEOBJ_THIS(iface);
398
399     TRACE("(%p)->(%lx %p)\n", This, dwDrawAspect, psizel);
400
401     /* Tests show that dwDrawAspect is ignored */
402     memcpy(&This->extent, psizel, sizeof(SIZEL));
403     return S_OK;
404 }
405
406 static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
407 {
408     WebBrowser *This = OLEOBJ_THIS(iface);
409
410     TRACE("(%p)->(%lx, %p)\n", This, dwDrawAspect, psizel);
411
412     /* Tests show that dwDrawAspect is ignored */
413     memcpy(psizel, &This->extent, sizeof(SIZEL));
414     return S_OK;
415 }
416
417 static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *pAdvSink,
418         DWORD* pdwConnection)
419 {
420     WebBrowser *This = OLEOBJ_THIS(iface);
421     FIXME("(%p)->(%p, %p)\n", This, pAdvSink, pdwConnection);
422     return E_NOTIMPL;
423 }
424
425 static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD dwConnection)
426 {
427     WebBrowser *This = OLEOBJ_THIS(iface);
428     FIXME("(%p)->(%ld)\n", This, dwConnection);
429     return E_NOTIMPL;
430 }
431
432 static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **ppenumAdvise)
433 {
434     WebBrowser *This = OLEOBJ_THIS(iface);
435     FIXME("(%p)->(%p)\n", This, ppenumAdvise);
436     return S_OK;
437 }
438
439 static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD dwAspect, DWORD *pdwStatus)
440 {
441     WebBrowser *This = OLEOBJ_THIS(iface);
442
443     TRACE("(%p)->(%lx, %p)\n", This, dwAspect, pdwStatus);
444
445     *pdwStatus = OLEMISC_SETCLIENTSITEFIRST|OLEMISC_ACTIVATEWHENVISIBLE|OLEMISC_INSIDEOUT
446         |OLEMISC_CANTLINKINSIDE|OLEMISC_RECOMPOSEONRESIZE;
447
448     return S_OK;
449 }
450
451 static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE* pLogpal)
452 {
453     WebBrowser *This = OLEOBJ_THIS(iface);
454     FIXME("(%p)->(%p)\n", This, pLogpal);
455     return E_NOTIMPL;
456 }
457
458 #undef OLEOBJ_THIS
459
460 static const IOleObjectVtbl OleObjectVtbl =
461 {
462     OleObject_QueryInterface,
463     OleObject_AddRef,
464     OleObject_Release,
465     OleObject_SetClientSite,
466     OleObject_GetClientSite,
467     OleObject_SetHostNames,
468     OleObject_Close,
469     OleObject_SetMoniker,
470     OleObject_GetMoniker,
471     OleObject_InitFromData,
472     OleObject_GetClipboardData,
473     OleObject_DoVerb,
474     OleObject_EnumVerbs,
475     OleObject_Update,
476     OleObject_IsUpToDate,
477     OleObject_GetUserClassID,
478     OleObject_GetUserType,
479     OleObject_SetExtent,
480     OleObject_GetExtent,
481     OleObject_Advise,
482     OleObject_Unadvise,
483     OleObject_EnumAdvise,
484     OleObject_GetMiscStatus,
485     OleObject_SetColorScheme
486 };
487
488 /**********************************************************************
489  * Implement the IOleInPlaceObject interface
490  */
491
492 #define INPLACEOBJ_THIS(iface) DEFINE_THIS(WebBrowser, OleInPlaceObject, iface)
493
494 static HRESULT WINAPI OleInPlaceObject_QueryInterface(IOleInPlaceObject *iface,
495         REFIID riid, LPVOID *ppobj)
496 {
497     WebBrowser *This = INPLACEOBJ_THIS(iface);
498     return IWebBrowser_QueryInterface(WEBBROWSER(This), riid, ppobj);
499 }
500
501 static ULONG WINAPI OleInPlaceObject_AddRef(IOleInPlaceObject *iface)
502 {
503     WebBrowser *This = INPLACEOBJ_THIS(iface);
504     return IWebBrowser_AddRef(WEBBROWSER(This));
505 }
506
507 static ULONG WINAPI OleInPlaceObject_Release(IOleInPlaceObject *iface)
508 {
509     WebBrowser *This = INPLACEOBJ_THIS(iface);
510     return IWebBrowser_Release(WEBBROWSER(This));
511 }
512
513 static HRESULT WINAPI OleInPlaceObject_GetWindow(IOleInPlaceObject *iface, HWND* phwnd)
514 {
515     WebBrowser *This = INPLACEOBJ_THIS(iface);
516
517     TRACE("(%p)->(%p)\n", This, phwnd);
518
519     *phwnd = This->shell_embedding_hwnd;
520     return S_OK;
521 }
522
523 static HRESULT WINAPI OleInPlaceObject_ContextSensitiveHelp(IOleInPlaceObject *iface,
524         BOOL fEnterMode)
525 {
526     WebBrowser *This = INPLACEOBJ_THIS(iface);
527     FIXME("(%p)->(%x)\n", This, fEnterMode);
528     return E_NOTIMPL;
529 }
530
531 static HRESULT WINAPI OleInPlaceObject_InPlaceDeactivate(IOleInPlaceObject *iface)
532 {
533     WebBrowser *This = INPLACEOBJ_THIS(iface);
534     FIXME("(%p)\n", This);
535     return E_NOTIMPL;
536 }
537
538 static HRESULT WINAPI OleInPlaceObject_UIDeactivate(IOleInPlaceObject *iface)
539 {
540     WebBrowser *This = INPLACEOBJ_THIS(iface);
541     FIXME("(%p)\n", This);
542     return E_NOTIMPL;
543 }
544
545 static HRESULT WINAPI OleInPlaceObject_SetObjectRects(IOleInPlaceObject *iface,
546         LPCRECT lprcPosRect, LPCRECT lprcClipRect)
547 {
548     WebBrowser *This = INPLACEOBJ_THIS(iface);
549
550     TRACE("(%p)->(%p %p)\n", This, lprcPosRect, lprcClipRect);
551
552     memcpy(&This->pos_rect, lprcPosRect, sizeof(RECT));
553
554     if(lprcClipRect)
555         memcpy(&This->clip_rect, lprcClipRect, sizeof(RECT));
556
557     if(This->shell_embedding_hwnd) {
558         SetWindowPos(This->shell_embedding_hwnd, NULL,
559                      lprcPosRect->left, lprcPosRect->top,
560                      lprcPosRect->right-lprcPosRect->left,
561                      lprcPosRect->bottom-lprcPosRect->top,
562                      SWP_NOZORDER | SWP_NOACTIVATE);
563     }
564
565     return S_OK;
566 }
567
568 static HRESULT WINAPI OleInPlaceObject_ReactivateAndUndo(IOleInPlaceObject *iface)
569 {
570     WebBrowser *This = INPLACEOBJ_THIS(iface);
571     FIXME("(%p)\n", This);
572     return E_NOTIMPL;
573 }
574
575 #undef INPLACEOBJ_THIS
576
577 static const IOleInPlaceObjectVtbl OleInPlaceObjectVtbl =
578 {
579     OleInPlaceObject_QueryInterface,
580     OleInPlaceObject_AddRef,
581     OleInPlaceObject_Release,
582     OleInPlaceObject_GetWindow,
583     OleInPlaceObject_ContextSensitiveHelp,
584     OleInPlaceObject_InPlaceDeactivate,
585     OleInPlaceObject_UIDeactivate,
586     OleInPlaceObject_SetObjectRects,
587     OleInPlaceObject_ReactivateAndUndo
588 };
589
590 /**********************************************************************
591  * Implement the IOleControl interface
592  */
593
594 #define CONTROL_THIS(iface) DEFINE_THIS(WebBrowser, OleControl, iface)
595
596 static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface,
597         REFIID riid, LPVOID *ppobj)
598 {
599     WebBrowser *This = CONTROL_THIS(iface);
600     return IWebBrowser_QueryInterface(WEBBROWSER(This), riid, ppobj);
601 }
602
603 static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
604 {
605     WebBrowser *This = CONTROL_THIS(iface);
606     return IWebBrowser_AddRef(WEBBROWSER(This));
607 }
608
609 static ULONG WINAPI OleControl_Release(IOleControl *iface)
610 {
611     WebBrowser *This = CONTROL_THIS(iface);
612     return IWebBrowser_Release(WEBBROWSER(This));
613 }
614
615 static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, LPCONTROLINFO pCI)
616 {
617     WebBrowser *This = CONTROL_THIS(iface);
618
619     TRACE("(%p)->(%p)\n", This, pCI);
620
621     /* Tests show that this function should be not implemented */
622     return E_NOTIMPL;
623 }
624
625 static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, struct tagMSG *pMsg)
626 {
627     WebBrowser *This = CONTROL_THIS(iface);
628     FIXME("(%p)->(%p)\n", This, pMsg);
629     return E_NOTIMPL;
630 }
631
632 static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispID)
633 {
634     WebBrowser *This = CONTROL_THIS(iface);
635     FIXME("(%p)->(%ld)\n", This, dispID);
636     return E_NOTIMPL;
637 }
638
639 static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL bFreeze)
640 {
641     WebBrowser *This = CONTROL_THIS(iface);
642     FIXME("(%p)->(%x)\n", This, bFreeze);
643     return E_NOTIMPL;
644 }
645
646 #undef CONTROL_THIS
647
648 static const IOleControlVtbl OleControlVtbl =
649 {
650     OleControl_QueryInterface,
651     OleControl_AddRef,
652     OleControl_Release,
653     OleControl_GetControlInfo,
654     OleControl_OnMnemonic,
655     OleControl_OnAmbientPropertyChange,
656     OleControl_FreezeEvents
657 };
658
659 #define ACTIVEOBJ_THIS(iface) DEFINE_THIS(WebBrowser, OleInPlaceActiveObject, iface)
660
661 static HRESULT WINAPI InPlaceActiveObject_QueryInterface(IOleInPlaceActiveObject *iface,
662                                                             REFIID riid, void **ppv)
663 {
664     WebBrowser *This = ACTIVEOBJ_THIS(iface);
665     return IWebBrowser2_QueryInterface(WEBBROWSER2(This), riid, ppv);
666 }
667
668 static ULONG WINAPI InPlaceActiveObject_AddRef(IOleInPlaceActiveObject *iface)
669 {
670     WebBrowser *This = ACTIVEOBJ_THIS(iface);
671     return IWebBrowser2_AddRef(WEBBROWSER2(This));
672 }
673
674 static ULONG WINAPI InPlaceActiveObject_Release(IOleInPlaceActiveObject *iface)
675 {
676     WebBrowser *This = ACTIVEOBJ_THIS(iface);
677     return IWebBrowser2_Release(WEBBROWSER2(This));
678 }
679
680 static HRESULT WINAPI InPlaceActiveObject_GetWindow(IOleInPlaceActiveObject *iface,
681                                                     HWND *phwnd)
682 {
683     WebBrowser *This = ACTIVEOBJ_THIS(iface);
684     return IOleInPlaceObject_GetWindow(INPLACEOBJ(This), phwnd);
685 }
686
687 static HRESULT WINAPI InPlaceActiveObject_ContextSensitiveHelp(IOleInPlaceActiveObject *iface,
688                                                                BOOL fEnterMode)
689 {
690     WebBrowser *This = ACTIVEOBJ_THIS(iface);
691     return IOleInPlaceObject_ContextSensitiveHelp(INPLACEOBJ(This), fEnterMode);
692 }
693
694 static HRESULT WINAPI InPlaceActiveObject_TranslateAccelerator(IOleInPlaceActiveObject *iface,
695                                                                LPMSG lpmsg)
696 {
697     WebBrowser *This = ACTIVEOBJ_THIS(iface);
698     FIXME("(%p)->(%p)\n", This, lpmsg);
699     return E_NOTIMPL;
700 }
701
702 static HRESULT WINAPI InPlaceActiveObject_OnFrameWindowActivate(IOleInPlaceActiveObject *iface,
703                                                                 BOOL fActivate)
704 {
705     WebBrowser *This = ACTIVEOBJ_THIS(iface);
706     FIXME("(%p)->(%x)\n", This, fActivate);
707     return E_NOTIMPL;
708 }
709
710 static HRESULT WINAPI InPlaceActiveObject_OnDocWindowActivate(IOleInPlaceActiveObject *iface,
711                                                               BOOL fActivate)
712 {
713     WebBrowser *This = ACTIVEOBJ_THIS(iface);
714     FIXME("(%p)->(%x)\n", This, fActivate);
715     return E_NOTIMPL;
716 }
717
718 static HRESULT WINAPI InPlaceActiveObject_ResizeBorder(IOleInPlaceActiveObject *iface,
719         LPCRECT lprcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fFrameWindow)
720 {
721     WebBrowser *This = ACTIVEOBJ_THIS(iface);
722     FIXME("(%p)->(%p %p %x)\n", This, lprcBorder, pUIWindow, fFrameWindow);
723     return E_NOTIMPL;
724 }
725
726 static HRESULT WINAPI InPlaceActiveObject_EnableModeless(IOleInPlaceActiveObject *iface,
727                                                          BOOL fEnable)
728 {
729     WebBrowser *This = ACTIVEOBJ_THIS(iface);
730     FIXME("(%p)->(%x)\n", This, fEnable);
731     return E_NOTIMPL;
732 }
733
734 #undef ACTIVEOBJ_THIS
735
736 static const IOleInPlaceActiveObjectVtbl OleInPlaceActiveObjectVtbl = {
737     InPlaceActiveObject_QueryInterface,
738     InPlaceActiveObject_AddRef,
739     InPlaceActiveObject_Release,
740     InPlaceActiveObject_GetWindow,
741     InPlaceActiveObject_ContextSensitiveHelp,
742     InPlaceActiveObject_TranslateAccelerator,
743     InPlaceActiveObject_OnFrameWindowActivate,
744     InPlaceActiveObject_OnDocWindowActivate,
745     InPlaceActiveObject_ResizeBorder,
746     InPlaceActiveObject_EnableModeless
747 };
748
749 #define OLECMD_THIS(iface) DEFINE_THIS(WebBrowser, OleCommandTarget, iface)
750
751 static HRESULT WINAPI WBOleCommandTarget_QueryInterface(IOleCommandTarget *iface,
752         REFIID riid, void **ppv)
753 {
754     WebBrowser *This = OLECMD_THIS(iface);
755     return IWebBrowser2_QueryInterface(WEBBROWSER(This), riid, ppv);
756 }
757
758 static ULONG WINAPI WBOleCommandTarget_AddRef(IOleCommandTarget *iface)
759 {
760     WebBrowser *This = OLECMD_THIS(iface);
761     return IWebBrowser2_AddRef(WEBBROWSER(This));
762 }
763
764 static ULONG WINAPI WBOleCommandTarget_Release(IOleCommandTarget *iface)
765 {
766     WebBrowser *This = OLECMD_THIS(iface);
767     return IWebBrowser2_Release(WEBBROWSER(This));
768 }
769
770 static HRESULT WINAPI WBOleCommandTarget_QueryStatus(IOleCommandTarget *iface,
771         const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
772 {
773     WebBrowser *This = OLECMD_THIS(iface);
774     FIXME("(%p)->(%s %lu %p %p)\n", This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds,
775           pCmdText);
776     return E_NOTIMPL;
777 }
778
779 static HRESULT WINAPI WBOleCommandTarget_Exec(IOleCommandTarget *iface,
780         const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn,
781         VARIANT *pvaOut)
782 {
783     WebBrowser *This = OLECMD_THIS(iface);
784     FIXME("(%p)->(%s %ld %ld %p %p)\n", This, debugstr_guid(pguidCmdGroup), nCmdID,
785           nCmdexecopt, pvaIn, pvaOut);
786     return E_NOTIMPL;
787 }
788
789 #undef OLECMD_THIS
790
791 static const IOleCommandTargetVtbl OleCommandTargetVtbl = {
792     WBOleCommandTarget_QueryInterface,
793     WBOleCommandTarget_AddRef,
794     WBOleCommandTarget_Release,
795     WBOleCommandTarget_QueryStatus,
796     WBOleCommandTarget_Exec
797 };
798
799 void WebBrowser_OleObject_Init(WebBrowser *This)
800 {
801     This->lpOleObjectVtbl              = &OleObjectVtbl;
802     This->lpOleInPlaceObjectVtbl       = &OleInPlaceObjectVtbl;
803     This->lpOleControlVtbl             = &OleControlVtbl;
804     This->lpOleInPlaceActiveObjectVtbl = &OleInPlaceActiveObjectVtbl;
805     This->lpOleCommandTargetVtbl     = &OleCommandTargetVtbl;
806
807     This->client = NULL;
808     This->inplace = NULL;
809     This->container = NULL;
810     This->iphwnd = NULL;
811     This->frame_hwnd = NULL;
812     This->frame = NULL;
813     This->uiwindow = NULL;
814     This->shell_embedding_hwnd = NULL;
815
816     memset(&This->pos_rect, 0, sizeof(RECT));
817     memset(&This->clip_rect, 0, sizeof(RECT));
818     memset(&This->frameinfo, 0, sizeof(OLEINPLACEFRAMEINFO));
819
820     This->extent.cx = 1323;
821     This->extent.cy = 529;
822 }
823
824 void WebBrowser_OleObject_Destroy(WebBrowser *This)
825 {
826     if(This->client)
827         IOleObject_SetClientSite(OLEOBJ(This), NULL);
828     if(This->container)
829         IOleContainer_Release(This->container);
830     if(This->frame)
831         IOleInPlaceFrame_Release(This->frame);
832     if(This->uiwindow)
833         IOleInPlaceUIWindow_Release(This->uiwindow);
834 }