/*
 * Implementation of IOleObject interfaces for WebBrowser class
 *
 * - IOleObject
 * - IOleInPlaceObject
 * - IOleControl
 *
 * 2001 John R. Sheets (for CodeWeavers)
 *
 * Copyright (c) 2003 TransGaming Technologies
 * david@transgaming.com
 */

#include <string.h>
#include "wine/debug.h"
#include "shdocvw.h"
#include "ole2.h"

WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);

static HRESULT WINAPI WBOOBJ_QueryInterface(LPOLEOBJECT iface,
                                            REFIID riid, void** ppobj)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);

    TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppobj);
    return IWebBrowser_QueryInterface((LPWEBBROWSER) This, riid, ppobj);
}

static ULONG WINAPI WBOOBJ_AddRef(LPOLEOBJECT iface)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);
    TRACE("(%p)->()\n", iface);
    return IWebBrowser_AddRef((LPWEBBROWSER) This);
}

static ULONG WINAPI WBOOBJ_Release(LPOLEOBJECT iface)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);
    TRACE("(%p)->()\n", iface);
    return IWebBrowser_Release((LPWEBBROWSER) This);
}

static HRESULT WINAPI WBOOBJ_SetClientSite(LPOLEOBJECT iface,
                                           LPOLECLIENTSITE pClientSite)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WBOOBJ_GetClientSite(LPOLEOBJECT iface,
                                           LPOLECLIENTSITE* ppClientSite)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WBOOBJ_SetHostNames(LPOLEOBJECT iface, LPCOLESTR szContainerApp,
                                          LPCOLESTR szContainerObj)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(%s, %s): stub\n", iface, debugstr_w(szContainerApp),
          debugstr_w(szContainerObj));
    return S_OK;
}

static HRESULT WINAPI WBOOBJ_Close(LPOLEOBJECT iface, DWORD dwSaveOption)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WBOOBJ_SetMoniker(LPOLEOBJECT iface,
                                        DWORD dwWhichMoniker, IMoniker* pmk)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(%ld, %p): stub\n", iface, dwWhichMoniker, pmk);
    return S_OK;
}

static HRESULT WINAPI WBOOBJ_GetMoniker(LPOLEOBJECT iface, DWORD dwAssign,
                                        DWORD dwWhichMoniker, LPMONIKER *ppmk)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(%ld, %ld, %p): stub\n", iface, dwAssign, dwWhichMoniker, ppmk);
    return E_UNSPEC;
}

static HRESULT WINAPI WBOOBJ_InitFromData(LPOLEOBJECT iface, LPDATAOBJECT pDataObject,
                                          BOOL fCreation, DWORD dwReserved)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(%p, %d, %ld): stub\n", iface, pDataObject, fCreation, dwReserved);
    return OLE_E_NOTRUNNING;
}

static HRESULT WINAPI WBOOBJ_GetClipboardData(LPOLEOBJECT iface, DWORD dwReserved,
                                              LPDATAOBJECT *ppDataObject)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(%ld, %p): stub\n", iface, dwReserved, ppDataObject);
    return OLE_E_NOTRUNNING;
}

static HRESULT WINAPI WBOOBJ_DoVerb(LPOLEOBJECT iface, LONG iVerb, struct tagMSG* lpmsg,
                                    LPOLECLIENTSITE pActiveSite, LONG lindex,
                                    HWND hwndParent, LPCRECT lprcPosRect)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(%08lx, ...): stub\n", iface, iVerb);
    switch (iVerb)
    {
    case OLEIVERB_INPLACEACTIVATE:
        FIXME ("stub for OLEIVERB_INPLACEACTIVATE\n");
        break;
    case OLEIVERB_HIDE:
        FIXME ("stub for OLEIVERB_HIDE\n");
        break;
    }
    return S_OK;
}

static HRESULT WINAPI WBOOBJ_EnumVerbs(LPOLEOBJECT iface,
                                       IEnumOLEVERB** ppEnumOleVerb)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    TRACE("(%p)->(%p)\n", iface, ppEnumOleVerb);

    return OleRegEnumVerbs(&CLSID_WebBrowser, ppEnumOleVerb);
}

