4 * Copyright 1998 Eric Kohl
5 * Copyright 1999 Francis Beaudet
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
37 #define INITIAL_SINKS 10
39 /**************************************************************************
40 * OleAdviseHolderImpl Implementation
42 typedef struct OleAdviseHolderImpl
44 const IOleAdviseHolderVtbl
*lpVtbl
;
49 IAdviseSink
** arrayOfSinks
;
51 } OleAdviseHolderImpl
;
53 static HRESULT
EnumOleSTATDATA_Construct(OleAdviseHolderImpl
*pOleAdviseHolder
, ULONG index
, IEnumSTATDATA
**ppenum
);
57 const IEnumSTATDATAVtbl
*lpvtbl
;
61 OleAdviseHolderImpl
*pOleAdviseHolder
;
64 static HRESULT WINAPI
EnumOleSTATDATA_QueryInterface(
65 IEnumSTATDATA
*iface
, REFIID riid
, void **ppv
)
67 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppv
);
68 if (IsEqualIID(riid
, &IID_IUnknown
) ||
69 IsEqualIID(riid
, &IID_IEnumSTATDATA
))
71 IUnknown_AddRef(iface
);
78 static ULONG WINAPI
EnumOleSTATDATA_AddRef(
81 EnumOleSTATDATA
*This
= (EnumOleSTATDATA
*)iface
;
83 return InterlockedIncrement(&This
->ref
);
86 static ULONG WINAPI
EnumOleSTATDATA_Release(
89 EnumOleSTATDATA
*This
= (EnumOleSTATDATA
*)iface
;
90 LONG refs
= InterlockedDecrement(&This
->ref
);
94 IOleAdviseHolder_Release((IOleAdviseHolder
*)This
->pOleAdviseHolder
);
95 HeapFree(GetProcessHeap(), 0, This
);
100 static HRESULT WINAPI
EnumOleSTATDATA_Next(
101 IEnumSTATDATA
*iface
, ULONG celt
, LPSTATDATA rgelt
,
104 EnumOleSTATDATA
*This
= (EnumOleSTATDATA
*)iface
;
107 TRACE("(%d, %p, %p)\n", celt
, rgelt
, pceltFetched
);
112 for (; celt
; celt
--, rgelt
++)
114 while ((This
->index
< This
->pOleAdviseHolder
->maxSinks
) &&
115 !This
->pOleAdviseHolder
->arrayOfSinks
[This
->index
])
119 if (This
->index
>= This
->pOleAdviseHolder
->maxSinks
)
125 memset(&rgelt
->formatetc
, 0, sizeof(rgelt
->formatetc
));
127 rgelt
->pAdvSink
= This
->pOleAdviseHolder
->arrayOfSinks
[This
->index
];
128 IAdviseSink_AddRef(rgelt
->pAdvSink
);
129 rgelt
->dwConnection
= This
->index
;
138 static HRESULT WINAPI
EnumOleSTATDATA_Skip(
139 IEnumSTATDATA
*iface
, ULONG celt
)
141 EnumOleSTATDATA
*This
= (EnumOleSTATDATA
*)iface
;
143 TRACE("(%d)\n", celt
);
147 while ((This
->index
< This
->pOleAdviseHolder
->maxSinks
) &&
148 !This
->pOleAdviseHolder
->arrayOfSinks
[This
->index
])
152 if (This
->index
>= This
->pOleAdviseHolder
->maxSinks
)
159 static HRESULT WINAPI
EnumOleSTATDATA_Reset(
160 IEnumSTATDATA
*iface
)
162 EnumOleSTATDATA
*This
= (EnumOleSTATDATA
*)iface
;
170 static HRESULT WINAPI
EnumOleSTATDATA_Clone(
171 IEnumSTATDATA
*iface
,
172 IEnumSTATDATA
**ppenum
)
174 EnumOleSTATDATA
*This
= (EnumOleSTATDATA
*)iface
;
175 return EnumOleSTATDATA_Construct(This
->pOleAdviseHolder
, This
->index
, ppenum
);
178 static const IEnumSTATDATAVtbl EnumOleSTATDATA_VTable
=
180 EnumOleSTATDATA_QueryInterface
,
181 EnumOleSTATDATA_AddRef
,
182 EnumOleSTATDATA_Release
,
183 EnumOleSTATDATA_Next
,
184 EnumOleSTATDATA_Skip
,
185 EnumOleSTATDATA_Reset
,
186 EnumOleSTATDATA_Clone
189 static HRESULT
EnumOleSTATDATA_Construct(OleAdviseHolderImpl
*pOleAdviseHolder
, ULONG index
, IEnumSTATDATA
**ppenum
)
191 EnumOleSTATDATA
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
193 return E_OUTOFMEMORY
;
194 This
->lpvtbl
= &EnumOleSTATDATA_VTable
;
197 This
->pOleAdviseHolder
= pOleAdviseHolder
;
198 IOleAdviseHolder_AddRef((IOleAdviseHolder
*)pOleAdviseHolder
);
199 *ppenum
= (IEnumSTATDATA
*)&This
->lpvtbl
;
203 /**************************************************************************
204 * OleAdviseHolderImpl_Destructor
206 static void OleAdviseHolderImpl_Destructor(
207 OleAdviseHolderImpl
* ptrToDestroy
)
210 TRACE("%p\n", ptrToDestroy
);
212 for (index
= 0; index
< ptrToDestroy
->maxSinks
; index
++)
214 if (ptrToDestroy
->arrayOfSinks
[index
]!=0)
216 IAdviseSink_Release(ptrToDestroy
->arrayOfSinks
[index
]);
217 ptrToDestroy
->arrayOfSinks
[index
] = NULL
;
221 HeapFree(GetProcessHeap(),
223 ptrToDestroy
->arrayOfSinks
);
226 HeapFree(GetProcessHeap(),
231 /**************************************************************************
232 * OleAdviseHolderImpl_QueryInterface
234 static HRESULT WINAPI
OleAdviseHolderImpl_QueryInterface(
235 LPOLEADVISEHOLDER iface
,
239 OleAdviseHolderImpl
*This
= (OleAdviseHolderImpl
*)iface
;
240 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
249 if (IsEqualIID(riid
, &IID_IUnknown
))
254 else if(IsEqualIID(riid
, &IID_IOleAdviseHolder
))
256 /* IOleAdviseHolder */
257 *ppvObj
= (IOleAdviseHolder
*) This
;
261 return E_NOINTERFACE
;
264 * A successful QI always increments the reference count.
266 IUnknown_AddRef((IUnknown
*)*ppvObj
);
271 /******************************************************************************
272 * OleAdviseHolderImpl_AddRef
274 static ULONG WINAPI
OleAdviseHolderImpl_AddRef(
275 LPOLEADVISEHOLDER iface
)
277 OleAdviseHolderImpl
*This
= (OleAdviseHolderImpl
*)iface
;
278 ULONG ref
= InterlockedIncrement(&This
->ref
);
280 TRACE("(%p)->(ref=%d)\n", This
, ref
- 1);
285 /******************************************************************************
286 * OleAdviseHolderImpl_Release
288 static ULONG WINAPI
OleAdviseHolderImpl_Release(
289 LPOLEADVISEHOLDER iface
)
291 OleAdviseHolderImpl
*This
= (OleAdviseHolderImpl
*)iface
;
293 TRACE("(%p)->(ref=%d)\n", This
, This
->ref
);
294 ref
= InterlockedDecrement(&This
->ref
);
296 if (ref
== 0) OleAdviseHolderImpl_Destructor(This
);
301 /******************************************************************************
302 * OleAdviseHolderImpl_Advise
304 static HRESULT WINAPI
OleAdviseHolderImpl_Advise(
305 LPOLEADVISEHOLDER iface
,
306 IAdviseSink
* pAdvise
,
307 DWORD
* pdwConnection
)
311 OleAdviseHolderImpl
*This
= (OleAdviseHolderImpl
*)iface
;
313 TRACE("(%p)->(%p, %p)\n", This
, pAdvise
, pdwConnection
);
318 if (pdwConnection
==NULL
)
324 * Find a free spot in the array.
326 for (index
= 0; index
< This
->maxSinks
; index
++)
328 if (This
->arrayOfSinks
[index
]==NULL
)
333 * If the array is full, we need to grow it.
335 if (index
== This
->maxSinks
)
339 This
->maxSinks
+=INITIAL_SINKS
;
341 This
->arrayOfSinks
= HeapReAlloc(GetProcessHeap(),
344 This
->maxSinks
*sizeof(IAdviseSink
*));
346 for (i
=index
;i
< This
->maxSinks
; i
++)
347 This
->arrayOfSinks
[i
]=0;
353 This
->arrayOfSinks
[index
] = pAdvise
;
355 if (This
->arrayOfSinks
[index
]!=NULL
)
356 IAdviseSink_AddRef(This
->arrayOfSinks
[index
]);
359 * Return the index as the cookie.
360 * Since 0 is not a valid cookie, we will increment by
361 * 1 the index in the table.
363 *pdwConnection
= index
+1;
368 /******************************************************************************
369 * OleAdviseHolderImpl_Unadvise
371 static HRESULT WINAPI
OleAdviseHolderImpl_Unadvise(
372 LPOLEADVISEHOLDER iface
,
375 OleAdviseHolderImpl
*This
= (OleAdviseHolderImpl
*)iface
;
377 TRACE("(%p)->(%u)\n", This
, dwConnection
);
380 * So we don't return 0 as a cookie, the index was
381 * incremented by 1 in OleAdviseHolderImpl_Advise
382 * we have to compensate.
387 * Check for invalid cookies.
389 if (dwConnection
>= This
->maxSinks
)
390 return OLE_E_NOCONNECTION
;
392 if (This
->arrayOfSinks
[dwConnection
] == NULL
)
393 return OLE_E_NOCONNECTION
;
396 * Release the sink and mark the spot in the list as free.
398 IAdviseSink_Release(This
->arrayOfSinks
[dwConnection
]);
399 This
->arrayOfSinks
[dwConnection
] = NULL
;
404 /******************************************************************************
405 * OleAdviseHolderImpl_EnumAdvise
407 static HRESULT WINAPI
408 OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface
, IEnumSTATDATA
**ppenumAdvise
)
410 OleAdviseHolderImpl
*This
= (OleAdviseHolderImpl
*)iface
;
412 TRACE("(%p)->(%p)\n", This
, ppenumAdvise
);
414 *ppenumAdvise
= NULL
;
416 return EnumOleSTATDATA_Construct(This
, 0, ppenumAdvise
);
419 /******************************************************************************
420 * OleAdviseHolderImpl_SendOnRename
422 static HRESULT WINAPI
423 OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface
, IMoniker
*pmk
)
425 IEnumSTATDATA
*pEnum
;
428 TRACE("(%p)->(%p)\n", iface
, pmk
);
430 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
434 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
436 IAdviseSink_OnRename(statdata
.pAdvSink
, pmk
);
438 IAdviseSink_Release(statdata
.pAdvSink
);
440 IEnumSTATDATA_Release(pEnum
);
446 /******************************************************************************
447 * OleAdviseHolderImpl_SendOnSave
449 static HRESULT WINAPI
450 OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface
)
452 IEnumSTATDATA
*pEnum
;
455 TRACE("(%p)->()\n", iface
);
457 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
461 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
463 IAdviseSink_OnSave(statdata
.pAdvSink
);
465 IAdviseSink_Release(statdata
.pAdvSink
);
467 IEnumSTATDATA_Release(pEnum
);
473 /******************************************************************************
474 * OleAdviseHolderImpl_SendOnClose
476 static HRESULT WINAPI
477 OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface
)
479 IEnumSTATDATA
*pEnum
;
482 TRACE("(%p)->()\n", iface
);
484 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
488 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
490 IAdviseSink_OnClose(statdata
.pAdvSink
);
492 IAdviseSink_Release(statdata
.pAdvSink
);
494 IEnumSTATDATA_Release(pEnum
);
500 /**************************************************************************
501 * OleAdviseHolderImpl_VTable
503 static const IOleAdviseHolderVtbl oahvt
=
505 OleAdviseHolderImpl_QueryInterface
,
506 OleAdviseHolderImpl_AddRef
,
507 OleAdviseHolderImpl_Release
,
508 OleAdviseHolderImpl_Advise
,
509 OleAdviseHolderImpl_Unadvise
,
510 OleAdviseHolderImpl_EnumAdvise
,
511 OleAdviseHolderImpl_SendOnRename
,
512 OleAdviseHolderImpl_SendOnSave
,
513 OleAdviseHolderImpl_SendOnClose
516 /**************************************************************************
517 * OleAdviseHolderImpl_Constructor
520 static LPOLEADVISEHOLDER
OleAdviseHolderImpl_Constructor(void)
522 OleAdviseHolderImpl
* lpoah
;
525 lpoah
= HeapAlloc(GetProcessHeap(), 0, sizeof(OleAdviseHolderImpl
));
527 lpoah
->lpVtbl
= &oahvt
;
529 lpoah
->maxSinks
= INITIAL_SINKS
;
530 lpoah
->arrayOfSinks
= HeapAlloc(GetProcessHeap(),
532 lpoah
->maxSinks
* sizeof(IAdviseSink
*));
534 for (index
= 0; index
< lpoah
->maxSinks
; index
++)
535 lpoah
->arrayOfSinks
[index
]=0;
537 TRACE("returning %p\n", lpoah
);
538 return (LPOLEADVISEHOLDER
)lpoah
;
541 /**************************************************************************
542 * DataAdviseHolder Implementation
544 typedef struct DataAdviseConnection
{
548 DWORD remote_connection
;
549 } DataAdviseConnection
;
551 typedef struct DataAdviseHolder
553 const IDataAdviseHolderVtbl
*lpVtbl
;
557 DataAdviseConnection
* Connections
;
558 IDataObject
* delegate
;
561 /* this connection has also has been advised to the delegate data object */
562 #define WINE_ADVF_REMOTE 0x80000000
564 /******************************************************************************
565 * DataAdviseHolder_Destructor
567 static void DataAdviseHolder_Destructor(DataAdviseHolder
* ptrToDestroy
)
570 TRACE("%p\n", ptrToDestroy
);
572 for (index
= 0; index
< ptrToDestroy
->maxCons
; index
++)
574 if (ptrToDestroy
->Connections
[index
].sink
!= NULL
)
576 if (ptrToDestroy
->delegate
&&
577 (ptrToDestroy
->Connections
[index
].advf
& WINE_ADVF_REMOTE
))
578 IDataObject_DUnadvise(ptrToDestroy
->delegate
,
579 ptrToDestroy
->Connections
[index
].remote_connection
);
581 IAdviseSink_Release(ptrToDestroy
->Connections
[index
].sink
);
582 ptrToDestroy
->Connections
[index
].sink
= NULL
;
586 HeapFree(GetProcessHeap(), 0, ptrToDestroy
->Connections
);
587 HeapFree(GetProcessHeap(), 0, ptrToDestroy
);
590 /************************************************************************
591 * DataAdviseHolder_QueryInterface (IUnknown)
593 * See Windows documentation for more details on IUnknown methods.
595 static HRESULT WINAPI
DataAdviseHolder_QueryInterface(
596 IDataAdviseHolder
* iface
,
600 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
601 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),ppvObject
);
603 * Perform a sanity check on the parameters.
605 if ( (This
==0) || (ppvObject
==0) )
609 * Initialize the return parameter.
614 * Compare the riid with the interface IDs implemented by this object.
616 if ( (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) == 0) ||
617 (memcmp(&IID_IDataAdviseHolder
, riid
, sizeof(IID_IDataAdviseHolder
)) == 0) )
623 * Check that we obtained an interface.
627 return E_NOINTERFACE
;
631 * Query Interface always increases the reference count by one when it is
634 IUnknown_AddRef((IUnknown
*)*ppvObject
);
639 /************************************************************************
640 * DataAdviseHolder_AddRef (IUnknown)
642 * See Windows documentation for more details on IUnknown methods.
644 static ULONG WINAPI
DataAdviseHolder_AddRef(
645 IDataAdviseHolder
* iface
)
647 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
648 TRACE("(%p) (ref=%d)\n", This
, This
->ref
);
649 return InterlockedIncrement(&This
->ref
);
652 /************************************************************************
653 * DataAdviseHolder_Release (IUnknown)
655 * See Windows documentation for more details on IUnknown methods.
657 static ULONG WINAPI
DataAdviseHolder_Release(
658 IDataAdviseHolder
* iface
)
660 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
662 TRACE("(%p) (ref=%d)\n", This
, This
->ref
);
665 * Decrease the reference count on this object.
667 ref
= InterlockedDecrement(&This
->ref
);
670 * If the reference count goes down to 0, perform suicide.
672 if (ref
==0) DataAdviseHolder_Destructor(This
);
677 /************************************************************************
678 * DataAdviseHolder_Advise
681 static HRESULT WINAPI
DataAdviseHolder_Advise(
682 IDataAdviseHolder
* iface
,
683 IDataObject
* pDataObject
,
686 IAdviseSink
* pAdvise
,
687 DWORD
* pdwConnection
)
691 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
693 TRACE("(%p)->(%p, %p, %08x, %p, %p)\n", This
, pDataObject
, pFetc
, advf
,
694 pAdvise
, pdwConnection
);
698 if (pdwConnection
==NULL
)
704 * Find a free spot in the array.
706 for (index
= 0; index
< This
->maxCons
; index
++)
708 if (This
->Connections
[index
].sink
== NULL
)
713 * If the array is full, we need to grow it.
715 if (index
== This
->maxCons
)
717 This
->maxCons
+=INITIAL_SINKS
;
718 This
->Connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
720 This
->maxCons
*sizeof(DataAdviseConnection
));
725 This
->Connections
[index
].sink
= pAdvise
;
726 This
->Connections
[index
].advf
= advf
& ~WINE_ADVF_REMOTE
;
727 memcpy(&(This
->Connections
[index
].fmat
), pFetc
, sizeof(FORMATETC
));
730 This
->Connections
[index
].fmat
.ptd
= CoTaskMemAlloc(pFetc
->ptd
->tdSize
);
731 if (!This
->Connections
[index
].fmat
.ptd
)
733 IDataAdviseHolder_Unadvise(iface
, index
+ 1);
734 return E_OUTOFMEMORY
;
736 memcpy(This
->Connections
[index
].fmat
.ptd
, pFetc
->ptd
, pFetc
->ptd
->tdSize
);
739 if (This
->Connections
[index
].sink
!= NULL
) {
740 IAdviseSink_AddRef(This
->Connections
[index
].sink
);
742 /* if we are already connected advise the remote object */
747 hr
= IDataObject_DAdvise(This
->delegate
, &This
->Connections
[index
].fmat
,
748 This
->Connections
[index
].advf
,
749 This
->Connections
[index
].sink
,
750 &This
->Connections
[index
].remote_connection
);
753 IDataAdviseHolder_Unadvise(iface
, index
+ 1);
756 This
->Connections
[index
].advf
|= WINE_ADVF_REMOTE
;
758 else if(advf
& ADVF_PRIMEFIRST
)
759 /* only do this if we have no delegate, since in the above case the
760 * delegate will do the priming for us */
761 IDataAdviseHolder_SendOnDataChange(iface
, pDataObject
, 0, advf
);
764 * Return the index as the cookie.
765 * Since 0 is not a valid cookie, we will increment by
766 * 1 the index in the table.
768 *pdwConnection
= index
+1;
773 /******************************************************************************
774 * DataAdviseHolder_Unadvise
776 static HRESULT WINAPI
DataAdviseHolder_Unadvise(
777 IDataAdviseHolder
* iface
,
780 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
782 TRACE("(%p)->(%u)\n", This
, dwConnection
);
785 * So we don't return 0 as a cookie, the index was
786 * incremented by 1 in OleAdviseHolderImpl_Advise
787 * we have to compensate.
792 * Check for invalid cookies.
794 if (dwConnection
>= This
->maxCons
)
795 return OLE_E_NOCONNECTION
;
797 if (This
->Connections
[dwConnection
].sink
== NULL
)
798 return OLE_E_NOCONNECTION
;
800 if (This
->delegate
&& This
->Connections
[dwConnection
].advf
& WINE_ADVF_REMOTE
)
801 IDataObject_DUnadvise(This
->delegate
,
802 This
->Connections
[dwConnection
].remote_connection
);
805 * Release the sink and mark the spot in the list as free.
807 IAdviseSink_Release(This
->Connections
[dwConnection
].sink
);
808 memset(&(This
->Connections
[dwConnection
]), 0, sizeof(DataAdviseConnection
));
813 static HRESULT WINAPI
DataAdviseHolder_EnumAdvise(
814 IDataAdviseHolder
* iface
,
815 IEnumSTATDATA
** ppenumAdvise
)
817 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
819 FIXME("(%p)->(%p)\n", This
, ppenumAdvise
);
823 /******************************************************************************
824 * DataAdviseHolder_SendOnDataChange
826 static HRESULT WINAPI
DataAdviseHolder_SendOnDataChange(
827 IDataAdviseHolder
* iface
,
828 IDataObject
* pDataObject
,
832 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
837 TRACE("(%p)->(%p,%08x,%08x)\n", This
, pDataObject
, dwReserved
, advf
);
839 for(index
= 0; index
< This
->maxCons
; index
++) {
840 if(This
->Connections
[index
].sink
!= NULL
) {
841 memset(&stg
, 0, sizeof(stg
));
842 if(!(This
->Connections
[index
].advf
& ADVF_NODATA
)) {
843 TRACE("Calling IDataObject_GetData\n");
844 res
= IDataObject_GetData(pDataObject
,
845 &(This
->Connections
[index
].fmat
),
847 TRACE("returns %08x\n", res
);
849 TRACE("Calling IAdviseSink_OnDataChange\n");
850 IAdviseSink_OnDataChange(This
->Connections
[index
].sink
,
851 &(This
->Connections
[index
].fmat
),
853 TRACE("Done IAdviseSink_OnDataChange\n");
854 if(This
->Connections
[index
].advf
& ADVF_ONLYONCE
) {
855 TRACE("Removing connection\n");
856 DataAdviseHolder_Unadvise(iface
, index
+1);
863 /**************************************************************************
864 * DataAdviseHolderImpl_VTable
866 static const IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable
=
868 DataAdviseHolder_QueryInterface
,
869 DataAdviseHolder_AddRef
,
870 DataAdviseHolder_Release
,
871 DataAdviseHolder_Advise
,
872 DataAdviseHolder_Unadvise
,
873 DataAdviseHolder_EnumAdvise
,
874 DataAdviseHolder_SendOnDataChange
877 HRESULT
DataAdviseHolder_OnConnect(IDataAdviseHolder
*iface
, IDataObject
*pDelegate
)
879 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
883 for(index
= 0; index
< This
->maxCons
; index
++)
885 if(This
->Connections
[index
].sink
!= NULL
)
887 hr
= IDataObject_DAdvise(pDelegate
, &This
->Connections
[index
].fmat
,
888 This
->Connections
[index
].advf
,
889 This
->Connections
[index
].sink
,
890 &This
->Connections
[index
].remote_connection
);
891 if (FAILED(hr
)) break;
892 This
->Connections
[index
].advf
|= WINE_ADVF_REMOTE
;
895 This
->delegate
= pDelegate
;
899 void DataAdviseHolder_OnDisconnect(IDataAdviseHolder
*iface
)
901 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
904 for(index
= 0; index
< This
->maxCons
; index
++)
906 if((This
->Connections
[index
].sink
!= NULL
) &&
907 (This
->Connections
[index
].advf
& WINE_ADVF_REMOTE
))
909 IDataObject_DUnadvise(This
->delegate
,
910 This
->Connections
[index
].remote_connection
);
911 This
->Connections
[index
].advf
&= ~WINE_ADVF_REMOTE
;
914 This
->delegate
= NULL
;
917 /******************************************************************************
918 * DataAdviseHolder_Constructor
920 static IDataAdviseHolder
* DataAdviseHolder_Constructor(void)
922 DataAdviseHolder
* newHolder
;
924 newHolder
= HeapAlloc(GetProcessHeap(), 0, sizeof(DataAdviseHolder
));
926 newHolder
->lpVtbl
= &DataAdviseHolderImpl_VTable
;
928 newHolder
->maxCons
= INITIAL_SINKS
;
929 newHolder
->Connections
= HeapAlloc(GetProcessHeap(),
932 sizeof(DataAdviseConnection
));
933 newHolder
->delegate
= NULL
;
935 TRACE("returning %p\n", newHolder
);
936 return (IDataAdviseHolder
*)newHolder
;
939 /***********************************************************************
943 /***********************************************************************
944 * CreateOleAdviseHolder [OLE32.@]
946 HRESULT WINAPI
CreateOleAdviseHolder(
947 LPOLEADVISEHOLDER
*ppOAHolder
)
949 TRACE("(%p)\n", ppOAHolder
);
954 if (ppOAHolder
==NULL
)
957 *ppOAHolder
= OleAdviseHolderImpl_Constructor ();
959 if (*ppOAHolder
!= NULL
)
962 return E_OUTOFMEMORY
;
965 /******************************************************************************
966 * CreateDataAdviseHolder [OLE32.@]
968 HRESULT WINAPI
CreateDataAdviseHolder(
969 LPDATAADVISEHOLDER
* ppDAHolder
)
971 TRACE("(%p)\n", ppDAHolder
);
976 if (ppDAHolder
==NULL
)
979 *ppDAHolder
= DataAdviseHolder_Constructor();
981 if (*ppDAHolder
!= NULL
)
984 return E_OUTOFMEMORY
;