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