rpcrt4: Add a comment in NdrSendReceive explaining why we change the BufferLength.
[wine] / dlls / hhctrl.ocx / webbrowser.c
1 /*
2  * WebBrowser Implementation
3  *
4  * Copyright 2005 James Hawkins
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "hhctrl.h"
22
23 #define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
24
25 typedef struct IOleClientSiteImpl
26 {
27     const IOleClientSiteVtbl *lpVtbl;
28     const IOleInPlaceSiteVtbl *lpvtblOleInPlaceSite;
29     const IOleInPlaceFrameVtbl *lpvtblOleInPlaceFrame;
30     const IDocHostUIHandlerVtbl *lpvtblDocHostUIHandler;
31
32     /* IOleClientSiteImpl data */
33     IOleObject *pBrowserObject;
34     LONG ref;
35
36     /* IOleInPlaceFrame data */
37     HWND hwndWindow;
38 } IOleClientSiteImpl;
39
40 static HRESULT STDMETHODCALLTYPE Site_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppvObj)
41 {
42     ICOM_THIS_MULTI(IOleClientSiteImpl, lpVtbl, iface);
43     *ppvObj = NULL;
44
45     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IOleClientSite))
46     {
47         *ppvObj = This;
48     }
49     else if (IsEqualIID(riid, &IID_IOleInPlaceSite))
50     {
51         *ppvObj = &(This->lpvtblOleInPlaceSite);
52     }
53     else if (IsEqualIID(riid, &IID_IDocHostUIHandler))
54     {
55         *ppvObj = &(This->lpvtblDocHostUIHandler);
56     }
57     else
58         return E_NOINTERFACE;
59
60     return S_OK;
61 }
62
63 static ULONG STDMETHODCALLTYPE Site_AddRef(IOleClientSite *iface)
64 {
65     ICOM_THIS_MULTI(IOleClientSiteImpl, lpVtbl, iface);
66     return InterlockedIncrement(&This->ref);
67 }
68
69 static ULONG STDMETHODCALLTYPE Site_Release(IOleClientSite *iface)
70 {
71     ICOM_THIS_MULTI(IOleClientSiteImpl, lpVtbl, iface);
72     LONG refCount = InterlockedDecrement(&This->ref);
73
74     if (refCount)
75         return refCount;
76
77     heap_free(This);
78     return 0;
79 }
80
81 static HRESULT STDMETHODCALLTYPE Site_SaveObject(IOleClientSite *iface)
82 {
83     return E_NOTIMPL;
84 }
85
86 static HRESULT STDMETHODCALLTYPE Site_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
87 {
88     return E_NOTIMPL;
89 }
90
91 static HRESULT STDMETHODCALLTYPE Site_GetContainer(IOleClientSite *iface, LPOLECONTAINER *ppContainer)
92 {
93     *ppContainer = NULL;
94
95     return E_NOINTERFACE;
96 }
97
98 static HRESULT STDMETHODCALLTYPE Site_ShowObject(IOleClientSite *iface)
99 {
100     return NOERROR;
101 }
102
103 static HRESULT STDMETHODCALLTYPE Site_OnShowWindow(IOleClientSite *iface, BOOL fShow)
104 {
105     return E_NOTIMPL;
106 }
107
108 static HRESULT STDMETHODCALLTYPE Site_RequestNewObjectLayout(IOleClientSite *iface)
109 {
110     return E_NOTIMPL;
111 }
112
113 static const IOleClientSiteVtbl MyIOleClientSiteTable =
114 {
115     Site_QueryInterface,
116     Site_AddRef,
117     Site_Release,
118     Site_SaveObject,
119     Site_GetMoniker,
120     Site_GetContainer,
121     Site_ShowObject,
122     Site_OnShowWindow,
123     Site_RequestNewObjectLayout
124 };
125
126 static HRESULT STDMETHODCALLTYPE UI_QueryInterface(IDocHostUIHandler *iface, REFIID riid, LPVOID *ppvObj)
127 {
128     ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblDocHostUIHandler, iface);
129     return Site_QueryInterface((IOleClientSite *)This, riid, ppvObj);
130 }
131
132 static ULONG STDMETHODCALLTYPE UI_AddRef(IDocHostUIHandler *iface)
133 {
134     return 1;
135 }
136
137 static ULONG STDMETHODCALLTYPE UI_Release(IDocHostUIHandler * iface)
138 {
139     return 2;
140 }
141
142 static HRESULT STDMETHODCALLTYPE UI_ShowContextMenu(IDocHostUIHandler *iface, DWORD dwID, POINT *ppt, IUnknown *pcmdtReserved, IDispatch *pdispReserved)
143 {
144     return S_OK;
145 }
146
147 static HRESULT STDMETHODCALLTYPE UI_GetHostInfo(IDocHostUIHandler *iface, DOCHOSTUIINFO *pInfo)
148 {
149     pInfo->cbSize = sizeof(DOCHOSTUIINFO);
150     pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER;
151     pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
152
153     return S_OK;
154 }
155
156 static HRESULT STDMETHODCALLTYPE UI_ShowUI(IDocHostUIHandler *iface, DWORD dwID, IOleInPlaceActiveObject *pActiveObject, IOleCommandTarget *pCommandTarget, IOleInPlaceFrame *pFrame, IOleInPlaceUIWindow *pDoc)
157 {
158     return S_OK;
159 }
160
161 static HRESULT STDMETHODCALLTYPE UI_HideUI(IDocHostUIHandler *iface)
162 {
163     return S_OK;
164 }
165
166 static HRESULT STDMETHODCALLTYPE UI_UpdateUI(IDocHostUIHandler *iface)
167 {
168     return S_OK;
169 }
170
171 static HRESULT STDMETHODCALLTYPE UI_EnableModeless(IDocHostUIHandler *iface, BOOL fEnable)
172 {
173     return S_OK;
174 }
175
176 static HRESULT STDMETHODCALLTYPE UI_OnDocWindowActivate(IDocHostUIHandler *iface, BOOL fActivate)
177 {
178     return S_OK;
179 }
180
181 static HRESULT STDMETHODCALLTYPE UI_OnFrameWindowActivate(IDocHostUIHandler *iface, BOOL fActivate)
182 {
183     return S_OK;
184 }
185
186 static HRESULT STDMETHODCALLTYPE UI_ResizeBorder(IDocHostUIHandler *iface, LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow)
187 {
188     return S_OK;
189 }
190
191 static HRESULT STDMETHODCALLTYPE UI_TranslateAccelerator(IDocHostUIHandler *iface, LPMSG lpMsg, const GUID *pguidCmdGroup, DWORD nCmdID)
192 {
193     return S_FALSE;
194 }
195
196 static HRESULT STDMETHODCALLTYPE UI_GetOptionKeyPath(IDocHostUIHandler *iface, LPOLESTR *pchKey, DWORD dw)
197 {
198     return S_FALSE;
199 }
200
201 static HRESULT STDMETHODCALLTYPE UI_GetDropTarget(IDocHostUIHandler *iface, IDropTarget *pDropTarget, IDropTarget **ppDropTarget)
202 {
203     return S_FALSE;
204 }
205
206 static HRESULT STDMETHODCALLTYPE UI_GetExternal(IDocHostUIHandler *iface, IDispatch **ppDispatch)
207 {
208     *ppDispatch = NULL;
209     return S_FALSE;
210 }
211
212 static HRESULT STDMETHODCALLTYPE UI_TranslateUrl(IDocHostUIHandler *iface, DWORD dwTranslate, OLECHAR *pchURLIn, OLECHAR **ppchURLOut)
213 {
214     *ppchURLOut = NULL;
215     return S_FALSE;
216 }
217
218 static HRESULT STDMETHODCALLTYPE UI_FilterDataObject(IDocHostUIHandler *iface, IDataObject *pDO, IDataObject **ppDORet)
219 {
220     *ppDORet = NULL;
221     return S_FALSE;
222 }
223
224 static const IDocHostUIHandlerVtbl MyIDocHostUIHandlerTable =
225 {
226     UI_QueryInterface,
227     UI_AddRef,
228     UI_Release,
229     UI_ShowContextMenu,
230     UI_GetHostInfo,
231     UI_ShowUI,
232     UI_HideUI,
233     UI_UpdateUI,
234     UI_EnableModeless,
235     UI_OnDocWindowActivate,
236     UI_OnFrameWindowActivate,
237     UI_ResizeBorder,
238     UI_TranslateAccelerator,
239     UI_GetOptionKeyPath,
240     UI_GetDropTarget,
241     UI_GetExternal,
242     UI_TranslateUrl,
243     UI_FilterDataObject
244 };
245
246 static HRESULT STDMETHODCALLTYPE InPlace_QueryInterface(IOleInPlaceSite *iface, REFIID riid, LPVOID *ppvObj)
247 {
248     ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceSite, iface);
249     return Site_QueryInterface((IOleClientSite *)This, riid, ppvObj);
250 }
251
252 static ULONG STDMETHODCALLTYPE InPlace_AddRef(IOleInPlaceSite *iface)
253 {
254     return 1;
255 }
256
257 static ULONG STDMETHODCALLTYPE InPlace_Release(IOleInPlaceSite *iface)
258 {
259     return 2;
260 }
261
262 static HRESULT STDMETHODCALLTYPE InPlace_GetWindow(IOleInPlaceSite *iface, HWND *lphwnd)
263 {
264     ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceSite, iface);
265     *lphwnd = This->hwndWindow;
266
267     return S_OK;
268 }
269
270 static HRESULT STDMETHODCALLTYPE InPlace_ContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
271 {
272     return E_NOTIMPL;
273 }
274
275 static HRESULT STDMETHODCALLTYPE InPlace_CanInPlaceActivate(IOleInPlaceSite *iface)
276 {
277     return S_OK;
278 }
279
280 static HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceActivate(IOleInPlaceSite *iface)
281 {
282     return S_OK;
283 }
284
285 static HRESULT STDMETHODCALLTYPE InPlace_OnUIActivate(IOleInPlaceSite *iface)
286 {
287     return S_OK;
288 }
289
290 static HRESULT STDMETHODCALLTYPE InPlace_GetWindowContext(IOleInPlaceSite *iface, LPOLEINPLACEFRAME *lplpFrame, LPOLEINPLACEUIWINDOW *lplpDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
291 {
292     ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceSite, iface);
293     *lplpFrame = (LPOLEINPLACEFRAME)&This->lpvtblOleInPlaceFrame;
294     *lplpDoc = NULL;
295
296     lpFrameInfo->fMDIApp = FALSE;
297     lpFrameInfo->hwndFrame = This->hwndWindow;
298     lpFrameInfo->haccel = NULL;
299     lpFrameInfo->cAccelEntries = 0;
300
301     return S_OK;
302 }
303
304 static HRESULT STDMETHODCALLTYPE InPlace_Scroll(IOleInPlaceSite *iface, SIZE scrollExtent)
305 {
306     return E_NOTIMPL;
307 }
308
309 static HRESULT STDMETHODCALLTYPE InPlace_OnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
310 {
311     return S_OK;
312 }
313
314 static HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceDeactivate(IOleInPlaceSite *iface)
315 {
316     return S_OK;
317 }
318
319 static HRESULT STDMETHODCALLTYPE InPlace_DiscardUndoState(IOleInPlaceSite *iface)
320 {
321     return E_NOTIMPL;
322 }
323
324 static HRESULT STDMETHODCALLTYPE InPlace_DeactivateAndUndo(IOleInPlaceSite *iface)
325 {
326     return E_NOTIMPL;
327 }
328
329 static HRESULT STDMETHODCALLTYPE InPlace_OnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
330 {
331     ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceSite, iface);
332     IOleInPlaceObject *inplace;
333
334     if (!IOleObject_QueryInterface(This->pBrowserObject, &IID_IOleInPlaceObject, (void **)&inplace))
335         IOleInPlaceObject_SetObjectRects(inplace, lprcPosRect, lprcPosRect);
336
337     return S_OK;
338 }
339
340 static const IOleInPlaceSiteVtbl MyIOleInPlaceSiteTable =
341 {
342     InPlace_QueryInterface,
343     InPlace_AddRef,
344     InPlace_Release,
345     InPlace_GetWindow,
346     InPlace_ContextSensitiveHelp,
347     InPlace_CanInPlaceActivate,
348     InPlace_OnInPlaceActivate,
349     InPlace_OnUIActivate,
350     InPlace_GetWindowContext,
351     InPlace_Scroll,
352     InPlace_OnUIDeactivate,
353     InPlace_OnInPlaceDeactivate,
354     InPlace_DiscardUndoState,
355     InPlace_DeactivateAndUndo,
356     InPlace_OnPosRectChange
357 };
358
359 static HRESULT STDMETHODCALLTYPE Frame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, LPVOID *ppvObj)
360 {
361     return E_NOTIMPL;
362 }
363
364 static ULONG STDMETHODCALLTYPE Frame_AddRef(IOleInPlaceFrame *iface)
365 {
366     return 1;
367 }
368
369 static ULONG STDMETHODCALLTYPE Frame_Release(IOleInPlaceFrame *iface)
370 {
371     return 2;
372 }
373
374 static HRESULT STDMETHODCALLTYPE Frame_GetWindow(IOleInPlaceFrame *iface, HWND *lphwnd)
375 {
376     ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceFrame, iface);
377     *lphwnd = This->hwndWindow;
378
379     return S_OK;
380 }
381
382 static HRESULT STDMETHODCALLTYPE Frame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode)
383 {
384     return E_NOTIMPL;
385 }
386
387 static HRESULT STDMETHODCALLTYPE Frame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder)
388 {
389     return E_NOTIMPL;
390 }
391
392 static HRESULT STDMETHODCALLTYPE Frame_RequestBorderSpace(IOleInPlaceFrame *iface, LPCBORDERWIDTHS pborderwidths)
393 {
394     return E_NOTIMPL;
395 }
396
397 static HRESULT STDMETHODCALLTYPE Frame_SetBorderSpace(IOleInPlaceFrame *iface, LPCBORDERWIDTHS pborderwidths)
398 {
399     return E_NOTIMPL;
400 }
401
402 static HRESULT STDMETHODCALLTYPE Frame_SetActiveObject(IOleInPlaceFrame *iface, IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
403 {
404     return S_OK;
405 }
406
407 static HRESULT STDMETHODCALLTYPE Frame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
408 {
409     return E_NOTIMPL;
410 }
411
412 static HRESULT STDMETHODCALLTYPE Frame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
413 {
414     return S_OK;
415 }
416
417 static HRESULT STDMETHODCALLTYPE Frame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared)
418 {
419     return E_NOTIMPL;
420 }
421
422 static HRESULT STDMETHODCALLTYPE Frame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText)
423 {
424     return S_OK;
425 }
426
427 static HRESULT STDMETHODCALLTYPE Frame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
428 {
429     return S_OK;
430 }
431
432 static HRESULT STDMETHODCALLTYPE Frame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID)
433 {
434     return E_NOTIMPL;
435 }
436
437 static const IOleInPlaceFrameVtbl MyIOleInPlaceFrameTable =
438 {
439     Frame_QueryInterface,
440     Frame_AddRef,
441     Frame_Release,
442     Frame_GetWindow,
443     Frame_ContextSensitiveHelp,
444     Frame_GetBorder,
445     Frame_RequestBorderSpace,
446     Frame_SetBorderSpace,
447     Frame_SetActiveObject,
448     Frame_InsertMenus,
449     Frame_SetMenu,
450     Frame_RemoveMenus,
451     Frame_SetStatusText,
452     Frame_EnableModeless,
453     Frame_TranslateAccelerator
454 };
455
456 static HRESULT STDMETHODCALLTYPE Storage_QueryInterface(IStorage *This, REFIID riid, LPVOID *ppvObj)
457 {
458     return E_NOTIMPL;
459 }
460
461 static ULONG STDMETHODCALLTYPE Storage_AddRef(IStorage *This)
462 {
463     return 1;
464 }
465
466 static ULONG STDMETHODCALLTYPE Storage_Release(IStorage *This)
467 {
468     return 2;
469 }
470
471 static HRESULT STDMETHODCALLTYPE Storage_CreateStream(IStorage *This, const WCHAR *pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream **ppstm)
472 {
473     return E_NOTIMPL;
474 }
475
476 static HRESULT STDMETHODCALLTYPE Storage_OpenStream(IStorage *This, const WCHAR * pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream **ppstm)
477 {
478     return E_NOTIMPL;
479 }
480
481 static HRESULT STDMETHODCALLTYPE Storage_CreateStorage(IStorage *This, const WCHAR *pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStorage **ppstg)
482 {
483     return E_NOTIMPL;
484 }
485
486 static HRESULT STDMETHODCALLTYPE Storage_OpenStorage(IStorage *This, const WCHAR * pwcsName, IStorage * pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstg)
487 {
488     return E_NOTIMPL;
489 }
490
491 static HRESULT STDMETHODCALLTYPE Storage_CopyTo(IStorage *This, DWORD ciidExclude, IID const *rgiidExclude, SNB snbExclude,IStorage *pstgDest)
492 {
493     return E_NOTIMPL;
494 }
495
496 static HRESULT STDMETHODCALLTYPE Storage_MoveElementTo(IStorage *This, const OLECHAR *pwcsName,IStorage * pstgDest, const OLECHAR *pwcsNewName, DWORD grfFlags)
497 {
498     return E_NOTIMPL;
499 }
500
501 static HRESULT STDMETHODCALLTYPE Storage_Commit(IStorage *This, DWORD grfCommitFlags)
502 {
503     return E_NOTIMPL;
504 }
505
506 static HRESULT STDMETHODCALLTYPE Storage_Revert(IStorage *This)
507 {
508     return E_NOTIMPL;
509 }
510
511 static HRESULT STDMETHODCALLTYPE Storage_EnumElements(IStorage *This, DWORD reserved1, void *reserved2, DWORD reserved3, IEnumSTATSTG **ppenum)
512 {
513     return E_NOTIMPL;
514 }
515
516 static HRESULT STDMETHODCALLTYPE Storage_DestroyElement(IStorage *This, const OLECHAR *pwcsName)
517 {
518     return E_NOTIMPL;
519 }
520
521 static HRESULT STDMETHODCALLTYPE Storage_RenameElement(IStorage *This, const WCHAR *pwcsOldName, const WCHAR *pwcsNewName)
522 {
523     return E_NOTIMPL;
524 }
525
526 static HRESULT STDMETHODCALLTYPE Storage_SetElementTimes(IStorage *This, const WCHAR *pwcsName, FILETIME const *pctime, FILETIME const *patime, FILETIME const *pmtime)
527 {
528     return E_NOTIMPL;
529 }
530
531 static HRESULT STDMETHODCALLTYPE Storage_SetClass(IStorage *This, REFCLSID clsid)
532 {
533     return S_OK;
534 }
535
536 static HRESULT STDMETHODCALLTYPE Storage_SetStateBits(IStorage *This, DWORD grfStateBits, DWORD grfMask)
537 {
538     return E_NOTIMPL;
539 }
540
541 static HRESULT STDMETHODCALLTYPE Storage_Stat(IStorage *This, STATSTG *pstatstg, DWORD grfStatFlag)
542 {
543     return E_NOTIMPL;
544 }
545
546 static const IStorageVtbl MyIStorageTable =
547 {
548     Storage_QueryInterface,
549     Storage_AddRef,
550     Storage_Release,
551     Storage_CreateStream,
552     Storage_OpenStream,
553     Storage_CreateStorage,
554     Storage_OpenStorage,
555     Storage_CopyTo,
556     Storage_MoveElementTo,
557     Storage_Commit,
558     Storage_Revert,
559     Storage_EnumElements,
560     Storage_DestroyElement,
561     Storage_RenameElement,
562     Storage_SetElementTimes,
563     Storage_SetClass,
564     Storage_SetStateBits,
565     Storage_Stat
566 };
567
568 static IStorage MyIStorage = { &MyIStorageTable };
569
570 BOOL InitWebBrowser(HHInfo *info, HWND hwndParent)
571 {
572     IOleClientSiteImpl *iOleClientSiteImpl;
573     IOleInPlaceObject *inplace;
574     IOleObject *browserObject;
575     IWebBrowser2 *webBrowser2;
576     HRESULT hr;
577     RECT rc;
578
579     iOleClientSiteImpl = heap_alloc_zero(sizeof(IOleClientSiteImpl));
580     if (!iOleClientSiteImpl)
581         return FALSE;
582
583     iOleClientSiteImpl->ref = 1;
584     iOleClientSiteImpl->lpVtbl = &MyIOleClientSiteTable;
585     iOleClientSiteImpl->lpvtblOleInPlaceSite = &MyIOleInPlaceSiteTable;
586     iOleClientSiteImpl->lpvtblOleInPlaceFrame = &MyIOleInPlaceFrameTable;
587     iOleClientSiteImpl->hwndWindow = hwndParent;
588     iOleClientSiteImpl->lpvtblDocHostUIHandler = &MyIDocHostUIHandlerTable;
589
590     hr = OleCreate(&CLSID_WebBrowser, &IID_IOleObject, OLERENDER_DRAW, 0,
591                    (IOleClientSite *)iOleClientSiteImpl, &MyIStorage,
592                    (void **)&browserObject);
593
594     info->client_site = (IOleClientSite *)iOleClientSiteImpl;
595     info->wb_object = browserObject;
596
597     if (FAILED(hr)) goto error;
598
599     /* make the browser object accessible to the IOleClientSite implementation */
600     iOleClientSiteImpl->pBrowserObject = browserObject;
601
602     GetClientRect(hwndParent, &rc);
603
604     hr = OleSetContainedObject((struct IUnknown *)browserObject, TRUE);
605     if (FAILED(hr)) goto error;
606
607     hr = IOleObject_DoVerb(browserObject, OLEIVERB_SHOW, NULL,
608                            (IOleClientSite *)iOleClientSiteImpl,
609                            -1, hwndParent, &rc);
610     if (FAILED(hr)) goto error;
611
612     hr = IOleObject_QueryInterface(browserObject, &IID_IOleInPlaceObject, (void**)&inplace);
613     if (FAILED(hr)) goto error;
614
615     IOleInPlaceObject_SetObjectRects(inplace, &rc, &rc);
616     IOleInPlaceObject_Release(inplace);
617
618     hr = IOleObject_QueryInterface(browserObject, &IID_IWebBrowser2,
619                                    (void **)&webBrowser2);
620     if (SUCCEEDED(hr))
621     {
622         info->web_browser = webBrowser2;
623         return TRUE;
624     }
625
626 error:
627     ReleaseWebBrowser(info);
628     heap_free(iOleClientSiteImpl);
629
630     return FALSE;
631 }
632
633 void ReleaseWebBrowser(HHInfo *info)
634 {
635     HRESULT hres;
636
637     if (info->web_browser)
638     {
639         IWebBrowser2_Release(info->web_browser);
640         info->web_browser = NULL;
641     }
642
643     if (info->client_site)
644     {
645         IOleClientSite_Release(info->client_site);
646         info->client_site = NULL;
647     }
648
649     if(info->wb_object) {
650         IOleInPlaceSite *inplace;
651
652         hres = IOleObject_QueryInterface(info->wb_object, &IID_IOleInPlaceSite, (void**)&inplace);
653         if(SUCCEEDED(hres)) {
654             IOleInPlaceSite_OnInPlaceDeactivate(inplace);
655             IOleInPlaceSite_Release(inplace);
656         }
657
658         IOleObject_SetClientSite(info->wb_object, NULL);
659
660         IOleObject_Release(info->wb_object);
661         info->wb_object = NULL;
662     }
663 }
664
665 void ResizeWebBrowser(HHInfo *info, DWORD dwWidth, DWORD dwHeight)
666 {
667     if (!info->web_browser)
668         return;
669
670     IWebBrowser2_put_Width(info->web_browser, dwWidth);
671     IWebBrowser2_put_Height(info->web_browser, dwHeight);
672 }
673
674 void DoPageAction(HHInfo *info, DWORD dwAction)
675 {
676     IWebBrowser2 *pWebBrowser2 = info->web_browser;
677
678     if (!pWebBrowser2)
679         return;
680
681     switch (dwAction)
682     {
683         case WB_GOBACK:
684             IWebBrowser2_GoBack(pWebBrowser2);
685             break;
686         case WB_GOFORWARD:
687             IWebBrowser2_GoForward(pWebBrowser2);
688             break;
689         case WB_GOHOME:
690             IWebBrowser2_GoHome(pWebBrowser2);
691             break;
692         case WB_SEARCH:
693             IWebBrowser2_GoSearch(pWebBrowser2);
694             break;
695         case WB_REFRESH:
696             IWebBrowser2_Refresh(pWebBrowser2);
697         case WB_STOP:
698             IWebBrowser2_Stop(pWebBrowser2);
699     }
700 }