2 * WebBrowser Implementation
4 * Copyright 2005 James Hawkins
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "webbrowser.h"
33 #define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
35 static const SAFEARRAYBOUND ArrayBound
= {1, 0};
37 typedef struct IOleClientSiteImpl
39 const IOleClientSiteVtbl
*lpVtbl
;
40 const IOleInPlaceSiteVtbl
*lpvtblOleInPlaceSite
;
41 const IOleInPlaceFrameVtbl
*lpvtblOleInPlaceFrame
;
42 const IDocHostUIHandlerVtbl
*lpvtblDocHostUIHandler
;
44 /* IOleClientSiteImpl data */
45 IOleObject
*pBrowserObject
;
48 /* IOleInPlaceFrame data */
52 static HRESULT STDMETHODCALLTYPE
Site_QueryInterface(IOleClientSite
*iface
, REFIID riid
, void **ppvObj
)
54 ICOM_THIS_MULTI(IOleClientSiteImpl
, lpVtbl
, iface
);
57 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IOleClientSite
))
61 else if (IsEqualIID(riid
, &IID_IOleInPlaceSite
))
63 *ppvObj
= &(This
->lpvtblOleInPlaceSite
);
65 else if (IsEqualIID(riid
, &IID_IDocHostUIHandler
))
67 *ppvObj
= &(This
->lpvtblDocHostUIHandler
);
75 static ULONG STDMETHODCALLTYPE
Site_AddRef(IOleClientSite
*iface
)
77 ICOM_THIS_MULTI(IOleClientSiteImpl
, lpVtbl
, iface
);
78 return InterlockedIncrement(&This
->ref
);
81 static ULONG STDMETHODCALLTYPE
Site_Release(IOleClientSite
*iface
)
83 ICOM_THIS_MULTI(IOleClientSiteImpl
, lpVtbl
, iface
);
84 LONG refCount
= InterlockedDecrement(&This
->ref
);
89 HeapFree(GetProcessHeap(), 0, This
);
93 static HRESULT STDMETHODCALLTYPE
Site_SaveObject(IOleClientSite
*iface
)
98 static HRESULT STDMETHODCALLTYPE
Site_GetMoniker(IOleClientSite
*iface
, DWORD dwAssign
, DWORD dwWhichMoniker
, IMoniker
**ppmk
)
103 static HRESULT STDMETHODCALLTYPE
Site_GetContainer(IOleClientSite
*iface
, LPOLECONTAINER
*ppContainer
)
107 return E_NOINTERFACE
;
110 static HRESULT STDMETHODCALLTYPE
Site_ShowObject(IOleClientSite
*iface
)
115 static HRESULT STDMETHODCALLTYPE
Site_OnShowWindow(IOleClientSite
*iface
, BOOL fShow
)
120 static HRESULT STDMETHODCALLTYPE
Site_RequestNewObjectLayout(IOleClientSite
*iface
)
125 static const IOleClientSiteVtbl MyIOleClientSiteTable
=
135 Site_RequestNewObjectLayout
138 static HRESULT STDMETHODCALLTYPE
UI_QueryInterface(IDocHostUIHandler
*iface
, REFIID riid
, LPVOID
*ppvObj
)
140 ICOM_THIS_MULTI(IOleClientSiteImpl
, lpvtblDocHostUIHandler
, iface
);
141 return Site_QueryInterface((IOleClientSite
*)This
, riid
, ppvObj
);
144 static ULONG STDMETHODCALLTYPE
UI_AddRef(IDocHostUIHandler
*iface
)
149 static ULONG STDMETHODCALLTYPE
UI_Release(IDocHostUIHandler
* iface
)
154 static HRESULT STDMETHODCALLTYPE
UI_ShowContextMenu(IDocHostUIHandler
*iface
, DWORD dwID
, POINT
*ppt
, IUnknown
*pcmdtReserved
, IDispatch
*pdispReserved
)
159 static HRESULT STDMETHODCALLTYPE
UI_GetHostInfo(IDocHostUIHandler
*iface
, DOCHOSTUIINFO
*pInfo
)
161 pInfo
->cbSize
= sizeof(DOCHOSTUIINFO
);
162 pInfo
->dwFlags
= DOCHOSTUIFLAG_NO3DBORDER
;
163 pInfo
->dwDoubleClick
= DOCHOSTUIDBLCLK_DEFAULT
;
168 static HRESULT STDMETHODCALLTYPE
UI_ShowUI(IDocHostUIHandler
*iface
, DWORD dwID
, IOleInPlaceActiveObject
*pActiveObject
, IOleCommandTarget
*pCommandTarget
, IOleInPlaceFrame
*pFrame
, IOleInPlaceUIWindow
*pDoc
)
173 static HRESULT STDMETHODCALLTYPE
UI_HideUI(IDocHostUIHandler
*iface
)
178 static HRESULT STDMETHODCALLTYPE
UI_UpdateUI(IDocHostUIHandler
*iface
)
183 static HRESULT STDMETHODCALLTYPE
UI_EnableModeless(IDocHostUIHandler
*iface
, BOOL fEnable
)
188 static HRESULT STDMETHODCALLTYPE
UI_OnDocWindowActivate(IDocHostUIHandler
*iface
, BOOL fActivate
)
193 static HRESULT STDMETHODCALLTYPE
UI_OnFrameWindowActivate(IDocHostUIHandler
*iface
, BOOL fActivate
)
198 static HRESULT STDMETHODCALLTYPE
UI_ResizeBorder(IDocHostUIHandler
*iface
, LPCRECT prcBorder
, IOleInPlaceUIWindow
*pUIWindow
, BOOL fRameWindow
)
203 static HRESULT STDMETHODCALLTYPE
UI_TranslateAccelerator(IDocHostUIHandler
*iface
, LPMSG lpMsg
, const GUID
*pguidCmdGroup
, DWORD nCmdID
)
208 static HRESULT STDMETHODCALLTYPE
UI_GetOptionKeyPath(IDocHostUIHandler
*iface
, LPOLESTR
*pchKey
, DWORD dw
)
213 static HRESULT STDMETHODCALLTYPE
UI_GetDropTarget(IDocHostUIHandler
*iface
, IDropTarget
*pDropTarget
, IDropTarget
**ppDropTarget
)
218 static HRESULT STDMETHODCALLTYPE
UI_GetExternal(IDocHostUIHandler
*iface
, IDispatch
**ppDispatch
)
224 static HRESULT STDMETHODCALLTYPE
UI_TranslateUrl(IDocHostUIHandler
*iface
, DWORD dwTranslate
, OLECHAR
*pchURLIn
, OLECHAR
**ppchURLOut
)
230 static HRESULT STDMETHODCALLTYPE
UI_FilterDataObject(IDocHostUIHandler
*iface
, IDataObject
*pDO
, IDataObject
**ppDORet
)
236 static const IDocHostUIHandlerVtbl MyIDocHostUIHandlerTable
=
247 UI_OnDocWindowActivate
,
248 UI_OnFrameWindowActivate
,
250 UI_TranslateAccelerator
,
258 static HRESULT STDMETHODCALLTYPE
InPlace_QueryInterface(IOleInPlaceSite
*iface
, REFIID riid
, LPVOID
*ppvObj
)
260 ICOM_THIS_MULTI(IOleClientSiteImpl
, lpvtblOleInPlaceSite
, iface
);
261 return Site_QueryInterface((IOleClientSite
*)This
, riid
, ppvObj
);
264 static ULONG STDMETHODCALLTYPE
InPlace_AddRef(IOleInPlaceSite
*iface
)
269 static ULONG STDMETHODCALLTYPE
InPlace_Release(IOleInPlaceSite
*iface
)
274 static HRESULT STDMETHODCALLTYPE
InPlace_GetWindow(IOleInPlaceSite
*iface
, HWND
*lphwnd
)
276 ICOM_THIS_MULTI(IOleClientSiteImpl
, lpvtblOleInPlaceSite
, iface
);
277 *lphwnd
= This
->hwndWindow
;
282 static HRESULT STDMETHODCALLTYPE
InPlace_ContextSensitiveHelp(IOleInPlaceSite
*iface
, BOOL fEnterMode
)
287 static HRESULT STDMETHODCALLTYPE
InPlace_CanInPlaceActivate(IOleInPlaceSite
*iface
)
292 static HRESULT STDMETHODCALLTYPE
InPlace_OnInPlaceActivate(IOleInPlaceSite
*iface
)
297 static HRESULT STDMETHODCALLTYPE
InPlace_OnUIActivate(IOleInPlaceSite
*iface
)
302 static HRESULT STDMETHODCALLTYPE
InPlace_GetWindowContext(IOleInPlaceSite
*iface
, LPOLEINPLACEFRAME
*lplpFrame
, LPOLEINPLACEUIWINDOW
*lplpDoc
, LPRECT lprcPosRect
, LPRECT lprcClipRect
, LPOLEINPLACEFRAMEINFO lpFrameInfo
)
304 ICOM_THIS_MULTI(IOleClientSiteImpl
, lpvtblOleInPlaceSite
, iface
);
305 *lplpFrame
= (LPOLEINPLACEFRAME
)&This
->lpvtblOleInPlaceFrame
;
308 lpFrameInfo
->fMDIApp
= FALSE
;
309 lpFrameInfo
->hwndFrame
= This
->hwndWindow
;
310 lpFrameInfo
->haccel
= NULL
;
311 lpFrameInfo
->cAccelEntries
= 0;
316 static HRESULT STDMETHODCALLTYPE
InPlace_Scroll(IOleInPlaceSite
*iface
, SIZE scrollExtent
)
321 static HRESULT STDMETHODCALLTYPE
InPlace_OnUIDeactivate(IOleInPlaceSite
*iface
, BOOL fUndoable
)
326 static HRESULT STDMETHODCALLTYPE
InPlace_OnInPlaceDeactivate(IOleInPlaceSite
*iface
)
331 static HRESULT STDMETHODCALLTYPE
InPlace_DiscardUndoState(IOleInPlaceSite
*iface
)
336 static HRESULT STDMETHODCALLTYPE
InPlace_DeactivateAndUndo(IOleInPlaceSite
*iface
)
341 static HRESULT STDMETHODCALLTYPE
InPlace_OnPosRectChange(IOleInPlaceSite
*iface
, LPCRECT lprcPosRect
)
343 ICOM_THIS_MULTI(IOleClientSiteImpl
, lpvtblOleInPlaceSite
, iface
);
344 IOleInPlaceObject
*inplace
;
346 if (!IOleObject_QueryInterface(This
->pBrowserObject
, &IID_IOleInPlaceObject
, (void **)&inplace
))
347 IOleInPlaceObject_SetObjectRects(inplace
, lprcPosRect
, lprcPosRect
);
352 static const IOleInPlaceSiteVtbl MyIOleInPlaceSiteTable
=
354 InPlace_QueryInterface
,
358 InPlace_ContextSensitiveHelp
,
359 InPlace_CanInPlaceActivate
,
360 InPlace_OnInPlaceActivate
,
361 InPlace_OnUIActivate
,
362 InPlace_GetWindowContext
,
364 InPlace_OnUIDeactivate
,
365 InPlace_OnInPlaceDeactivate
,
366 InPlace_DiscardUndoState
,
367 InPlace_DeactivateAndUndo
,
368 InPlace_OnPosRectChange
371 static HRESULT STDMETHODCALLTYPE
Frame_QueryInterface(IOleInPlaceFrame
*iface
, REFIID riid
, LPVOID
*ppvObj
)
376 static ULONG STDMETHODCALLTYPE
Frame_AddRef(IOleInPlaceFrame
*iface
)
381 static ULONG STDMETHODCALLTYPE
Frame_Release(IOleInPlaceFrame
*iface
)
386 static HRESULT STDMETHODCALLTYPE
Frame_GetWindow(IOleInPlaceFrame
*iface
, HWND
*lphwnd
)
388 ICOM_THIS_MULTI(IOleClientSiteImpl
, lpvtblOleInPlaceFrame
, iface
);
389 *lphwnd
= This
->hwndWindow
;
394 static HRESULT STDMETHODCALLTYPE
Frame_ContextSensitiveHelp(IOleInPlaceFrame
*iface
, BOOL fEnterMode
)
399 static HRESULT STDMETHODCALLTYPE
Frame_GetBorder(IOleInPlaceFrame
*iface
, LPRECT lprectBorder
)
404 static HRESULT STDMETHODCALLTYPE
Frame_RequestBorderSpace(IOleInPlaceFrame
*iface
, LPCBORDERWIDTHS pborderwidths
)
409 static HRESULT STDMETHODCALLTYPE
Frame_SetBorderSpace(IOleInPlaceFrame
*iface
, LPCBORDERWIDTHS pborderwidths
)
414 static HRESULT STDMETHODCALLTYPE
Frame_SetActiveObject(IOleInPlaceFrame
*iface
, IOleInPlaceActiveObject
*pActiveObject
, LPCOLESTR pszObjName
)
419 static HRESULT STDMETHODCALLTYPE
Frame_InsertMenus(IOleInPlaceFrame
*iface
, HMENU hmenuShared
, LPOLEMENUGROUPWIDTHS lpMenuWidths
)
424 static HRESULT STDMETHODCALLTYPE
Frame_SetMenu(IOleInPlaceFrame
*iface
, HMENU hmenuShared
, HOLEMENU holemenu
, HWND hwndActiveObject
)
429 static HRESULT STDMETHODCALLTYPE
Frame_RemoveMenus(IOleInPlaceFrame
*iface
, HMENU hmenuShared
)
434 static HRESULT STDMETHODCALLTYPE
Frame_SetStatusText(IOleInPlaceFrame
*iface
, LPCOLESTR pszStatusText
)
439 static HRESULT STDMETHODCALLTYPE
Frame_EnableModeless(IOleInPlaceFrame
*iface
, BOOL fEnable
)
444 static HRESULT STDMETHODCALLTYPE
Frame_TranslateAccelerator(IOleInPlaceFrame
*iface
, LPMSG lpmsg
, WORD wID
)
449 static const IOleInPlaceFrameVtbl MyIOleInPlaceFrameTable
=
451 Frame_QueryInterface
,
455 Frame_ContextSensitiveHelp
,
457 Frame_RequestBorderSpace
,
458 Frame_SetBorderSpace
,
459 Frame_SetActiveObject
,
464 Frame_EnableModeless
,
465 Frame_TranslateAccelerator
468 static HRESULT STDMETHODCALLTYPE
Storage_QueryInterface(IStorage
*This
, REFIID riid
, LPVOID
*ppvObj
)
473 static ULONG STDMETHODCALLTYPE
Storage_AddRef(IStorage
*This
)
478 static ULONG STDMETHODCALLTYPE
Storage_Release(IStorage
*This
)
483 static HRESULT STDMETHODCALLTYPE
Storage_CreateStream(IStorage
*This
, const WCHAR
*pwcsName
, DWORD grfMode
, DWORD reserved1
, DWORD reserved2
, IStream
**ppstm
)
488 static HRESULT STDMETHODCALLTYPE
Storage_OpenStream(IStorage
*This
, const WCHAR
* pwcsName
, void *reserved1
, DWORD grfMode
, DWORD reserved2
, IStream
**ppstm
)
493 static HRESULT STDMETHODCALLTYPE
Storage_CreateStorage(IStorage
*This
, const WCHAR
*pwcsName
, DWORD grfMode
, DWORD reserved1
, DWORD reserved2
, IStorage
**ppstg
)
498 static HRESULT STDMETHODCALLTYPE
Storage_OpenStorage(IStorage
*This
, const WCHAR
* pwcsName
, IStorage
* pstgPriority
, DWORD grfMode
, SNB snbExclude
, DWORD reserved
, IStorage
**ppstg
)
503 static HRESULT STDMETHODCALLTYPE
Storage_CopyTo(IStorage
*This
, DWORD ciidExclude
, IID
const *rgiidExclude
, SNB snbExclude
,IStorage
*pstgDest
)
508 static HRESULT STDMETHODCALLTYPE
Storage_MoveElementTo(IStorage
*This
, const OLECHAR
*pwcsName
,IStorage
* pstgDest
, const OLECHAR
*pwcsNewName
, DWORD grfFlags
)
513 static HRESULT STDMETHODCALLTYPE
Storage_Commit(IStorage
*This
, DWORD grfCommitFlags
)
518 static HRESULT STDMETHODCALLTYPE
Storage_Revert(IStorage
*This
)
523 static HRESULT STDMETHODCALLTYPE
Storage_EnumElements(IStorage
*This
, DWORD reserved1
, void *reserved2
, DWORD reserved3
, IEnumSTATSTG
**ppenum
)
528 static HRESULT STDMETHODCALLTYPE
Storage_DestroyElement(IStorage
*This
, const OLECHAR
*pwcsName
)
533 static HRESULT STDMETHODCALLTYPE
Storage_RenameElement(IStorage
*This
, const WCHAR
*pwcsOldName
, const WCHAR
*pwcsNewName
)
538 static HRESULT STDMETHODCALLTYPE
Storage_SetElementTimes(IStorage
*This
, const WCHAR
*pwcsName
, FILETIME
const *pctime
, FILETIME
const *patime
, FILETIME
const *pmtime
)
543 static HRESULT STDMETHODCALLTYPE
Storage_SetClass(IStorage
*This
, REFCLSID clsid
)
548 static HRESULT STDMETHODCALLTYPE
Storage_SetStateBits(IStorage
*This
, DWORD grfStateBits
, DWORD grfMask
)
553 static HRESULT STDMETHODCALLTYPE
Storage_Stat(IStorage
*This
, STATSTG
*pstatstg
, DWORD grfStatFlag
)
558 static const IStorageVtbl MyIStorageTable
=
560 Storage_QueryInterface
,
563 Storage_CreateStream
,
565 Storage_CreateStorage
,
568 Storage_MoveElementTo
,
571 Storage_EnumElements
,
572 Storage_DestroyElement
,
573 Storage_RenameElement
,
574 Storage_SetElementTimes
,
576 Storage_SetStateBits
,
580 static IStorage MyIStorage
= { &MyIStorageTable
};
582 BOOL
WB_EmbedBrowser(WBInfo
*pWBInfo
, HWND hwndParent
)
584 IOleClientSiteImpl
*iOleClientSiteImpl
;
585 IOleObject
*browserObject
;
586 IWebBrowser2
*webBrowser2
;
590 static const WCHAR hostNameW
[] = {'H','o','s','t',' ','N','a','m','e',0};
592 /* clear out struct to keep from accessing invalid ptrs */
593 ZeroMemory(pWBInfo
, sizeof(WBInfo
));
595 iOleClientSiteImpl
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
596 sizeof(IOleClientSiteImpl
));
597 if (!iOleClientSiteImpl
)
600 iOleClientSiteImpl
->ref
= 0;
601 iOleClientSiteImpl
->lpVtbl
= &MyIOleClientSiteTable
;
602 iOleClientSiteImpl
->lpvtblOleInPlaceSite
= &MyIOleInPlaceSiteTable
;
603 iOleClientSiteImpl
->lpvtblOleInPlaceFrame
= &MyIOleInPlaceFrameTable
;
604 iOleClientSiteImpl
->hwndWindow
= hwndParent
;
605 iOleClientSiteImpl
->lpvtblDocHostUIHandler
= &MyIDocHostUIHandlerTable
;
607 hr
= OleCreate(&CLSID_WebBrowser
, &IID_IOleObject
, OLERENDER_DRAW
, 0,
608 (IOleClientSite
*)iOleClientSiteImpl
, &MyIStorage
,
609 (void **)&browserObject
);
611 pWBInfo
->pOleClientSite
= (IOleClientSite
*)iOleClientSiteImpl
;
612 pWBInfo
->pBrowserObject
= browserObject
;
614 if (FAILED(hr
)) goto error
;
616 /* make the browser object accessible to the IOleClientSite implementation */
617 iOleClientSiteImpl
->pBrowserObject
= browserObject
;
618 IOleObject_SetHostNames(browserObject
, hostNameW
, 0);
620 GetClientRect(hwndParent
, &rc
);
622 hr
= OleSetContainedObject((struct IUnknown
*)browserObject
, TRUE
);
623 if (FAILED(hr
)) goto error
;
625 hr
= IOleObject_DoVerb(browserObject
, OLEIVERB_SHOW
, NULL
,
626 (IOleClientSite
*)iOleClientSiteImpl
,
627 -1, hwndParent
, &rc
);
628 if (FAILED(hr
)) goto error
;
631 hr
= IOleObject_QueryInterface(browserObject
, &IID_IWebBrowser2
,
632 (void **)&webBrowser2
);
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
);
640 pWBInfo
->pWebBrowser2
= webBrowser2
;
641 pWBInfo
->hwndParent
= hwndParent
;
647 WB_UnEmbedBrowser(pWBInfo
);
648 HeapFree(GetProcessHeap(), 0, iOleClientSiteImpl
);
653 void WB_UnEmbedBrowser(WBInfo
*pWBInfo
)
655 if (pWBInfo
->pBrowserObject
)
657 IOleObject_Close(pWBInfo
->pBrowserObject
, OLECLOSE_NOSAVE
);
658 IOleObject_Release(pWBInfo
->pBrowserObject
);
659 pWBInfo
->pBrowserObject
= NULL
;
662 if (pWBInfo
->pWebBrowser2
)
664 IWebBrowser2_Release(pWBInfo
->pWebBrowser2
);
665 pWBInfo
->pWebBrowser2
= NULL
;
668 if (pWBInfo
->pOleClientSite
)
670 IOleClientSite_Release(pWBInfo
->pOleClientSite
);
671 pWBInfo
->pOleClientSite
= NULL
;
675 BOOL
WB_Navigate(WBInfo
*pWBInfo
, LPCWSTR szUrl
)
677 IWebBrowser2
*pWebBrowser2
= pWBInfo
->pWebBrowser2
;
683 V_VT(&myURL
) = VT_BSTR
;
684 V_BSTR(&myURL
) = SysAllocString(szUrl
);
686 IWebBrowser2_Navigate2(pWebBrowser2
, &myURL
, 0, 0, 0, 0);
687 VariantClear(&myURL
);
692 void WB_ResizeBrowser(WBInfo
*pWBInfo
, DWORD dwWidth
, DWORD dwHeight
)
694 IWebBrowser2
*pWebBrowser2
= pWBInfo
->pWebBrowser2
;
699 IWebBrowser2_put_Width(pWebBrowser2
, dwWidth
);
700 IWebBrowser2_put_Height(pWebBrowser2
, dwHeight
);
703 void WB_DoPageAction(WBInfo
*pWBInfo
, DWORD dwAction
)
705 IWebBrowser2
*pWebBrowser2
= pWBInfo
->pWebBrowser2
;
713 IWebBrowser2_GoBack(pWebBrowser2
);
716 IWebBrowser2_GoForward(pWebBrowser2
);
719 IWebBrowser2_GoHome(pWebBrowser2
);
722 IWebBrowser2_GoSearch(pWebBrowser2
);
725 IWebBrowser2_Refresh(pWebBrowser2
);
727 IWebBrowser2_Stop(pWebBrowser2
);