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