static HRESULT WINAPI WBOOBJ_Update(LPOLEOBJECT iface)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WBOOBJ_IsUpToDate(LPOLEOBJECT iface)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WBOOBJ_GetUserClassID(LPOLEOBJECT iface, CLSID* pClsid)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(%p): stub\n", iface, pClsid);
    return S_OK;
}

static HRESULT WINAPI WBOOBJ_GetUserType(LPOLEOBJECT iface, DWORD dwFormOfType,
                                         LPOLESTR* pszUserType)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    TRACE("(%p)->(%ld, %p)\n", iface, dwFormOfType, pszUserType);

    return OleRegGetUserType(&CLSID_WebBrowser, dwFormOfType, pszUserType);
}

static HRESULT WINAPI WBOOBJ_SetExtent(LPOLEOBJECT iface, DWORD dwDrawAspect,
                                       SIZEL* psizel)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(%lx, (%ld x %ld)): stub\n", iface, dwDrawAspect,
          psizel->cx, psizel->cy);
    return OLE_E_NOTRUNNING;
}

static HRESULT WINAPI WBOOBJ_GetExtent(LPOLEOBJECT iface, DWORD dwDrawAspect,
                                       SIZEL* psizel)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(%lx, %p): stub\n", iface, dwDrawAspect, psizel);
    return S_OK;
}

static HRESULT WINAPI WBOOBJ_Advise(LPOLEOBJECT iface, IAdviseSink* pAdvSink,
                                    DWORD* pdwConnection)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(%p, %p): stub\n", iface, pAdvSink, pdwConnection);
    return S_OK;
}

static HRESULT WINAPI WBOOBJ_Unadvise(LPOLEOBJECT iface, DWORD dwConnection)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(%ld): stub\n", iface, dwConnection);
    return S_OK;
}

static HRESULT WINAPI WBOOBJ_EnumAdvise(LPOLEOBJECT iface, IEnumSTATDATA** ppenumAdvise)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(%p): stub\n", iface, ppenumAdvise);
    return S_OK;
}

static HRESULT WINAPI WBOOBJ_GetMiscStatus(LPOLEOBJECT iface, DWORD dwAspect,
                                           DWORD* pdwStatus)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    HRESULT hres;

    TRACE("(%p)->(%lx, %p)\n", iface, dwAspect, pdwStatus);

    hres = OleRegGetMiscStatus(&CLSID_WebBrowser, dwAspect, pdwStatus);

    if (FAILED(hres))
        *pdwStatus = 0;

    return S_OK;
}

static HRESULT WINAPI WBOOBJ_SetColorScheme(LPOLEOBJECT iface,
                                            struct tagLOGPALETTE* pLogpal)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OOBJ, iface);*/
    FIXME("(%p)->(%p)): stub\n", iface, pLogpal);
    return OLE_E_NOTRUNNING;
}

/**********************************************************************
 * IOleObject virtual function table for WebBrowser class
 */

ICOM_VTABLE(IOleObject) WBOOBJ_Vtbl =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    WBOOBJ_QueryInterface,
    WBOOBJ_AddRef,
    WBOOBJ_Release,
    WBOOBJ_SetClientSite,
    WBOOBJ_GetClientSite,
    WBOOBJ_SetHostNames,
    WBOOBJ_Close,
    WBOOBJ_SetMoniker,
    WBOOBJ_GetMoniker,
    WBOOBJ_InitFromData,
    WBOOBJ_GetClipboardData,
    WBOOBJ_DoVerb,
    WBOOBJ_EnumVerbs,
    WBOOBJ_Update,
    WBOOBJ_IsUpToDate,
    WBOOBJ_GetUserClassID,
    WBOOBJ_GetUserType,
    WBOOBJ_SetExtent,
    WBOOBJ_GetExtent,
    WBOOBJ_Advise,
    WBOOBJ_Unadvise,
    WBOOBJ_EnumAdvise,
    WBOOBJ_GetMiscStatus,
    WBOOBJ_SetColorScheme
};

