From 5d29a2df6395204991b5df1c6bc5470615814064 Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=A9=20van=20Geldorp?= Date: Sun, 20 Nov 2005 14:26:47 +0000 Subject: [PATCH] Sync to Wine-0_9_1: Michael Jung - Support for shell instance objects. Removed a wine_todo for a no longer failing test. Added a test for IPersistFolder3::GetCurFolder. - Added initial tests for shdocvw's FolderShortcut related functionality. - Only return SHDOCVW_ClassFactory if asked for CLSID_WebBrowser. svn path=/trunk/; revision=19363 --- reactos/include/wine/objidl.h | 30 ++ reactos/lib/shdocvw/Ko.rc | 36 +++ reactos/lib/shdocvw/Makefile.in | 26 -- reactos/lib/shdocvw/client.c | 258 ++++++++++++++++++ reactos/lib/shdocvw/oleobject.c | 76 +++++- reactos/lib/shdocvw/shdocvw.h | 36 +++ reactos/lib/shdocvw/shdocvw.rc | 1 + reactos/lib/shdocvw/shdocvw.xml | 4 + reactos/lib/shdocvw/shdocvw_main.c | 6 +- reactos/lib/shdocvw/shlinstobj.c | 421 +++++++++++++++++++++++++++++ reactos/lib/shdocvw/view.c | 124 +++++++++ reactos/lib/shdocvw/webbrowser.c | 87 +++++- reactos/lib/uuid/uuid.c | 2 + reactos/w32api/include/mshtml.h | 1 + reactos/w32api/include/oleidl.h | 48 ++++ 15 files changed, 1115 insertions(+), 41 deletions(-) create mode 100644 reactos/lib/shdocvw/Ko.rc delete mode 100644 reactos/lib/shdocvw/Makefile.in create mode 100644 reactos/lib/shdocvw/client.c create mode 100644 reactos/lib/shdocvw/shlinstobj.c create mode 100644 reactos/lib/shdocvw/view.c diff --git a/reactos/include/wine/objidl.h b/reactos/include/wine/objidl.h index 7f2fe249a0d..985fb3203a6 100644 --- a/reactos/include/wine/objidl.h +++ b/reactos/include/wine/objidl.h @@ -643,6 +643,36 @@ DECLARE_INTERFACE_(IMoniker,IPersistStream) }; #undef INTERFACE +#ifdef COBJMACROS +/*** IUnknown methods ***/ +#define IMoniker_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IMoniker_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IMoniker_Release(p) (p)->lpVtbl->Release(p) +/*** IPersist methods ***/ +#define IMoniker_GetClassID(p,a) (p)->lpVtbl->GetClassID(p,a) +/*** IPersistStream methods ***/ +#define IMoniker_IsDirty(p) (p)->lpVtbl->IsDirty(p) +#define IMoniker_Load(p,a) (p)->lpVtbl->Load(p,a) +#define IMoniker_Save(p,a,b) (p)->lpVtbl->Save(p,a,b) +#define IMoniker_GetSizeMax(p,a) (p)->lpVtbl->GetSizeMax(p,a) +/*** IMoniker methods ***/ +#define IMoniker_BindToObject(p,a,b,c,d) (p)->lpVtbl->BindToObject(p,a,b,c,d) +#define IMoniker_BindToStorage(p,a,b,c,d) (p)->lpVtbl->BindToStorage(p,a,b,c,d) +#define IMoniker_Reduce(p,a,b,c,d) (p)->lpVtbl->Reduce(p,a,b,c,d) +#define IMoniker_ComposeWith(p,a,b,c) (p)->lpVtbl->ComposeWith(p,a,b,c) +#define IMoniker_Enum(p,a,b) (p)->lpVtbl->Enum(p,a,b) +#define IMoniker_IsEqual(p,a) (p)->lpVtbl->IsEqual(p,a) +#define IMoniker_Hash(p,a) (p)->lpVtbl->Hash(p,a) +#define IMoniker_IsRunning(p,a,b,c) (p)->lpVtbl->IsRunning(p,a,b,c) +#define IMoniker_GetTimeOfLastChange(p,a,b,c) (p)->lpVtbl->GetTimeOfLastChange(p,a,b,c) +#define IMoniker_Inverse(p,a) (p)->lpVtbl->Inverse(p,a) +#define IMoniker_CommonPrefixWith(p,a,b) (p)->lpVtbl->CommonPrefixWith(p,a,b) +#define IMoniker_RelativePathTo(p,a,b) (p)->lpVtbl->RelativePathTo(p,a,b) +#define IMoniker_GetDisplayName(p,a,b,c) (p)->lpVtbl->GetDisplayName(p,a,b,c) +#define IMoniker_ParseDisplayName(p,a,b,c,d,e) (p)->lpVtbl->ParseDisplayName(p,a,b,c,d,e) +#define IMoniker_IsSystemMoniker(p,a) (p)->lpVtbl->IsSystemMoniker(p,a) +#endif + EXTERN_C const IID IID_IPersistStorage; #define INTERFACE IPersistStorage DECLARE_INTERFACE_(IPersistStorage,IPersist) diff --git a/reactos/lib/shdocvw/Ko.rc b/reactos/lib/shdocvw/Ko.rc new file mode 100644 index 00000000000..4929bc10037 --- /dev/null +++ b/reactos/lib/shdocvw/Ko.rc @@ -0,0 +1,36 @@ +/* + * Copyright 2005 YunSong Hwang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT + +100 DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 220, 62 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "¸ðÁú¶ó ¾×Ƽºê ¿¢½º ÄÁÆ®·Ñ ´Ù¿î·ÎµåÁß" +FONT 8, "MS Shell Dlg" +{ + CONTROL "Progress1",1000,"msctls_progress32",WS_BORDER|PBS_SMOOTH,10,10,200,12 + LTEXT "", 104, 10, 30, 200, 10, SS_CENTER + PUSHBUTTON "Ãë¼Ò", IDCANCEL, 85, 44, 50, 15, WS_GROUP | WS_TABSTOP +} + +STRINGTABLE +BEGIN + 1001 "This application is requesting an ActiveX browser object\n" \ + "but the Mozilla Active X control is currently not installed." \ + "Do you wish to download and install it?" +END diff --git a/reactos/lib/shdocvw/Makefile.in b/reactos/lib/shdocvw/Makefile.in deleted file mode 100644 index a0135b6ddcd..00000000000 --- a/reactos/lib/shdocvw/Makefile.in +++ /dev/null @@ -1,26 +0,0 @@ -EXTRADEFS = -D_SHDOCVW_ -TOPSRCDIR = @top_srcdir@ -TOPOBJDIR = ../.. -SRCDIR = @srcdir@ -VPATH = @srcdir@ -MODULE = shdocvw.dll -IMPORTLIB = libshdocvw.$(IMPLIBEXT) -IMPORTS = urlmon ole32 user32 advapi32 kernel32 -EXTRALIBS = -luuid - -C_SRCS = \ - classinfo.c \ - events.c \ - factory.c \ - misc.c \ - oleobject.c \ - persist.c \ - regsvr.c \ - shdocvw_main.c \ - webbrowser.c - -RC_SRCS = shdocvw.rc - -@MAKE_DLL_RULES@ - -### Dependencies: diff --git a/reactos/lib/shdocvw/client.c b/reactos/lib/shdocvw/client.c new file mode 100644 index 00000000000..bf8e768e6b5 --- /dev/null +++ b/reactos/lib/shdocvw/client.c @@ -0,0 +1,258 @@ +/* + * Copyright 2005 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define COBJMACROS +#include "wine/debug.h" +#include "shdocvw.h" + +WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); + +#define CLIENTSITE_THIS(iface) DEFINE_THIS(WebBrowser, OleClientSite, iface) + +static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv) +{ + WebBrowser *This = CLIENTSITE_THIS(iface); + + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = CLIENTSITE(This); + }else if(IsEqualGUID(&IID_IOleClientSite, riid)) { + TRACE("(%p)->(IID_IOleClientSite %p)\n", This, ppv); + *ppv = CLIENTSITE(This); + }else if(IsEqualGUID(&IID_IOleWindow, riid)) { + TRACE("(%p)->(IID_IOleWindow %p)\n", This, ppv); + *ppv = INPLACESITE(This); + }else if(IsEqualGUID(&IID_IOleInPlaceSite, riid)) { + TRACE("(%p)->(IID_IOleInPlaceSite %p)\n", This, ppv); + *ppv = INPLACESITE(This); + } + + if(*ppv) { + IWebBrowser2_AddRef(WEBBROWSER(This)); + return S_OK; + } + + WARN("Unsupported intrface %s\n", debugstr_guid(riid)); + + return E_NOINTERFACE; +} + +static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface) +{ + WebBrowser *This = CLIENTSITE_THIS(iface); + return IWebBrowser2_AddRef(WEBBROWSER(This)); +} + +static ULONG WINAPI ClientSite_Release(IOleClientSite *iface) +{ + WebBrowser *This = CLIENTSITE_THIS(iface); + return IWebBrowser2_Release(WEBBROWSER(This)); +} + +static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface) +{ + WebBrowser *This = CLIENTSITE_THIS(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, + DWORD dwWhichMoniker, IMoniker **ppmk) +{ + WebBrowser *This = CLIENTSITE_THIS(iface); + FIXME("(%p)->(%ld %ld %p)\n", This, dwAssign, dwWhichMoniker, ppmk); + return E_NOTIMPL; +} + +static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer) +{ + WebBrowser *This = CLIENTSITE_THIS(iface); + FIXME("(%p)->(%p)\n", This, ppContainer); + return E_NOTIMPL; +} + +static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface) +{ + WebBrowser *This = CLIENTSITE_THIS(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow) +{ + WebBrowser *This = CLIENTSITE_THIS(iface); + FIXME("(%p)->(%x)\n", This, fShow); + return E_NOTIMPL; +} + +static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface) +{ + WebBrowser *This = CLIENTSITE_THIS(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +#undef CLIENTSITE_THIS + +static const IOleClientSiteVtbl OleClientSiteVtbl = { + ClientSite_QueryInterface, + ClientSite_AddRef, + ClientSite_Release, + ClientSite_SaveObject, + ClientSite_GetMoniker, + ClientSite_GetContainer, + ClientSite_ShowObject, + ClientSite_OnShowWindow, + ClientSite_RequestNewObjectLayout +}; + +#define INPLACESITE_THIS(iface) DEFINE_THIS(WebBrowser, OleInPlaceSite, iface) + +static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppv) +{ + WebBrowser *This = INPLACESITE_THIS(iface); + return IOleClientSite_QueryInterface(CLIENTSITE(This), riid, ppv); +} + +static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSite *iface) +{ + WebBrowser *This = INPLACESITE_THIS(iface); + return IOleClientSite_AddRef(CLIENTSITE(This)); +} + +static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSite *iface) +{ + WebBrowser *This = INPLACESITE_THIS(iface); + return IOleClientSite_Release(CLIENTSITE(This)); +} + +static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSite *iface, HWND *phwnd) +{ + WebBrowser *This = INPLACESITE_THIS(iface); + FIXME("(%p)->(%p)\n", This, phwnd); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode) +{ + WebBrowser *This = INPLACESITE_THIS(iface); + FIXME("(%p)->(%x)\n", This, fEnterMode); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSite *iface) +{ + WebBrowser *This = INPLACESITE_THIS(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSite *iface) +{ + WebBrowser *This = INPLACESITE_THIS(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSite *iface) +{ + WebBrowser *This = INPLACESITE_THIS(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSite *iface, + IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect, + LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo) +{ + WebBrowser *This = INPLACESITE_THIS(iface); + FIXME("(%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, + lprcClipRect, lpFrameInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSite *iface, SIZE scrollExtent) +{ + WebBrowser *This = INPLACESITE_THIS(iface); + FIXME("(%p)->({%ld %ld})\n", This, scrollExtent.cx, scrollExtent.cy); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable) +{ + WebBrowser *This = INPLACESITE_THIS(iface); + FIXME("(%p)->(%x)\n", This, fUndoable); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSite *iface) +{ + WebBrowser *This = INPLACESITE_THIS(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSite *iface) +{ + WebBrowser *This = INPLACESITE_THIS(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSite *iface) +{ + WebBrowser *This = INPLACESITE_THIS(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSite *iface, + LPCRECT lprcPosRect) +{ + WebBrowser *This = INPLACESITE_THIS(iface); + FIXME("(%p)->(%p)\n", This, lprcPosRect); + return E_NOTIMPL; +} + +#undef INPLACESITE_THIS + +static const IOleInPlaceSiteVtbl OleInPlaceSiteVtbl = { + InPlaceSite_QueryInterface, + InPlaceSite_AddRef, + InPlaceSite_Release, + InPlaceSite_GetWindow, + InPlaceSite_ContextSensitiveHelp, + InPlaceSite_CanInPlaceActivate, + InPlaceSite_OnInPlaceActivate, + InPlaceSite_OnUIActivate, + InPlaceSite_GetWindowContext, + InPlaceSite_Scroll, + InPlaceSite_OnUIDeactivate, + InPlaceSite_OnInPlaceDeactivate, + InPlaceSite_DiscardUndoState, + InPlaceSite_DeactivateAndUndo, + InPlaceSite_OnPosRectChange +}; + +void WebBrowser_ClientSite_Init(WebBrowser *This) +{ + This->lpOleClientSiteVtbl = &OleClientSiteVtbl; + This->lpOleInPlaceSiteVtbl = &OleInPlaceSiteVtbl; +} diff --git a/reactos/lib/shdocvw/oleobject.c b/reactos/lib/shdocvw/oleobject.c index 90804a7948a..a36588509c8 100644 --- a/reactos/lib/shdocvw/oleobject.c +++ b/reactos/lib/shdocvw/oleobject.c @@ -139,15 +139,58 @@ static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, struct tag LPOLECLIENTSITE pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect) { WebBrowser *This = OLEOBJ_THIS(iface); - FIXME("(%p)->(%ld %p %p %ld %p %p)\n", This, iVerb, lpmsg, pActiveSite, lindex, hwndParent, + HRESULT hres; + + TRACE("(%p)->(%ld %p %p %ld %p %p)\n", This, iVerb, lpmsg, pActiveSite, lindex, hwndParent, lprcPosRect); + switch (iVerb) { - case OLEIVERB_INPLACEACTIVATE: - FIXME ("stub for OLEIVERB_INPLACEACTIVATE\n"); - break; - case OLEIVERB_HIDE: - FIXME ("stub for OLEIVERB_HIDE\n"); + case OLEIVERB_INPLACEACTIVATE: { + IOleInPlaceSite *inplace; + + TRACE("OLEIVERB_INPLACEACTIVATE\n"); + + if(!pActiveSite) + return E_INVALIDARG; + + hres = IOleClientSite_QueryInterface(pActiveSite, &IID_IOleInPlaceSite, (void**)&inplace); + if(FAILED(hres)) { + WARN("Could not get IOleInPlaceSite\n"); + return hres; + } + + hres = IOleInPlaceSite_CanInPlaceActivate(inplace); + if(hres != S_OK) { + WARN("CanInPlaceActivate returned: %08lx\n", hres); + IOleInPlaceSite_Release(inplace); + return E_FAIL; + } + + hres = IOleInPlaceSite_GetWindow(inplace, &This->iphwnd); + if(FAILED(hres)) + This->iphwnd = hwndParent; + + IOleInPlaceSite_OnInPlaceActivate(inplace); + + IOleInPlaceSite_GetWindowContext(inplace, &This->frame, &This->uiwindow, + &This->pos_rect, &This->clip_rect, + &This->frameinfo); + + IOleInPlaceSite_Release(inplace); + + if(This->client) { + IOleClientSite_ShowObject(This->client); + IOleClientSite_GetContainer(This->client, &This->container); + } + + if(This->frame) + IOleInPlaceFrame_GetWindow(This->frame, &This->frame_hwnd); + + return S_OK; + } + default: + FIXME("stub for %ld\n", iVerb); break; } @@ -451,4 +494,25 @@ void WebBrowser_OleObject_Init(WebBrowser *This) This->lpOleControlVtbl = &OleControlVtbl; This->client = NULL; + This->container = NULL; + This->iphwnd = NULL; + This->frame_hwnd = NULL; + This->frame = NULL; + This->uiwindow = NULL; + + memset(&This->pos_rect, 0, sizeof(RECT)); + memset(&This->clip_rect, 0, sizeof(RECT)); + memset(&This->frameinfo, 0, sizeof(OLEINPLACEFRAMEINFO)); +} + +void WebBrowser_OleObject_Destroy(WebBrowser *This) +{ + if(This->client) + IOleClientSite_Release(This->client); + if(This->container) + IOleContainer_Release(This->container); + if(This->frame) + IOleInPlaceFrame_Release(This->frame); + if(This->uiwindow) + IOleInPlaceUIWindow_Release(This->uiwindow); } diff --git a/reactos/lib/shdocvw/shdocvw.h b/reactos/lib/shdocvw/shdocvw.h index 19d40fb7aa1..f30fa7dd4ca 100644 --- a/reactos/lib/shdocvw/shdocvw.h +++ b/reactos/lib/shdocvw/shdocvw.h @@ -48,11 +48,18 @@ typedef struct extern IClassFactoryImpl SHDOCVW_ClassFactory; +/********************************************************************** + * Shell Instance Objects + */ +extern HRESULT SHDOCVW_GetShellInstanceObjectClassObject(REFCLSID rclsid, + REFIID riid, LPVOID *ppvClassObj); /********************************************************************** * WebBrowser declaration for SHDOCVW.DLL */ typedef struct { + /* Interfaces available via WebBrowser object */ + const IWebBrowser2Vtbl *lpWebBrowser2Vtbl; const IOleObjectVtbl *lpOleObjectVtbl; const IOleInPlaceObjectVtbl *lpOleInPlaceObjectVtbl; @@ -62,10 +69,29 @@ typedef struct { const IProvideClassInfo2Vtbl *lpProvideClassInfoVtbl; const IQuickActivateVtbl *lpQuickActivateVtbl; const IConnectionPointContainerVtbl *lpConnectionPointContainerVtbl; + const IViewObject2Vtbl *lpViewObjectVtbl; + + /* Interfaces available for embeded document */ + + const IOleClientSiteVtbl *lpOleClientSiteVtbl; + const IOleInPlaceSiteVtbl *lpOleInPlaceSiteVtbl; LONG ref; + IUnknown *document; + IOleClientSite *client; + IOleContainer *container; + + /* window context */ + + HWND iphwnd; + HWND frame_hwnd; + IOleInPlaceFrame *frame; + IOleInPlaceUIWindow *uiwindow; + RECT pos_rect; + RECT clip_rect; + OLEINPLACEFRAMEINFO frameinfo; } WebBrowser; #define WEBBROWSER(x) ((IWebBrowser*) &(x)->lpWebBrowser2Vtbl) @@ -78,13 +104,23 @@ typedef struct { #define CLASSINFO(x) ((IProvideClassInfo2*) &(x)->lpProvideClassInfoVtbl) #define QUICKACT(x) ((IQuickActivate*) &(x)->lpQuickActivateVtbl) #define CONPTCONT(x) ((IConnectionPointContainer*) &(x)->lpConnectionPointContainerVtbl) +#define VIEWOBJ(x) ((IViewObject*) &(x)->lpViewObjectVtbl); +#define VIEWOBJ2(x) ((IViewObject2*) &(x)->lpViewObjectVtbl); + +#define CLIENTSITE(x) ((IOleClientSite*) &(x)->lpOleClientSiteVtbl) +#define INPLACESITE(x) ((IOleInPlaceSite*) &(x)->lpOleInPlaceSiteVtbl) void WebBrowser_OleObject_Init(WebBrowser*); +void WebBrowser_ViewObject_Init(WebBrowser*); void WebBrowser_Persist_Init(WebBrowser*); void WebBrowser_ClassInfo_Init(WebBrowser*); void WebBrowser_Misc_Init(WebBrowser*); void WebBrowser_Events_Init(WebBrowser*); +void WebBrowser_ClientSite_Init(WebBrowser*); + +void WebBrowser_OleObject_Destroy(WebBrowser*); + HRESULT WebBrowser_Create(IUnknown*,REFIID,void**); /********************************************************************** diff --git a/reactos/lib/shdocvw/shdocvw.rc b/reactos/lib/shdocvw/shdocvw.rc index 91c25edbd82..40c4c965381 100644 --- a/reactos/lib/shdocvw/shdocvw.rc +++ b/reactos/lib/shdocvw/shdocvw.rc @@ -30,6 +30,7 @@ #include "Fi.rc" #include "Fr.rc" #include "Ja.rc" +#include "Ko.rc" #include "Nl.rc" #include "No.rc" #include "Pl.rc" diff --git a/reactos/lib/shdocvw/shdocvw.xml b/reactos/lib/shdocvw/shdocvw.xml index 2ef54301891..1332caf91d2 100644 --- a/reactos/lib/shdocvw/shdocvw.xml +++ b/reactos/lib/shdocvw/shdocvw.xml @@ -15,8 +15,10 @@ advapi32 user32 ole32 + oleaut32 urlmon classinfo.c + client.c events.c factory.c misc.c @@ -24,6 +26,8 @@ persist.c regsvr.c shdocvw_main.c + shlinstobj.c + view.c webbrowser.c shdocvw.rc shdocvw.spec diff --git a/reactos/lib/shdocvw/shdocvw_main.c b/reactos/lib/shdocvw/shdocvw_main.c index a746e0556a6..4df0ead11b1 100644 --- a/reactos/lib/shdocvw/shdocvw_main.c +++ b/reactos/lib/shdocvw/shdocvw_main.c @@ -480,7 +480,8 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) return r; } - if (IsEqualGUID(&IID_IClassFactory, riid)) + if (IsEqualCLSID(&CLSID_WebBrowser, rclsid) && + IsEqualIID(&IID_IClassFactory, riid)) { /* Pass back our shdocvw class factory */ *ppv = (LPVOID)&SHDOCVW_ClassFactory; @@ -489,7 +490,8 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) return S_OK; } - return CLASS_E_CLASSNOTAVAILABLE; + /* As a last resort, figure if the CLSID belongs to a 'Shell Instance Object' */ + return SHDOCVW_GetShellInstanceObjectClassObject(rclsid, riid, ppv); } /*********************************************************************** diff --git a/reactos/lib/shdocvw/shlinstobj.c b/reactos/lib/shdocvw/shlinstobj.c new file mode 100644 index 00000000000..19ba3b84fae --- /dev/null +++ b/reactos/lib/shdocvw/shlinstobj.c @@ -0,0 +1,421 @@ +/* + * Shell Instance Objects - Add hot water and stir until dissolved. + * + * Copyright 2005 Michael Jung + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* 'Shell Instance Objects' allow you to add a node to the shell namespace + * (typically a shortcut to some location in the filesystem), just by setting + * some registry entries. This feature was introduced with win2k. Please + * search for 'Shell Instance Objects' on MSDN to get more information. */ + +#include + +#define COBJMACROS +#define COM_NO_WINDOWS_H + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "objbase.h" +#include "oleauto.h" + +#include "shdocvw.h" + +#include "wine/unicode.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); + +#define ADJUST_THIS(c,m,p) ((c*)(((long)p)-(long)&(((c*)0)->lp##m##Vtbl))) +#define STATIC_CAST(i,p) ((i*)&p->lp##i##Vtbl) +#define CHARS_IN_GUID 39 + +/****************************************************************************** + * RegistryPropertyBag + * + * Gives access to a registry key's values via the IPropertyBag interface. + */ +typedef struct _RegistryPropertyBag { + const IPropertyBagVtbl *lpIPropertyBagVtbl; + LONG m_cRef; + HKEY m_hInitPropertyBagKey; +} RegistryPropertyBag; + +static void RegistryPropertyBag_Destroy(RegistryPropertyBag *This) { + TRACE("This=%p)\n", This); + + RegCloseKey(This->m_hInitPropertyBagKey); + HeapFree(GetProcessHeap(), 0, This); +} + +static HRESULT WINAPI RegistryPropertyBag_IPropertyBag_QueryInterface(IPropertyBag *iface, + REFIID riid, void **ppv) +{ + RegistryPropertyBag *This = ADJUST_THIS(RegistryPropertyBag, IPropertyBag, iface); + + TRACE("(iface=%p, riid=%s, ppv=%p)\n", iface, debugstr_guid(riid), ppv); + + if (!ppv) + return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IPropertyBag, riid)) { + *ppv = STATIC_CAST(IPropertyBag, This); + } else { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI RegistryPropertyBag_IPropertyBag_AddRef(IPropertyBag *iface) { + RegistryPropertyBag *This = ADJUST_THIS(RegistryPropertyBag, IPropertyBag, iface); + ULONG cRef; + + TRACE("(iface=%p)\n", iface); + + cRef = InterlockedIncrement(&This->m_cRef); + + if (cRef == 1) + SHDOCVW_LockModule(); + + return cRef; +} + +static ULONG WINAPI RegistryPropertyBag_IPropertyBag_Release(IPropertyBag *iface) { + RegistryPropertyBag *This = ADJUST_THIS(RegistryPropertyBag, IPropertyBag, iface); + ULONG cRef; + + TRACE("(iface=%p)\n", iface); + + cRef = InterlockedDecrement(&This->m_cRef); + + if (cRef == 0) { + RegistryPropertyBag_Destroy(This); + SHDOCVW_UnlockModule(); + } + + return cRef; +} + +static HRESULT WINAPI RegistryPropertyBag_IPropertyBag_Read(IPropertyBag *iface, + LPCOLESTR pwszPropName, VARIANT *pVar, IErrorLog *pErrorLog) +{ + RegistryPropertyBag *This = ADJUST_THIS(RegistryPropertyBag, IPropertyBag, iface); + WCHAR *pwszValue; + DWORD dwType, cbData; + LONG res; + VARTYPE vtDst = V_VT(pVar); + HRESULT hr = S_OK; + + TRACE("(iface=%p, pwszPropName=%s, pVar=%p, pErrorLog=%p)\n", iface, debugstr_w(pwszPropName), + pVar, pErrorLog); + + res = RegQueryValueExW(This->m_hInitPropertyBagKey, pwszPropName, NULL, &dwType, NULL, &cbData); + if (res != ERROR_SUCCESS) + return E_INVALIDARG; + + pwszValue = HeapAlloc(GetProcessHeap(), 0, cbData); + if (!pwszValue) + return E_OUTOFMEMORY; + + res = RegQueryValueExW(This->m_hInitPropertyBagKey, pwszPropName, NULL, &dwType, + (LPBYTE)pwszValue, &cbData); + if (res != ERROR_SUCCESS) { + HeapFree(GetProcessHeap(), 0, pwszValue); + return E_INVALIDARG; + } + + V_VT(pVar) = VT_BSTR; + V_BSTR(pVar) = SysAllocString(pwszValue); + HeapFree(GetProcessHeap(), 0, pwszValue); + + if (vtDst != VT_BSTR) { + hr = VariantChangeTypeEx(pVar, pVar, LOCALE_SYSTEM_DEFAULT, 0, vtDst); + if (FAILED(hr)) + SysFreeString(V_BSTR(pVar)); + } + + return hr; +} + +static HRESULT WINAPI RegistryPropertyBag_IPropertyBag_Write(IPropertyBag *iface, + LPCOLESTR pwszPropName, VARIANT *pVar) +{ + FIXME("(iface=%p, pwszPropName=%s, pVar=%p) stub\n", iface, debugstr_w(pwszPropName), pVar); + return E_NOTIMPL; +} + +static const IPropertyBagVtbl RegistryPropertyBag_IPropertyBagVtbl = { + RegistryPropertyBag_IPropertyBag_QueryInterface, + RegistryPropertyBag_IPropertyBag_AddRef, + RegistryPropertyBag_IPropertyBag_Release, + RegistryPropertyBag_IPropertyBag_Read, + RegistryPropertyBag_IPropertyBag_Write +}; + +HRESULT RegistryPropertyBag_Constructor(HKEY hInitPropertyBagKey, REFIID riid, LPVOID *ppvObject) { + HRESULT hr = E_FAIL; + RegistryPropertyBag *pRegistryPropertyBag; + + TRACE("(hInitPropertyBagKey=%p, riid=%s, ppvObject=%p)\n", hInitPropertyBagKey, + debugstr_guid(riid), ppvObject); + + pRegistryPropertyBag = HeapAlloc(GetProcessHeap(), 0, sizeof(RegistryPropertyBag)); + if (pRegistryPropertyBag) { + pRegistryPropertyBag->lpIPropertyBagVtbl = &RegistryPropertyBag_IPropertyBagVtbl; + pRegistryPropertyBag->m_cRef = 0; + pRegistryPropertyBag->m_hInitPropertyBagKey = hInitPropertyBagKey; + + /* The clasping AddRef/Release is for the case that QueryInterface fails, which will result + * in a reference count of 0 in the Release call, which will result in object destruction.*/ + IPropertyBag_AddRef(STATIC_CAST(IPropertyBag, pRegistryPropertyBag)); + hr = IPropertyBag_QueryInterface(STATIC_CAST(IPropertyBag, pRegistryPropertyBag), riid, ppvObject); + IPropertyBag_Release(STATIC_CAST(IPropertyBag, pRegistryPropertyBag)); + } + + return hr; +} + +/****************************************************************************** + * InstanceObjectFactory + * Builds Instance Objects and asks them to initialize themselves based on the + * values of a PropertyBag. + */ +typedef struct _InstanceObjectFactory { + const IClassFactoryVtbl *lpIClassFactoryVtbl; + LONG m_cRef; + CLSID m_clsidInstance; /* CLSID of the objects to create. */ + IPropertyBag *m_pPropertyBag; /* PropertyBag to initialize those objects. */ +} InstanceObjectFactory; + +static void InstanceObjectFactory_Destroy(InstanceObjectFactory *This) { + IPropertyBag_Release(This->m_pPropertyBag); + HeapFree(GetProcessHeap(), 0, This); +} + +static HRESULT WINAPI InstanceObjectFactory_IClassFactory_QueryInterface(IClassFactory *iface, + REFIID riid, LPVOID* ppv) +{ + InstanceObjectFactory *This = ADJUST_THIS(InstanceObjectFactory, IClassFactory, iface); + + TRACE("iface=%p, riid=%s, ppv=%p)\n", iface, debugstr_guid(riid), ppv); + + if (!ppv) + return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IClassFactory, riid)) { + *ppv = STATIC_CAST(IClassFactory, This); + } else { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI InstanceObjectFactory_IClassFactory_AddRef(IClassFactory *iface) +{ + InstanceObjectFactory *This = ADJUST_THIS(InstanceObjectFactory, IClassFactory, iface); + ULONG cRef; + + TRACE("(iface=%p)\n", iface); + + cRef = InterlockedIncrement(&This->m_cRef); + + if (cRef == 1) + IClassFactory_LockServer(iface, TRUE); + + return cRef; +} + +static ULONG WINAPI InstanceObjectFactory_IClassFactory_Release(IClassFactory *iface) +{ + InstanceObjectFactory *This = ADJUST_THIS(InstanceObjectFactory, IClassFactory, iface); + ULONG cRef; + + TRACE("(iface=%p)\n", iface); + + cRef = InterlockedDecrement(&This->m_cRef); + + if (cRef == 0) { + IClassFactory_LockServer(iface, FALSE); + InstanceObjectFactory_Destroy(This); + } + + return cRef; +} + +static HRESULT WINAPI InstanceObjectFactory_IClassFactory_CreateInstance(IClassFactory *iface, + IUnknown *pUnkOuter, REFIID riid, LPVOID *ppvObj) +{ + InstanceObjectFactory *This = ADJUST_THIS(InstanceObjectFactory, IClassFactory, iface); + IPersistPropertyBag *pPersistPropertyBag; + HRESULT hr; + + TRACE("(pUnkOuter=%p, riid=%s, ppvObj=%p)\n", pUnkOuter, debugstr_guid(riid), ppvObj); + + hr = CoCreateInstance(&This->m_clsidInstance, NULL, CLSCTX_INPROC_SERVER, + &IID_IPersistPropertyBag, (LPVOID*)&pPersistPropertyBag); + if (FAILED(hr)) { + TRACE("Failed to create instance of %s. hr = %08lx\n", + debugstr_guid(&This->m_clsidInstance), hr); + return hr; + } + + hr = IPersistPropertyBag_Load(pPersistPropertyBag, This->m_pPropertyBag, NULL); + if (FAILED(hr)) { + TRACE("Failed to initialize object from ProperyBag: hr = %08lx\n", hr); + IPersistPropertyBag_Release(pPersistPropertyBag); + return hr; + } + + hr = IPersistPropertyBag_QueryInterface(pPersistPropertyBag, riid, ppvObj); + IPersistPropertyBag_Release(pPersistPropertyBag); + + return hr; +} + +static HRESULT WINAPI InstanceObjectFactory_IClassFactory_LockServer(IClassFactory *iface, + BOOL fLock) +{ + TRACE("(iface=%p, fLock=%d) stub\n", iface, fLock); + + if (fLock) + SHDOCVW_LockModule(); + else + SHDOCVW_UnlockModule(); + + return S_OK; +} + +static const IClassFactoryVtbl InstanceObjectFactory_IClassFactoryVtbl = { + InstanceObjectFactory_IClassFactory_QueryInterface, + InstanceObjectFactory_IClassFactory_AddRef, + InstanceObjectFactory_IClassFactory_Release, + InstanceObjectFactory_IClassFactory_CreateInstance, + InstanceObjectFactory_IClassFactory_LockServer +}; + +HRESULT InstanceObjectFactory_Constructor(REFCLSID rclsid, IPropertyBag *pPropertyBag, REFIID riid, + LPVOID *ppvObject) +{ + InstanceObjectFactory *pInstanceObjectFactory; + HRESULT hr = E_FAIL; + + TRACE("(RegistryPropertyBag=%p, riid=%s, ppvObject=%p)\n", pPropertyBag, + debugstr_guid(riid), ppvObject); + + pInstanceObjectFactory = HeapAlloc(GetProcessHeap(), 0, sizeof(InstanceObjectFactory)); + if (pInstanceObjectFactory) { + pInstanceObjectFactory->lpIClassFactoryVtbl = &InstanceObjectFactory_IClassFactoryVtbl; + pInstanceObjectFactory->m_cRef = 0; + memcpy(&pInstanceObjectFactory->m_clsidInstance, rclsid, sizeof(CLSID)); + pInstanceObjectFactory->m_pPropertyBag = pPropertyBag; + IPropertyBag_AddRef(pPropertyBag); + + IClassFactory_AddRef(STATIC_CAST(IClassFactory, pInstanceObjectFactory)); + hr = IClassFactory_QueryInterface(STATIC_CAST(IClassFactory, pInstanceObjectFactory), + riid, ppvObject); + IClassFactory_Release(STATIC_CAST(IClassFactory, pInstanceObjectFactory)); + } + + return hr; +} + +/****************************************************************************** + * SHDOCVW_GetShellInstanceObjectClassObject [Internal] + * + * Figure if there is a 'Shell Instance Object' conformant registry entry for + * the given CLSID and if so create and return a corresponding ClassObject. + * + * PARAMS + * rclsid [I] CLSID of the 'Shell Instance Object'. + * riid [I] Desired interface. Only IClassFactory supported. + * ppvClassObj [O] The corresponding ClassObject. + * + * RETURNS + * Success: S_OK, + * Failure: CLASS_E_CLASSNOTAVAILABLE + */ +HRESULT SHDOCVW_GetShellInstanceObjectClassObject(REFCLSID rclsid, REFIID riid, + LPVOID *ppvClassObj) +{ + WCHAR wszInstanceKey[] = { 'C','L','S','I','D','\\','{','0','0','0','0','0','0','0','0','-', + '0','0','0','0','-','0','0','0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0', + '0','0','0','0','}','\\','I','n','s','t','a','n','c','e', 0 }; + const WCHAR wszCLSID[] = { 'C','L','S','I','D',0 }; + const WCHAR wszInitPropertyBag[] = + { 'I','n','i','t','P','r','o','p','e','r','t','y','B','a','g',0 }; + WCHAR wszCLSIDInstance[CHARS_IN_GUID]; + CLSID clsidInstance; + HKEY hInstanceKey, hInitPropertyBagKey; + DWORD dwType, cbBytes = sizeof(wszCLSIDInstance); + IPropertyBag *pInitPropertyBag; + HRESULT hr; + LONG res; + + TRACE("(rclsid=%s, riid=%s, ppvClassObject=%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), + ppvClassObj); + + /* Figure if there is an 'Instance' subkey for the given CLSID and aquire a handle. */ + if (!StringFromGUID2(rclsid, wszInstanceKey + 6, CHARS_IN_GUID) || + !(wszInstanceKey[5+CHARS_IN_GUID]='\\') || /* Repair the null-termination. */ + ERROR_SUCCESS != RegOpenKeyExW(HKEY_CLASSES_ROOT, wszInstanceKey, 0, KEY_READ, &hInstanceKey)) + { + /* If there is no 'Instance' subkey, then it's not a Shell Instance Object. */ + return CLASS_E_CLASSNOTAVAILABLE; + } + + if (RegQueryValueExW(hInstanceKey, wszCLSID, NULL, &dwType, (LPBYTE)wszCLSIDInstance, &cbBytes) + != ERROR_SUCCESS || FAILED(CLSIDFromString(wszCLSIDInstance, &clsidInstance))) + { + /* 'Instance' should have a 'CLSID' value with a well-formed clsid-string. */ + FIXME("Failed to infer instance CLSID! %s\n", debugstr_w(wszCLSIDInstance)); + RegCloseKey(hInstanceKey); + return CLASS_E_CLASSNOTAVAILABLE; + } + + /* Try to open the 'InitPropertyBag' subkey. */ + res = RegOpenKeyExW(hInstanceKey, wszInitPropertyBag, 0, KEY_READ, &hInitPropertyBagKey); + RegCloseKey(hInstanceKey); + if (res != ERROR_SUCCESS) { + /* Besides 'InitPropertyBag's, shell instance objects might be initialized by streams. + * So this case might not be an error. */ + TRACE("No InitPropertyBag key found!\n"); + return CLASS_E_CLASSNOTAVAILABLE; + } + + /* If the construction succeeds, the new RegistryPropertyBag is responsible for closing + * hInitProperyBagKey. */ + hr = RegistryPropertyBag_Constructor(hInitPropertyBagKey, &IID_IPropertyBag, + (LPVOID*)&pInitPropertyBag); + if (FAILED(hr)) { + RegCloseKey(hInitPropertyBagKey); + return hr; + } + + /* Construct an Instance Object Factory, which creates objects of class 'clsidInstance' + * and asks them to initialize themselves with the help of the 'pInitiPropertyBag' */ + hr = InstanceObjectFactory_Constructor(&clsidInstance, pInitPropertyBag, riid, ppvClassObj); + IPropertyBag_Release(pInitPropertyBag); /* The factory will hold a reference the bag. */ + + return hr; +} diff --git a/reactos/lib/shdocvw/view.c b/reactos/lib/shdocvw/view.c new file mode 100644 index 00000000000..1f4d3c708b9 --- /dev/null +++ b/reactos/lib/shdocvw/view.c @@ -0,0 +1,124 @@ +/* + * Copyright 2005 Jacek Caban + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "wine/debug.h" +#include "shdocvw.h" + +WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); + +#define VIEWOBJ_THIS(iface) DEFINE_THIS(WebBrowser, ViewObject, iface) + +static HRESULT WINAPI ViewObject_QueryInterface(IViewObject2 *iface, REFIID riid, void **ppv) +{ + WebBrowser *This = VIEWOBJ_THIS(iface); + return IWebBrowser2_QueryInterface(WEBBROWSER(This), riid, ppv); +} + +static ULONG WINAPI ViewObject_AddRef(IViewObject2 *iface) +{ + WebBrowser *This = VIEWOBJ_THIS(iface); + return IWebBrowser2_AddRef(WEBBROWSER(This)); +} + +static ULONG WINAPI ViewObject_Release(IViewObject2 *iface) +{ + WebBrowser *This = VIEWOBJ_THIS(iface); + return IWebBrowser2_Release(WEBBROWSER(This)); +} + +static HRESULT WINAPI ViewObject_Draw(IViewObject2 *iface, DWORD dwDrawAspect, + LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, + HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, + BOOL (STDMETHODCALLTYPE *pfnContinue)(ULONG_PTR), + ULONG_PTR dwContinue) +{ + WebBrowser *This = VIEWOBJ_THIS(iface); + FIXME("(%p)->(%ld %ld %p %p %p %p %p %p %p %08lx)\n", This, dwDrawAspect, lindex, + pvAspect, ptd, hdcTargetDev, hdcDraw, lprcBounds, lprcWBounds, pfnContinue, + dwContinue); + return E_NOTIMPL; +} + +static HRESULT WINAPI ViewObject_GetColorSet(IViewObject2 *iface, DWORD dwAspect, + LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, + LOGPALETTE **ppColorSet) +{ + WebBrowser *This = VIEWOBJ_THIS(iface); + FIXME("(%p)->(%ld %ld %p %p %p %p)\n", This, dwAspect, lindex, pvAspect, ptd, + hicTargetDev, ppColorSet); + return E_NOTIMPL; +} + +static HRESULT WINAPI ViewObject_Freeze(IViewObject2 *iface, DWORD dwDrawAspect, LONG lindex, + void *pvAspect, DWORD *pdwFreeze) +{ + WebBrowser *This = VIEWOBJ_THIS(iface); + FIXME("(%p)->(%ld %ld %p %p)\n", This, dwDrawAspect, lindex, pvAspect, pdwFreeze); + return E_NOTIMPL; +} + +static HRESULT WINAPI ViewObject_Unfreeze(IViewObject2 *iface, DWORD dwFreeze) +{ + WebBrowser *This = VIEWOBJ_THIS(iface); + FIXME("(%p)->(%ld)\n", This, dwFreeze); + return E_NOTIMPL; +} + +static HRESULT WINAPI ViewObject_SetAdvise(IViewObject2 *iface, DWORD aspects, DWORD advf, + IAdviseSink *pAdvSink) +{ + WebBrowser *This = VIEWOBJ_THIS(iface); + FIXME("(%p)->(%ld %08lx %p)\n", This, aspects, advf, pAdvSink); + return E_NOTIMPL; +} + +static HRESULT WINAPI ViewObject_GetAdvise(IViewObject2 *iface, DWORD *pAspects, + DWORD *pAdvf, IAdviseSink **ppAdvSink) +{ + WebBrowser *This = VIEWOBJ_THIS(iface); + FIXME("(%p)->(%p %p %p)\n", This, pAspects, pAdvf, ppAdvSink); + return E_NOTIMPL; +} + +static HRESULT WINAPI ViewObject_GetExtent(IViewObject2 *iface, DWORD dwAspect, LONG lindex, + DVTARGETDEVICE *ptd, LPSIZEL lpsizel) +{ + WebBrowser *This = VIEWOBJ_THIS(iface); + FIXME("(%p)->(%ld %ld %p %p)\n", This, dwAspect, lindex, ptd, lpsizel); + return E_NOTIMPL; +} + +static const IViewObject2Vtbl ViewObjectVtbl = { + ViewObject_QueryInterface, + ViewObject_AddRef, + ViewObject_Release, + ViewObject_Draw, + ViewObject_GetColorSet, + ViewObject_Freeze, + ViewObject_Unfreeze, + ViewObject_SetAdvise, + ViewObject_GetAdvise, + ViewObject_GetExtent +}; + +#undef VIEWOBJ_THIS + +void WebBrowser_ViewObject_Init(WebBrowser *This) +{ + This->lpViewObjectVtbl = &ViewObjectVtbl; +} diff --git a/reactos/lib/shdocvw/webbrowser.c b/reactos/lib/shdocvw/webbrowser.c index 5520d745abd..7f699a13dcd 100644 --- a/reactos/lib/shdocvw/webbrowser.c +++ b/reactos/lib/shdocvw/webbrowser.c @@ -19,8 +19,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#define COBJMACROS #include "wine/debug.h" #include "shdocvw.h" +#include "mshtml.h" + WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); @@ -41,7 +44,7 @@ static HRESULT WINAPI WebBrowser_QueryInterface(IWebBrowser2 *iface, REFIID riid if(IsEqualGUID(&IID_IUnknown, riid)) { TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); *ppv = WEBBROWSER(This); - }else if(IsEqualGUID (&IID_IDispatch, riid)) { + }else if(IsEqualGUID(&IID_IDispatch, riid)) { TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv); *ppv = WEBBROWSER(This); }else if(IsEqualGUID(&IID_IWebBrowser, riid)) { @@ -74,18 +77,24 @@ static HRESULT WINAPI WebBrowser_QueryInterface(IWebBrowser2 *iface, REFIID riid }else if(IsEqualGUID (&IID_IPersistStreamInit, riid)) { TRACE("(%p)->(IID_IPersistStreamInit %p)\n", This, ppv); *ppv = PERSTRINIT(This); - }else if(IsEqualGUID (&IID_IProvideClassInfo, riid)) { + }else if(IsEqualGUID(&IID_IProvideClassInfo, riid)) { TRACE("(%p)->(IID_IProvideClassInfo %p)\n", This, ppv); *ppv = CLASSINFO(This); - }else if(IsEqualGUID (&IID_IProvideClassInfo2, riid)) { + }else if(IsEqualGUID(&IID_IProvideClassInfo2, riid)) { TRACE("(%p)->(IID_IProvideClassInfo2 %p)\n", This, ppv); *ppv = CLASSINFO(This); - }else if(IsEqualGUID (&IID_IQuickActivate, riid)) { + }else if(IsEqualGUID(&IID_IQuickActivate, riid)) { TRACE("(%p)->(IID_IQuickActivate %p)\n", This, ppv); *ppv = QUICKACT(This); - }else if(IsEqualGUID (&IID_IConnectionPointContainer, riid)) { + }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) { TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv); *ppv = CONPTCONT(This); + }else if(IsEqualGUID(&IID_IViewObject, riid)) { + TRACE("(%p)->(IID_IViewObject %p)\n", This, ppv); + *ppv = VIEWOBJ(This); + }else if(IsEqualGUID(&IID_IViewObject2, riid)) { + TRACE("(%p)->(IID_IViewObject2 %p)\n", This, ppv); + *ppv = VIEWOBJ2(This); } if(*ppv) { @@ -113,6 +122,11 @@ static ULONG WINAPI WebBrowser_Release(IWebBrowser2 *iface) TRACE("(%p) ref=%ld\n", This, ref); if(!ref) { + if(This->document) + IUnknown_Release(This->document); + + WebBrowser_OleObject_Destroy(This); + HeapFree(GetProcessHeap(), 0, This); SHDOCVW_UnlockModule(); } @@ -480,8 +494,63 @@ static HRESULT WINAPI WebBrowser_Navigate2(IWebBrowser2 *iface, VARIANT *URL, VA VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers) { WebBrowser *This = WEBBROWSER_THIS(iface); - FIXME("(%p)->(%p %p %p %p %p)\n", This, URL, Flags, TargetFrameName, PostData, Headers); - return E_NOTIMPL; + IPersistMoniker *persist; + IOleObject *oleobj; + IMoniker *mon; + HRESULT hres; + + TRACE("(%p)->(%p %p %p %p %p)\n", This, URL, Flags, TargetFrameName, PostData, Headers); + + if(!This->client) + return E_FAIL; + + if(V_VT(Flags) != VT_EMPTY || V_VT(TargetFrameName) != VT_EMPTY + || V_VT(PostData) != VT_EMPTY || V_VT(Headers) != VT_EMPTY) + FIXME("Unsupported arguments\n"); + + if(V_VT(URL) != VT_BSTR) + FIXME("V_VT(URL) != VT_BSTR\n"); + + /* + * FIXME: + * We should use URLMoniker's BindToObject instead creating HTMLDocument here. + * This should be fixed when mshtml.dll and urlmon.dll will be good enough. + */ + + if(!This->document) { + hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, + CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IUnknown, (void**)&This->document); + if(FAILED(hres)) + return hres; + } + + hres = IUnknown_QueryInterface(This->document, &IID_IPersistMoniker, (void**)&persist); + if(FAILED(hres)) + return hres; + + hres = CreateURLMoniker(NULL, V_BSTR(URL), &mon); + if(FAILED(hres)) { + IPersistMoniker_Release(persist); + return hres; + } + + hres = IPersistMoniker_Load(persist, FALSE, mon, NULL /* FIXME */, 0); + IMoniker_Release(mon); + IPersistMoniker_Release(persist); + if(FAILED(hres)) { + WARN("Load failed: %08lx\n", hres); + return hres; + } + + hres = IUnknown_QueryInterface(This->document, &IID_IOleObject, (void**)&oleobj); + if(FAILED(hres)) + return hres; + + hres = IOleObject_SetClientSite(oleobj, CLIENTSITE(This)); + IOleObject_Release(oleobj); + + return hres; } static HRESULT WINAPI WebBrowser_QueryStatusWB(IWebBrowser2 *iface, OLECMDID cmdID, OLECMDF *pcmdf) @@ -705,11 +774,15 @@ HRESULT WebBrowser_Create(IUnknown *pOuter, REFIID riid, void **ppv) ret->lpWebBrowser2Vtbl = &WebBrowser2Vtbl; ret->ref = 0; + ret->document = NULL; + WebBrowser_OleObject_Init(ret); + WebBrowser_ViewObject_Init(ret); WebBrowser_Persist_Init(ret); WebBrowser_ClassInfo_Init(ret); WebBrowser_Misc_Init(ret); WebBrowser_Events_Init(ret); + WebBrowser_ClientSite_Init(ret); hres = IWebBrowser_QueryInterface(WEBBROWSER(ret), riid, ppv); if(SUCCEEDED(hres)) { diff --git a/reactos/lib/uuid/uuid.c b/reactos/lib/uuid/uuid.c index 634b6b2f927..479b33e7a43 100644 --- a/reactos/lib/uuid/uuid.c +++ b/reactos/lib/uuid/uuid.c @@ -89,3 +89,5 @@ DEFINE_OLEGUID(IID_StdOle,0x00020430,0,0); DEFINE_GUID(CLSID_StdFont,0x0be35203,0x8f91,0x11ce,0x9d,0xe3,0x00,0xaa,0x00,0x4b,0xb8,0x51); DEFINE_GUID(CLSID_StdPicture,0x0be35204,0x8f91,0x11ce,0x9d,0xe3,0x00,0xaa,0x00,0x4b,0xb8,0x51); + +DEFINE_GUID(CLSID_HTMLDocument, 0x25336920, 0x03f9, 0x11cf, 0x8f,0xd0, 0x00,0xaa,0x00,0x68,0x6f,0x13); diff --git a/reactos/w32api/include/mshtml.h b/reactos/w32api/include/mshtml.h index 281ce928dc2..6d289117cdf 100644 --- a/reactos/w32api/include/mshtml.h +++ b/reactos/w32api/include/mshtml.h @@ -156,6 +156,7 @@ DECLARE_INTERFACE_(IHTMLDocument,IDispatch) STDMETHOD(get_Script)(THIS_ IDispatch**) PURE; }; #undef INTERFACE +EXTERN_C const CLSID CLSID_HTMLDocument; EXTERN_C const IID IID_IHTMLDocument2; #define INTERFACE IHTMLDocument2 diff --git a/reactos/w32api/include/oleidl.h b/reactos/w32api/include/oleidl.h index 2d32f7d453f..36e9f40801b 100644 --- a/reactos/w32api/include/oleidl.h +++ b/reactos/w32api/include/oleidl.h @@ -125,6 +125,18 @@ DECLARE_INTERFACE_(IOleContainer,IParseDisplayName) }; #undef INTERFACE +#ifdef COBJMACROS +/*** IUnknown methods ***/ +#define IOleContainer_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IOleContainer_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IOleContainer_Release(p) (p)->lpVtbl->Release(p) +/*** IParseDisplayName methods ***/ +#define IOleContainer_ParseDisplayName(p,a,b,c,d) (p)->lpVtbl->ParseDisplayName(p,a,b,c,d) +/*** IOleContainer methods ***/ +#define IOleContainer_EnumObjects(p,a,b) (p)->lpVtbl->EnumObjects(p,a,b) +#define IOleContainer_LockContainer(p,a) (p)->lpVtbl->LockContainer(p,a) +#endif + EXTERN_C const IID IID_IOleItemContainer; #define INTERFACE IOleItemContainer DECLARE_INTERFACE_(IOleItemContainer,IOleContainer) @@ -275,6 +287,21 @@ DECLARE_INTERFACE_(IOleInPlaceUIWindow,IOleWindow) }; #undef INTERFACE +#ifdef COBJMACROS +/*** IUnknown methods ***/ +#define IOleInPlaceUIWindow_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IOleInPlaceUIWindow_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IOleInPlaceUIWindow_Release(p) (p)->lpVtbl->Release(p) +/*** IOleWindow methods ***/ +#define IOleInPlaceUIWindow_GetWindow(p,a) (p)->lpVtbl->GetWindow(p,a) +#define IOleInPlaceUIWindow_ContextSensitiveHelp(p,a) (p)->lpVtbl->ContextSensitiveHelp(p,a) +/*** IOleInPlaceUIWindow methods ***/ +#define IOleInPlaceUIWindow_GetBorder(p,a) (p)->lpVtbl->GetBorder(p,a) +#define IOleInPlaceUIWindow_RequestBorderSpace(p,a) (p)->lpVtbl->RequestBorderSpace(p,a) +#define IOleInPlaceUIWindow_SetBorderSpace(p,a) (p)->lpVtbl->SetBorderSpace(p,a) +#define IOleInPlaceUIWindow_SetActiveObject(p,a,b) (p)->lpVtbl->SetActiveObject(p,a,b) +#endif + EXTERN_C const IID IID_IOleInPlaceObject; #define INTERFACE IOleInPlaceObject DECLARE_INTERFACE_(IOleInPlaceObject,IOleWindow) @@ -386,6 +413,27 @@ DECLARE_INTERFACE_(IOleInPlaceSite,IOleWindow) }; #undef INTERFACE +#ifdef COBJMACROS +/*** IUnknown methods ***/ +#define IOleInPlaceSite_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IOleInPlaceSite_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IOleInPlaceSite_Release(p) (p)->lpVtbl->Release(p) +/*** IOleWindow methods ***/ +#define IOleInPlaceSite_GetWindow(p,a) (p)->lpVtbl->GetWindow(p,a) +#define IOleInPlaceSite_ContextSensitiveHelp(p,a) (p)->lpVtbl->ContextSensitiveHelp(p,a) +/*** IOleInPlaceSite methods ***/ +#define IOleInPlaceSite_CanInPlaceActivate(p) (p)->lpVtbl->CanInPlaceActivate(p) +#define IOleInPlaceSite_OnInPlaceActivate(p) (p)->lpVtbl->OnInPlaceActivate(p) +#define IOleInPlaceSite_OnUIActivate(p) (p)->lpVtbl->OnUIActivate(p) +#define IOleInPlaceSite_GetWindowContext(p,a,b,c,d,e) (p)->lpVtbl->GetWindowContext(p,a,b,c,d,e) +#define IOleInPlaceSite_Scroll(p,a) (p)->lpVtbl->Scroll(p,a) +#define IOleInPlaceSite_OnUIDeactivate(p,a) (p)->lpVtbl->OnUIDeactivate(p,a) +#define IOleInPlaceSite_OnInPlaceDeactivate(p) (p)->lpVtbl->OnInPlaceDeactivate(p) +#define IOleInPlaceSite_DiscardUndoState(p) (p)->lpVtbl->DiscardUndoState(p) +#define IOleInPlaceSite_DeactivateAndUndo(p) (p)->lpVtbl->DeactivateAndUndo(p) +#define IOleInPlaceSite_OnPosRectChange(p,a) (p)->lpVtbl->OnPosRectChange(p,a) +#endif + EXTERN_C const IID IID_IOleAdviseHolder; #define INTERFACE IOleAdviseHolder DECLARE_INTERFACE_(IOleAdviseHolder,IUnknown) -- 2.17.1