Sync to Wine-0_9_1:
authorGé van Geldorp <ge@gse.nl>
Sun, 20 Nov 2005 14:26:47 +0000 (14:26 +0000)
committerGé van Geldorp <ge@gse.nl>
Sun, 20 Nov 2005 14:26:47 +0000 (14:26 +0000)
Michael Jung <mjung@iss.tu-darmstadt.de>
- 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

15 files changed:
reactos/include/wine/objidl.h
reactos/lib/shdocvw/Ko.rc [new file with mode: 0644]
reactos/lib/shdocvw/Makefile.in [deleted file]
reactos/lib/shdocvw/client.c [new file with mode: 0644]
reactos/lib/shdocvw/oleobject.c
reactos/lib/shdocvw/shdocvw.h
reactos/lib/shdocvw/shdocvw.rc
reactos/lib/shdocvw/shdocvw.xml
reactos/lib/shdocvw/shdocvw_main.c
reactos/lib/shdocvw/shlinstobj.c [new file with mode: 0644]
reactos/lib/shdocvw/view.c [new file with mode: 0644]
reactos/lib/shdocvw/webbrowser.c
reactos/lib/uuid/uuid.c
reactos/w32api/include/mshtml.h
reactos/w32api/include/oleidl.h

index 7f2fe24..985fb32 100644 (file)
@@ -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 (file)
index 0000000..4929bc1
--- /dev/null
@@ -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 (file)
index a0135b6..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-EXTRADEFS = -D_SHDOCVW_\r
-TOPSRCDIR = @top_srcdir@\r
-TOPOBJDIR = ../..\r
-SRCDIR    = @srcdir@\r
-VPATH     = @srcdir@\r
-MODULE    = shdocvw.dll\r
-IMPORTLIB = libshdocvw.$(IMPLIBEXT)\r
-IMPORTS   = urlmon ole32 user32 advapi32 kernel32\r
-EXTRALIBS = -luuid\r
-\r
-C_SRCS = \\r
-       classinfo.c \\r
-       events.c \\r
-       factory.c \\r
-       misc.c \\r
-       oleobject.c \\r
-       persist.c \\r
-       regsvr.c \\r
-       shdocvw_main.c \\r
-       webbrowser.c\r
-\r
-RC_SRCS = shdocvw.rc\r
-\r
-@MAKE_DLL_RULES@\r
-\r
-### Dependencies:\r
diff --git a/reactos/lib/shdocvw/client.c b/reactos/lib/shdocvw/client.c
new file mode 100644 (file)
index 0000000..bf8e768
--- /dev/null
@@ -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;
+}
index 90804a7..a365885 100644 (file)
@@ -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);
 }
index 19d40fb..f30fa7d 100644 (file)
@@ -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**);
 
 /**********************************************************************
index 91c25ed..40c4c96 100644 (file)
@@ -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"
index 2ef5430..1332caf 100644 (file)
        <library>advapi32</library>
        <library>user32</library>
        <library>ole32</library>
+       <library>oleaut32</library>
        <library>urlmon</library>
        <file>classinfo.c</file>
+       <file>client.c</file>
        <file>events.c</file>
        <file>factory.c</file>
        <file>misc.c</file>
@@ -24,6 +26,8 @@
        <file>persist.c</file>
        <file>regsvr.c</file>
        <file>shdocvw_main.c</file>
+        <file>shlinstobj.c</file>
+       <file>view.c</file>
        <file>webbrowser.c</file>
        <file>shdocvw.rc</file>
        <file>shdocvw.spec</file>
index a746e05..4df0ead 100644 (file)
@@ -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 (file)
index 0000000..19ba3b8
--- /dev/null
@@ -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 <stdarg.h>
+
+#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 (file)
index 0000000..1f4d3c7
--- /dev/null
@@ -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;
+}
index 5520d74..7f699a1 100644 (file)
  * 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)) {
index 634b6b2..479b33e 100644 (file)
@@ -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);
index 281ce92..6d28911 100644 (file)
@@ -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
index 2d32f7d..36e9f40 100644 (file)
@@ -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)