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