shell32: Add IObjectWithSite implementation to the ExplorerBrowser control.
diff --git a/dlls/shell32/ebrowser.c b/dlls/shell32/ebrowser.c
index 3ba15b9..b243aa0 100644
--- a/dlls/shell32/ebrowser.c
+++ b/dlls/shell32/ebrowser.c
@@ -52,6 +52,7 @@
const IExplorerBrowserVtbl *lpVtbl;
const IShellBrowserVtbl *lpsbVtbl;
const ICommDlgBrowser3Vtbl *lpcdb3Vtbl;
+ const IObjectWithSiteVtbl *lpowsVtbl;
LONG ref;
BOOL destroyed;
@@ -70,6 +71,8 @@
IShellView *psv;
RECT sv_rc;
LPITEMIDLIST current_pidl;
+
+ IUnknown *punk_site;
} ExplorerBrowserImpl;
/**************************************************************************
@@ -328,6 +331,28 @@
return hr;
}
+static void get_interfaces_from_site(ExplorerBrowserImpl *This)
+{
+ IServiceProvider *psp;
+ HRESULT hr;
+
+ /* Calling this with This->punk_site set to NULL should properly
+ * release any previously fetched interfaces.
+ */
+
+ if(This->punk_site)
+ {
+ hr = IUnknown_QueryInterface(This->punk_site, &IID_IServiceProvider, (void**)&psp);
+ if(SUCCEEDED(hr))
+ {
+ FIXME("Not requesting any interfaces.\n");
+ IServiceProvider_Release(psp);
+ }
+ else
+ ERR("Failed to get IServiceProvider from site.\n");
+ }
+}
+
/**************************************************************************
* Main window related functions.
*/
@@ -389,6 +414,10 @@
{
*ppvObject = &This->lpcdb3Vtbl;
}
+ else if(IsEqualIID(riid, &IID_IObjectWithSite))
+ {
+ *ppvObject = &This->lpowsVtbl;
+ }
if(*ppvObject)
{
@@ -421,6 +450,8 @@
if(!This->destroyed)
IExplorerBrowser_Destroy(iface);
+ IObjectWithSite_SetSite((IObjectWithSite*)&This->lpowsVtbl, NULL);
+
HeapFree(GetProcessHeap(), 0, This);
return 0;
}
@@ -731,6 +762,8 @@
return E_FAIL;
}
+ get_interfaces_from_site(This);
+
/* Only browse if the new pidl differs from the old */
if(!ILIsEqual(This->current_pidl, absolute_pidl))
{
@@ -1204,6 +1237,76 @@
ICommDlgBrowser3_fnOnPreviewCreated
};
+/**************************************************************************
+ * IObjectWithSite Implementation
+ */
+
+static inline ExplorerBrowserImpl *impl_from_IObjectWithSite(IObjectWithSite *iface)
+{
+ return (ExplorerBrowserImpl *)((char*)iface - FIELD_OFFSET(ExplorerBrowserImpl, lpowsVtbl));
+}
+
+static HRESULT WINAPI IObjectWithSite_fnQueryInterface(IObjectWithSite *iface,
+ REFIID riid, void **ppvObject)
+{
+ ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
+ TRACE("%p\n", This);
+ return IUnknown_QueryInterface((IUnknown*)This, riid, ppvObject);
+}
+
+static ULONG WINAPI IObjectWithSite_fnAddRef(IObjectWithSite *iface)
+{
+ ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
+ TRACE("%p\n", This);
+ return IUnknown_AddRef((IUnknown*)This);
+}
+
+static ULONG WINAPI IObjectWithSite_fnRelease(IObjectWithSite *iface)
+{
+ ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
+ TRACE("%p\n", This);
+ return IUnknown_Release((IUnknown*)This);
+}
+
+static HRESULT WINAPI IObjectWithSite_fnSetSite(IObjectWithSite *iface, IUnknown *punk_site)
+{
+ ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
+ TRACE("%p (%p)\n", This, punk_site);
+
+ if(This->punk_site)
+ {
+ IUnknown_Release(This->punk_site);
+ This->punk_site = NULL;
+ get_interfaces_from_site(This);
+ }
+
+ This->punk_site = punk_site;
+
+ if(This->punk_site)
+ IUnknown_AddRef(This->punk_site);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI IObjectWithSite_fnGetSite(IObjectWithSite *iface, REFIID riid, void **ppvSite)
+{
+ ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
+ TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvSite);
+
+ if(!This->punk_site)
+ return E_FAIL;
+
+ return IUnknown_QueryInterface(This->punk_site, riid, ppvSite);
+}
+
+static const IObjectWithSiteVtbl vt_IObjectWithSite = {
+ IObjectWithSite_fnQueryInterface,
+ IObjectWithSite_fnAddRef,
+ IObjectWithSite_fnRelease,
+ IObjectWithSite_fnSetSite,
+ IObjectWithSite_fnGetSite
+};
+
HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
{
ExplorerBrowserImpl *eb;
@@ -1221,6 +1324,7 @@
eb->lpVtbl = &vt_IExplorerBrowser;
eb->lpsbVtbl = &vt_IShellBrowser;
eb->lpcdb3Vtbl = &vt_ICommDlgBrowser3;
+ eb->lpowsVtbl = &vt_IObjectWithSite;
list_init(&eb->event_clients);
list_init(&eb->travellog);