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