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