/**********************************************************************
 * Implement the IOleInPlaceObject interface
 */

static HRESULT WINAPI WBOIPO_QueryInterface(LPOLEINPLACEOBJECT iface,
                                            REFIID riid, LPVOID *ppobj)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OIPO, iface);

    TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppobj);
    return IWebBrowser_QueryInterface((LPWEBBROWSER) This, riid, ppobj);
}

static ULONG WINAPI WBOIPO_AddRef(LPOLEINPLACEOBJECT iface)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OIPO, iface);
    TRACE("(%p)->()\n", iface);
    return IWebBrowser_AddRef((LPWEBBROWSER) This);
}

static ULONG WINAPI WBOIPO_Release(LPOLEINPLACEOBJECT iface)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OIPO, iface);
    TRACE("(%p)->()\n", iface);
    return IWebBrowser_Release((LPWEBBROWSER) This);
}

static HRESULT WINAPI WBOIPO_GetWindow(LPOLEINPLACEOBJECT iface, HWND* phwnd)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OIPO, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
#if 0
    /* Create a fake window to fool MFC into believing that we actually
     * have an implemented browser control.  Avoids the assertion.
     */
    HWND hwnd;
    hwnd = CreateWindowA("BUTTON", "Web Control",
                        WS_HSCROLL | WS_VSCROLL | WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT, CW_USEDEFAULT, 600,
                        400, NULL, NULL, NULL, NULL);

    *phwnd = hwnd;
    TRACE ("Returning hwnd = %d\n", hwnd);
#endif

}

static HRESULT WINAPI WBOIPO_ContextSensitiveHelp(LPOLEINPLACEOBJECT iface,
                                                  BOOL fEnterMode)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OIPO, iface)*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WBOIPO_InPlaceDeactivate(LPOLEINPLACEOBJECT iface)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OIPO, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WBOIPO_UIDeactivate(LPOLEINPLACEOBJECT iface)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OIPO, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WBOIPO_SetObjectRects(LPOLEINPLACEOBJECT iface,
                                            LPCRECT lprcPosRect, LPCRECT lprcClipRect)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OIPO, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WBOIPO_ReactivateAndUndo(LPOLEINPLACEOBJECT iface)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OIPO, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

/**********************************************************************
 * IOleInPlaceObject virtual function table for WebBrowser class
 */

ICOM_VTABLE(IOleInPlaceObject) WBOIPO_Vtbl =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    WBOIPO_QueryInterface,
    WBOIPO_AddRef,
    WBOIPO_Release,
    WBOIPO_GetWindow,
    WBOIPO_ContextSensitiveHelp,
    WBOIPO_InPlaceDeactivate,
    WBOIPO_UIDeactivate,
    WBOIPO_SetObjectRects,
    WBOIPO_ReactivateAndUndo
};


/**********************************************************************
 * Implement the IOleControl interface
 */

static HRESULT WINAPI WBOC_QueryInterface(LPOLECONTROL iface,
                                          REFIID riid, LPVOID *ppobj)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OC, iface);

    TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppobj);
    return IWebBrowser_QueryInterface((LPWEBBROWSER) This, riid, ppobj);
}

static ULONG WINAPI WBOC_AddRef(LPOLECONTROL iface)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OC, iface);
    TRACE("(%p)->()\n", iface);
    return IWebBrowser_AddRef((LPWEBBROWSER) This);
}

static ULONG WINAPI WBOC_Release(LPOLECONTROL iface)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OC, iface);
    TRACE("(%p)->()\n", iface);
    return IWebBrowser_Release((LPWEBBROWSER) This);
}

static HRESULT WINAPI WBOC_GetControlInfo(LPOLECONTROL iface, LPCONTROLINFO pCI)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OC, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WBOC_OnMnemonic(LPOLECONTROL iface, struct tagMSG *pMsg)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OC, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WBOC_OnAmbientPropertyChange(LPOLECONTROL iface, DISPID dispID)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OC, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WBOC_FreezeEvents(LPOLECONTROL iface, BOOL bFreeze)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_OC, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

