Delegate advises to the remote object to enable the client to receive
data change notifications.
diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index 8364c6c..790042e 100644
--- a/dlls/ole32/compobj_private.h
+++ b/dlls/ole32/compobj_private.h
@@ -263,4 +263,8 @@
#define CHARS_IN_GUID 39 /* including NULL */
+/* Exported non-interface Data Advise Holder functions */
+HRESULT DataAdviseHolder_OnConnect(IDataAdviseHolder *iface, IDataObject *pDelegate);
+void DataAdviseHolder_OnDisconnect(IDataAdviseHolder *iface);
+
#endif /* __WINE_OLE_COMPOBJ_H */
diff --git a/dlls/ole32/defaulthandler.c b/dlls/ole32/defaulthandler.c
index 8ce836e..32e564c 100644
--- a/dlls/ole32/defaulthandler.c
+++ b/dlls/ole32/defaulthandler.c
@@ -55,8 +55,11 @@
#include "winbase.h"
#include "winuser.h"
#include "winerror.h"
-#include "wine/unicode.h"
#include "ole2.h"
+
+#include "compobj_private.h"
+
+#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
@@ -108,6 +111,8 @@
IOleObject *pOleDelegate;
/* IPersistStorage delegate */
IPersistStorage *pPSDelegate;
+ /* IDataObject delegate */
+ IDataObject *pDataDelegate;
/* connection cookie for the advise on the delegate OLE object */
DWORD dwAdvConn;
@@ -411,6 +416,12 @@
/* FIXME: call IOleCache_OnStop */
+ DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
+ if (This->pDataDelegate)
+ {
+ IDataObject_Release(This->pDataDelegate);
+ This->pDataDelegate = NULL;
+ }
if (This->pPSDelegate)
{
IPersistStorage_Release(This->pPSDelegate);
@@ -1284,6 +1295,13 @@
* - IOleCache_OnRun
*/
+ if (SUCCEEDED(hr))
+ hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
+ (void **)&This->pDataDelegate);
+
+ if (SUCCEEDED(hr) && This->dataAdviseHolder)
+ hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
+
if (FAILED(hr))
DefaultHandler_Stop(This);
@@ -1558,6 +1576,7 @@
This->containerObj = NULL;
This->pOleDelegate = NULL;
This->pPSDelegate = NULL;
+ This->pDataDelegate = NULL;
This->dwAdvConn = 0;
diff --git a/dlls/ole32/oleobj.c b/dlls/ole32/oleobj.c
index 0c77121..3943aec 100644
--- a/dlls/ole32/oleobj.c
+++ b/dlls/ole32/oleobj.c
@@ -351,6 +351,7 @@
IAdviseSink *sink;
FORMATETC fmat;
DWORD advf;
+ DWORD remote_connection;
} DataAdviseConnection;
typedef struct DataAdviseHolder
@@ -362,6 +363,9 @@
DataAdviseConnection* Connections;
} DataAdviseHolder;
+/* this connection has also has been advised to the delegate data object */
+#define WINE_ADVF_REMOTE 0x80000000
+
/******************************************************************************
* DataAdviseHolder_Destructor
*/
@@ -520,7 +524,7 @@
*/
This->Connections[index].sink = pAdvise;
memcpy(&(This->Connections[index].fmat), pFetc, sizeof(FORMATETC));
- This->Connections[index].advf = advf;
+ This->Connections[index].advf = advf & ~WINE_ADVF_REMOTE;
if (This->Connections[index].sink != NULL) {
IAdviseSink_AddRef(This->Connections[index].sink);
@@ -636,6 +640,33 @@
DataAdviseHolder_SendOnDataChange
};
+HRESULT DataAdviseHolder_OnConnect(IDataAdviseHolder *iface, IDataObject *pDelegate)
+{
+ DataAdviseHolder *This = (DataAdviseHolder *)iface;
+ DWORD index;
+ HRESULT hr = S_OK;
+
+ for(index = 0; index < This->maxCons; index++)
+ {
+ if(This->Connections[index].sink != NULL)
+ {
+ hr = IDataObject_DAdvise(pDelegate, &This->Connections[index].fmat,
+ This->Connections[index].advf,
+ This->Connections[index].sink,
+ &This->Connections[index].remote_connection);
+ if (FAILED(hr)) break;
+ This->Connections[index].advf |= WINE_ADVF_REMOTE;
+ }
+ }
+ /* FIXME: store pDelegate somewhere */
+ return hr;
+}
+
+void DataAdviseHolder_OnDisconnect(IDataAdviseHolder *iface)
+{
+ /* FIXME: Unadvise all remote interfaces */
+}
+
/******************************************************************************
* DataAdviseHolder_Constructor
*/