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