/**********************************************************************
 * IOleControl virtual function table for IE Web Browser component
 */

ICOM_VTABLE(IOleControl) WBOC_Vtbl =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    WBOC_QueryInterface,
    WBOC_AddRef,
    WBOC_Release,
    WBOC_GetControlInfo,
    WBOC_OnMnemonic,
    WBOC_OnAmbientPropertyChange,
    WBOC_FreezeEvents
};

/**********************************************************************
 * Implement the IViewObject interface
 */

static HRESULT WINAPI VOBJ_QueryInterface(LPVIEWOBJECT iface,
                                          REFIID riid, LPVOID *ppobj)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO, iface);

    TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppobj);
    return IWebBrowser_QueryInterface((LPWEBBROWSER) This, riid, ppobj);
}

static ULONG WINAPI VOBJ_AddRef(LPVIEWOBJECT iface)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO, iface);
    TRACE("(%p)->()\n", iface);
    return IWebBrowser_AddRef((LPWEBBROWSER) This);
}

static ULONG WINAPI VOBJ_Release(LPVIEWOBJECT iface)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO, iface);
    TRACE("(%p)->()\n", iface);
    return IWebBrowser_Release((LPWEBBROWSER) This);
}

static HRESULT WINAPI VOBJ_Draw (LPVIEWOBJECT iface, DWORD dwDrawAspect, LONG lindex,
                          void* pvAspect, DVTARGETDEVICE* ptd,
                          HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds,
                          LPCRECTL lprcWBounds, BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
                          DWORD dwContinue)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI VOBJ_GetColorSet (LPVIEWOBJECT iface, DWORD dwDrawAspect, LONG lindex,
                                 void* pvAspect, DVTARGETDEVICE* ptd, HDC hicTargetDevice,
                                 struct tagLOGPALETTE** ppColorSet)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI VOBJ_Freeze (LPVIEWOBJECT iface, DWORD dwDrawAspect, LONG lindex, void* pvAspect, DWORD* pdwFreeze)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI VOBJ_Unfreeze (LPVIEWOBJECT iface, DWORD dwFreeze)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI VOBJ_SetAdvise (LPVIEWOBJECT iface, DWORD aspects, DWORD advf, IAdviseSink* pAdvSink)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI VOBJ_GetAdvise (LPVIEWOBJECT iface, DWORD* pAspects, DWORD* pAdvf, IAdviseSink** ppAdvSink)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

/**********************************************************************
 * Implement the IViewObject2 interface
 */

static HRESULT WINAPI WINAPI VOBJ2_QueryInterface(LPVIEWOBJECT2 iface,
                                           REFIID riid, LPVOID *ppobj)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO2, iface);

    TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppobj);
    return IWebBrowser_QueryInterface((LPWEBBROWSER) This, riid, ppobj);
}

static ULONG WINAPI VOBJ2_AddRef(LPVIEWOBJECT2 iface)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO2, iface);
    TRACE("(%p)->()\n", iface);
    return IWebBrowser_AddRef((LPWEBBROWSER) This);
}

static ULONG WINAPI VOBJ2_Release(LPVIEWOBJECT2 iface)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO2, iface);
    TRACE("(%p)->()\n", iface);
    return IWebBrowser_Release((LPWEBBROWSER) This);
}

