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