static HRESULT WINAPI VOBJ2_Draw (LPVIEWOBJECT2 iface, DWORD dwDrawAspect,
                           LONG lindex, void* pvAspect, DVTARGETDEVICE* ptd,
                           HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds,
                           LPCRECTL lprcWBounds, BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
                           DWORD dwContinue)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI VOBJ2_GetColorSet (LPVIEWOBJECT2 iface, DWORD dwDrawAspect,
                                  LONG lindex, void* pvAspect, DVTARGETDEVICE* ptd,
                                  HDC hicTargetDevice,
                                  struct tagLOGPALETTE** ppColorSet)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI VOBJ2_Freeze (LPVIEWOBJECT2 iface, DWORD dwDrawAspect, LONG lindex,
                             void* pvAspect, DWORD* pdwFreeze)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI VOBJ2_Unfreeze (LPVIEWOBJECT2 iface, DWORD dwFreeze)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI VOBJ2_SetAdvise (LPVIEWOBJECT2 iface, DWORD aspects, DWORD advf, IAdviseSink* pAdvSink)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI VOBJ2_GetAdvise (LPVIEWOBJECT2 iface, DWORD* pAspects, DWORD* pAdvf, IAdviseSink** ppAdvSink)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI VOBJ2_GetExtent (LPVIEWOBJECT2 iface, DWORD dwDrawAspect, LONG lindex,
                                DVTARGETDEVICE* ptd, LPSIZEL lpsizel)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_VO2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

/**********************************************************************
 * IViewObject2 virtual function table for WebBrowser class
 */

ICOM_VTABLE(IViewObject2) VOBJ2_Vtbl =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    VOBJ2_QueryInterface,
    VOBJ2_AddRef,
    VOBJ2_Release,
    VOBJ2_Draw,
    VOBJ2_GetColorSet,
    VOBJ2_Freeze,
    VOBJ2_Unfreeze,
    VOBJ2_SetAdvise,
    VOBJ2_GetAdvise,
    VOBJ2_GetExtent
};

/**********************************************************************
 * IViewObject virtual function table for IE Web Browser component
 */
ICOM_VTABLE(IViewObject) VOBJ_Vtbl =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    VOBJ_QueryInterface,
    VOBJ_AddRef,
    VOBJ_Release,
    VOBJ_Draw,
    VOBJ_GetColorSet,
    VOBJ_Freeze,
    VOBJ_Unfreeze,
    VOBJ_SetAdvise,
    VOBJ_GetAdvise
};

/**********************************************************************
 * IRunnableObject
 */

static HRESULT WINAPI WBRUNOBJ_QueryInterface(LPRUNNABLEOBJECT iface,
                                              REFIID riid, void** ppobj)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_RUNOBJ, iface);

    TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppobj);
    return IWebBrowser_QueryInterface((LPWEBBROWSER) This, riid, ppobj);
}

static ULONG WINAPI WBRUNOBJ_AddRef(LPRUNNABLEOBJECT iface)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_RUNOBJ, iface);
    TRACE("(%p)->()\n", iface);
    return IWebBrowser_AddRef((LPWEBBROWSER) This);
}

static ULONG WINAPI WBRUNOBJ_Release(LPRUNNABLEOBJECT iface)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl_RUNOBJ, iface);
    TRACE("(%p)->()\n", iface);
    return IWebBrowser_Release((LPWEBBROWSER) This);
}

static HRESULT WINAPI WBRUNOBJ_GetRunningClass(LPRUNNABLEOBJECT iface, LPCLSID lpClsid)
{
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WBRUNOBJ_Run(LPRUNNABLEOBJECT iface, LPBINDCTX pbc)
{
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static BOOL WINAPI WBRUNOBJ_IsRunning(LPRUNNABLEOBJECT iface)
{
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WBRUNOBJ_LockRunning(LPRUNNABLEOBJECT iface, BOOL fLock, BOOL fLastUnlockCloses)
{
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WBRUNOBJ_SetContainedObject(LPRUNNABLEOBJECT iface, BOOL fContainer)
{
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}


/**********************************************************************
 * IRunnableObject virtual function table for WebBrowser class
 */

ICOM_VTABLE(IRunnableObject) WBRUNOBJ_Vtbl =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    WBRUNOBJ_QueryInterface,
    WBRUNOBJ_AddRef,
    WBRUNOBJ_Release,
    WBRUNOBJ_GetRunningClass,
    WBRUNOBJ_Run,
    WBRUNOBJ_IsRunning,
    WBRUNOBJ_LockRunning,
    WBRUNOBJ_SetContainedObject
};


