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 #include "compobj_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
39 #define INITIAL_SINKS 10
41 /**************************************************************************
42 * OleAdviseHolderImpl Implementation
44 typedef struct OleAdviseHolderImpl
46 const IOleAdviseHolderVtbl
*lpVtbl
;
51 IAdviseSink
** arrayOfSinks
;
53 } OleAdviseHolderImpl
;
55 static HRESULT
EnumOleSTATDATA_Construct(OleAdviseHolderImpl
*pOleAdviseHolder
, ULONG index
, IEnumSTATDATA
**ppenum
);
59 const IEnumSTATDATAVtbl
*lpvtbl
;
63 OleAdviseHolderImpl
*pOleAdviseHolder
;
66 static HRESULT WINAPI
EnumOleSTATDATA_QueryInterface(
67 IEnumSTATDATA
*iface
, REFIID riid
, void **ppv
)
69 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppv
);
70 if (IsEqualIID(riid
, &IID_IUnknown
) ||
71 IsEqualIID(riid
, &IID_IEnumSTATDATA
))
73 IUnknown_AddRef(iface
);
80 static ULONG WINAPI
EnumOleSTATDATA_AddRef(
83 EnumOleSTATDATA
*This
= (EnumOleSTATDATA
*)iface
;
85 return InterlockedIncrement(&This
->ref
);
88 static ULONG WINAPI
EnumOleSTATDATA_Release(
91 EnumOleSTATDATA
*This
= (EnumOleSTATDATA
*)iface
;
92 LONG refs
= InterlockedDecrement(&This
->ref
);
96 IOleAdviseHolder_Release((IOleAdviseHolder
*)This
->pOleAdviseHolder
);
97 HeapFree(GetProcessHeap(), 0, This
);
102 static HRESULT WINAPI
EnumOleSTATDATA_Next(
103 IEnumSTATDATA
*iface
, ULONG celt
, LPSTATDATA rgelt
,
106 EnumOleSTATDATA
*This
= (EnumOleSTATDATA
*)iface
;
109 TRACE("(%d, %p, %p)\n", celt
, rgelt
, pceltFetched
);
114 for (; celt
; celt
--, rgelt
++)
116 while ((This
->index
< This
->pOleAdviseHolder
->maxSinks
) &&
117 !This
->pOleAdviseHolder
->arrayOfSinks
[This
->index
])
121 if (This
->index
>= This
->pOleAdviseHolder
->maxSinks
)
127 memset(&rgelt
->formatetc
, 0, sizeof(rgelt
->formatetc
));
129 rgelt
->pAdvSink
= This
->pOleAdviseHolder
->arrayOfSinks
[This
->index
];
130 IAdviseSink_AddRef(rgelt
->pAdvSink
);
131 rgelt
->dwConnection
= This
->index
;
140 static HRESULT WINAPI
EnumOleSTATDATA_Skip(
141 IEnumSTATDATA
*iface
, ULONG celt
)
143 EnumOleSTATDATA
*This
= (EnumOleSTATDATA
*)iface
;
145 TRACE("(%d)\n", celt
);
149 while ((This
->index
< This
->pOleAdviseHolder
->maxSinks
) &&
150 !This
->pOleAdviseHolder
->arrayOfSinks
[This
->index
])
154 if (This
->index
>= This
->pOleAdviseHolder
->maxSinks
)
161 static HRESULT WINAPI
EnumOleSTATDATA_Reset(
162 IEnumSTATDATA
*iface
)
164 EnumOleSTATDATA
*This
= (EnumOleSTATDATA
*)iface
;
172 static HRESULT WINAPI
EnumOleSTATDATA_Clone(
173 IEnumSTATDATA
*iface
,
174 IEnumSTATDATA
**ppenum
)
176 EnumOleSTATDATA
*This
= (EnumOleSTATDATA
*)iface
;
177 return EnumOleSTATDATA_Construct(This
->pOleAdviseHolder
, This
->index
, ppenum
);
180 static const IEnumSTATDATAVtbl EnumOleSTATDATA_VTable
=
182 EnumOleSTATDATA_QueryInterface
,
183 EnumOleSTATDATA_AddRef
,
184 EnumOleSTATDATA_Release
,
185 EnumOleSTATDATA_Next
,
186 EnumOleSTATDATA_Skip
,
187 EnumOleSTATDATA_Reset
,
188 EnumOleSTATDATA_Clone
191 static HRESULT
EnumOleSTATDATA_Construct(OleAdviseHolderImpl
*pOleAdviseHolder
, ULONG index
, IEnumSTATDATA
**ppenum
)
193 EnumOleSTATDATA
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
195 return E_OUTOFMEMORY
;
196 This
->lpvtbl
= &EnumOleSTATDATA_VTable
;
199 This
->pOleAdviseHolder
= pOleAdviseHolder
;
200 IOleAdviseHolder_AddRef((IOleAdviseHolder
*)pOleAdviseHolder
);
201 *ppenum
= (IEnumSTATDATA
*)&This
->lpvtbl
;
205 /**************************************************************************
206 * OleAdviseHolderImpl_Destructor
208 static void OleAdviseHolderImpl_Destructor(
209 OleAdviseHolderImpl
* ptrToDestroy
)
212 TRACE("%p\n", ptrToDestroy
);
214 for (index
= 0; index
< ptrToDestroy
->maxSinks
; index
++)
216 if (ptrToDestroy
->arrayOfSinks
[index
]!=0)
218 IAdviseSink_Release(ptrToDestroy
->arrayOfSinks
[index
]);
219 ptrToDestroy
->arrayOfSinks
[index
] = NULL
;
223 HeapFree(GetProcessHeap(),
225 ptrToDestroy
->arrayOfSinks
);
228 HeapFree(GetProcessHeap(),
233 /**************************************************************************
234 * OleAdviseHolderImpl_QueryInterface
236 static HRESULT WINAPI
OleAdviseHolderImpl_QueryInterface(
237 LPOLEADVISEHOLDER iface
,
241 OleAdviseHolderImpl
*This
= (OleAdviseHolderImpl
*)iface
;
242 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
251 if (IsEqualIID(riid
, &IID_IUnknown
))
256 else if(IsEqualIID(riid
, &IID_IOleAdviseHolder
))
258 /* IOleAdviseHolder */
263 return E_NOINTERFACE
;
266 * A successful QI always increments the reference count.
268 IUnknown_AddRef((IUnknown
*)*ppvObj
);
273 /******************************************************************************
274 * OleAdviseHolderImpl_AddRef
276 static ULONG WINAPI
OleAdviseHolderImpl_AddRef(
277 LPOLEADVISEHOLDER iface
)
279 OleAdviseHolderImpl
*This
= (OleAdviseHolderImpl
*)iface
;
280 ULONG ref
= InterlockedIncrement(&This
->ref
);
282 TRACE("(%p)->(ref=%d)\n", This
, ref
- 1);
287 /******************************************************************************
288 * OleAdviseHolderImpl_Release
290 static ULONG WINAPI
OleAdviseHolderImpl_Release(
291 LPOLEADVISEHOLDER iface
)
293 OleAdviseHolderImpl
*This
= (OleAdviseHolderImpl
*)iface
;
295 TRACE("(%p)->(ref=%d)\n", This
, This
->ref
);
296 ref
= InterlockedDecrement(&This
->ref
);
298 if (ref
== 0) OleAdviseHolderImpl_Destructor(This
);
303 /******************************************************************************
304 * OleAdviseHolderImpl_Advise
306 static HRESULT WINAPI
OleAdviseHolderImpl_Advise(
307 LPOLEADVISEHOLDER iface
,
308 IAdviseSink
* pAdvise
,
309 DWORD
* pdwConnection
)
313 OleAdviseHolderImpl
*This
= (OleAdviseHolderImpl
*)iface
;
315 TRACE("(%p)->(%p, %p)\n", This
, pAdvise
, pdwConnection
);
320 if (pdwConnection
==NULL
)
326 * Find a free spot in the array.
328 for (index
= 0; index
< This
->maxSinks
; index
++)
330 if (This
->arrayOfSinks
[index
]==NULL
)
335 * If the array is full, we need to grow it.
337 if (index
== This
->maxSinks
)
341 This
->maxSinks
+=INITIAL_SINKS
;
343 This
->arrayOfSinks
= HeapReAlloc(GetProcessHeap(),
346 This
->maxSinks
*sizeof(IAdviseSink
*));
348 for (i
=index
;i
< This
->maxSinks
; i
++)
349 This
->arrayOfSinks
[i
]=0;
355 This
->arrayOfSinks
[index
] = pAdvise
;
357 if (This
->arrayOfSinks
[index
]!=NULL
)
358 IAdviseSink_AddRef(This
->arrayOfSinks
[index
]);
361 * Return the index as the cookie.
362 * Since 0 is not a valid cookie, we will increment by
363 * 1 the index in the table.
365 *pdwConnection
= index
+1;
370 /******************************************************************************
371 * OleAdviseHolderImpl_Unadvise
373 static HRESULT WINAPI
OleAdviseHolderImpl_Unadvise(
374 LPOLEADVISEHOLDER iface
,
377 OleAdviseHolderImpl
*This
= (OleAdviseHolderImpl
*)iface
;
379 TRACE("(%p)->(%u)\n", This
, dwConnection
);
382 * So we don't return 0 as a cookie, the index was
383 * incremented by 1 in OleAdviseHolderImpl_Advise
384 * we have to compensate.
389 * Check for invalid cookies.
391 if (dwConnection
>= This
->maxSinks
)
392 return OLE_E_NOCONNECTION
;
394 if (This
->arrayOfSinks
[dwConnection
] == NULL
)
395 return OLE_E_NOCONNECTION
;
398 * Release the sink and mark the spot in the list as free.
400 IAdviseSink_Release(This
->arrayOfSinks
[dwConnection
]);
401 This
->arrayOfSinks
[dwConnection
] = NULL
;
406 /******************************************************************************
407 * OleAdviseHolderImpl_EnumAdvise
409 static HRESULT WINAPI
410 OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface
, IEnumSTATDATA
**ppenumAdvise
)
412 OleAdviseHolderImpl
*This
= (OleAdviseHolderImpl
*)iface
;
414 TRACE("(%p)->(%p)\n", This
, ppenumAdvise
);
416 *ppenumAdvise
= NULL
;
418 return EnumOleSTATDATA_Construct(This
, 0, ppenumAdvise
);
421 /******************************************************************************
422 * OleAdviseHolderImpl_SendOnRename
424 static HRESULT WINAPI
425 OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface
, IMoniker
*pmk
)
427 IEnumSTATDATA
*pEnum
;
430 TRACE("(%p)->(%p)\n", iface
, pmk
);
432 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
436 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
438 IAdviseSink_OnRename(statdata
.pAdvSink
, pmk
);
440 IAdviseSink_Release(statdata
.pAdvSink
);
442 IEnumSTATDATA_Release(pEnum
);
448 /******************************************************************************
449 * OleAdviseHolderImpl_SendOnSave
451 static HRESULT WINAPI
452 OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface
)
454 IEnumSTATDATA
*pEnum
;
457 TRACE("(%p)->()\n", iface
);
459 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
463 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
465 IAdviseSink_OnSave(statdata
.pAdvSink
);
467 IAdviseSink_Release(statdata
.pAdvSink
);
469 IEnumSTATDATA_Release(pEnum
);
475 /******************************************************************************
476 * OleAdviseHolderImpl_SendOnClose
478 static HRESULT WINAPI
479 OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface
)
481 IEnumSTATDATA
*pEnum
;
484 TRACE("(%p)->()\n", iface
);
486 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
490 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
492 IAdviseSink_OnClose(statdata
.pAdvSink
);
494 IAdviseSink_Release(statdata
.pAdvSink
);
496 IEnumSTATDATA_Release(pEnum
);
502 /**************************************************************************
503 * OleAdviseHolderImpl_VTable
505 static const IOleAdviseHolderVtbl oahvt
=
507 OleAdviseHolderImpl_QueryInterface
,
508 OleAdviseHolderImpl_AddRef
,
509 OleAdviseHolderImpl_Release
,
510 OleAdviseHolderImpl_Advise
,
511 OleAdviseHolderImpl_Unadvise
,
512 OleAdviseHolderImpl_EnumAdvise
,
513 OleAdviseHolderImpl_SendOnRename
,
514 OleAdviseHolderImpl_SendOnSave
,
515 OleAdviseHolderImpl_SendOnClose
518 /**************************************************************************
519 * OleAdviseHolderImpl_Constructor
522 static LPOLEADVISEHOLDER
OleAdviseHolderImpl_Constructor(void)
524 OleAdviseHolderImpl
* lpoah
;
527 lpoah
= HeapAlloc(GetProcessHeap(), 0, sizeof(OleAdviseHolderImpl
));
529 lpoah
->lpVtbl
= &oahvt
;
531 lpoah
->maxSinks
= INITIAL_SINKS
;
532 lpoah
->arrayOfSinks
= HeapAlloc(GetProcessHeap(),
534 lpoah
->maxSinks
* sizeof(IAdviseSink
*));
536 for (index
= 0; index
< lpoah
->maxSinks
; index
++)
537 lpoah
->arrayOfSinks
[index
]=0;
539 TRACE("returning %p\n", lpoah
);
540 return (LPOLEADVISEHOLDER
)lpoah
;
543 /**************************************************************************
544 * DataAdviseHolder Implementation
546 typedef struct DataAdviseConnection
{
550 DWORD remote_connection
;
551 } DataAdviseConnection
;
553 typedef struct DataAdviseHolder
555 const IDataAdviseHolderVtbl
*lpVtbl
;
559 DataAdviseConnection
* Connections
;
560 IDataObject
* delegate
;
563 /* this connection has also has been advised to the delegate data object */
564 #define WINE_ADVF_REMOTE 0x80000000
566 /******************************************************************************
567 * DataAdviseHolder_Destructor
569 static void DataAdviseHolder_Destructor(DataAdviseHolder
* ptrToDestroy
)
572 TRACE("%p\n", ptrToDestroy
);
574 for (index
= 0; index
< ptrToDestroy
->maxCons
; index
++)
576 if (ptrToDestroy
->Connections
[index
].sink
!= NULL
)
578 if (ptrToDestroy
->delegate
&&
579 (ptrToDestroy
->Connections
[index
].advf
& WINE_ADVF_REMOTE
))
580 IDataObject_DUnadvise(ptrToDestroy
->delegate
,
581 ptrToDestroy
->Connections
[index
].remote_connection
);
583 IAdviseSink_Release(ptrToDestroy
->Connections
[index
].sink
);
584 ptrToDestroy
->Connections
[index
].sink
= NULL
;
588 HeapFree(GetProcessHeap(), 0, ptrToDestroy
->Connections
);
589 HeapFree(GetProcessHeap(), 0, ptrToDestroy
);
592 /************************************************************************
593 * DataAdviseHolder_QueryInterface (IUnknown)
595 * See Windows documentation for more details on IUnknown methods.
597 static HRESULT WINAPI
DataAdviseHolder_QueryInterface(
598 IDataAdviseHolder
* iface
,
602 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
603 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),ppvObject
);
605 * Perform a sanity check on the parameters.
607 if ( (This
==0) || (ppvObject
==0) )
611 * Initialize the return parameter.
616 * Compare the riid with the interface IDs implemented by this object.
618 if ( (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) == 0) ||
619 (memcmp(&IID_IDataAdviseHolder
, riid
, sizeof(IID_IDataAdviseHolder
)) == 0) )
625 * Check that we obtained an interface.
629 return E_NOINTERFACE
;
633 * Query Interface always increases the reference count by one when it is
636 IUnknown_AddRef((IUnknown
*)*ppvObject
);
641 /************************************************************************
642 * DataAdviseHolder_AddRef (IUnknown)
644 * See Windows documentation for more details on IUnknown methods.
646 static ULONG WINAPI
DataAdviseHolder_AddRef(
647 IDataAdviseHolder
* iface
)
649 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
650 TRACE("(%p) (ref=%d)\n", This
, This
->ref
);
651 return InterlockedIncrement(&This
->ref
);
654 /************************************************************************
655 * DataAdviseHolder_Release (IUnknown)
657 * See Windows documentation for more details on IUnknown methods.
659 static ULONG WINAPI
DataAdviseHolder_Release(
660 IDataAdviseHolder
* iface
)
662 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
664 TRACE("(%p) (ref=%d)\n", This
, This
->ref
);
667 * Decrease the reference count on this object.
669 ref
= InterlockedDecrement(&This
->ref
);
672 * If the reference count goes down to 0, perform suicide.
674 if (ref
==0) DataAdviseHolder_Destructor(This
);
679 /************************************************************************
680 * DataAdviseHolder_Advise
683 static HRESULT WINAPI
DataAdviseHolder_Advise(
684 IDataAdviseHolder
* iface
,
685 IDataObject
* pDataObject
,
688 IAdviseSink
* pAdvise
,
689 DWORD
* pdwConnection
)
693 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
695 TRACE("(%p)->(%p, %p, %08x, %p, %p)\n", This
, pDataObject
, pFetc
, advf
,
696 pAdvise
, pdwConnection
);
700 if (pdwConnection
==NULL
)
706 * Find a free spot in the array.
708 for (index
= 0; index
< This
->maxCons
; index
++)
710 if (This
->Connections
[index
].sink
== NULL
)
715 * If the array is full, we need to grow it.
717 if (index
== This
->maxCons
)
719 This
->maxCons
+=INITIAL_SINKS
;
720 This
->Connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
722 This
->maxCons
*sizeof(DataAdviseConnection
));
727 This
->Connections
[index
].sink
= pAdvise
;
728 This
->Connections
[index
].advf
= advf
& ~WINE_ADVF_REMOTE
;
729 This
->Connections
[index
].fmat
= *pFetc
;
732 This
->Connections
[index
].fmat
.ptd
= CoTaskMemAlloc(pFetc
->ptd
->tdSize
);
733 if (!This
->Connections
[index
].fmat
.ptd
)
735 IDataAdviseHolder_Unadvise(iface
, index
+ 1);
736 return E_OUTOFMEMORY
;
738 memcpy(This
->Connections
[index
].fmat
.ptd
, pFetc
->ptd
, pFetc
->ptd
->tdSize
);
741 if (This
->Connections
[index
].sink
!= NULL
) {
742 IAdviseSink_AddRef(This
->Connections
[index
].sink
);
744 /* if we are already connected advise the remote object */
749 hr
= IDataObject_DAdvise(This
->delegate
, &This
->Connections
[index
].fmat
,
750 This
->Connections
[index
].advf
,
751 This
->Connections
[index
].sink
,
752 &This
->Connections
[index
].remote_connection
);
755 IDataAdviseHolder_Unadvise(iface
, index
+ 1);
758 This
->Connections
[index
].advf
|= WINE_ADVF_REMOTE
;
760 else if(advf
& ADVF_PRIMEFIRST
)
761 /* only do this if we have no delegate, since in the above case the
762 * delegate will do the priming for us */
763 IDataAdviseHolder_SendOnDataChange(iface
, pDataObject
, 0, advf
);
766 * Return the index as the cookie.
767 * Since 0 is not a valid cookie, we will increment by
768 * 1 the index in the table.
770 *pdwConnection
= index
+1;
775 /******************************************************************************
776 * DataAdviseHolder_Unadvise
778 static HRESULT WINAPI
DataAdviseHolder_Unadvise(
779 IDataAdviseHolder
* iface
,
782 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
784 TRACE("(%p)->(%u)\n", This
, dwConnection
);
787 * So we don't return 0 as a cookie, the index was
788 * incremented by 1 in OleAdviseHolderImpl_Advise
789 * we have to compensate.
794 * Check for invalid cookies.
796 if (dwConnection
>= This
->maxCons
)
797 return OLE_E_NOCONNECTION
;
799 if (This
->Connections
[dwConnection
].sink
== NULL
)
800 return OLE_E_NOCONNECTION
;
802 if (This
->delegate
&& This
->Connections
[dwConnection
].advf
& WINE_ADVF_REMOTE
)
803 IDataObject_DUnadvise(This
->delegate
,
804 This
->Connections
[dwConnection
].remote_connection
);
807 * Release the sink and mark the spot in the list as free.
809 IAdviseSink_Release(This
->Connections
[dwConnection
].sink
);
810 memset(&(This
->Connections
[dwConnection
]), 0, sizeof(DataAdviseConnection
));
815 static HRESULT WINAPI
DataAdviseHolder_EnumAdvise(
816 IDataAdviseHolder
* iface
,
817 IEnumSTATDATA
** ppenumAdvise
)
819 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
821 FIXME("(%p)->(%p)\n", This
, ppenumAdvise
);
825 /******************************************************************************
826 * DataAdviseHolder_SendOnDataChange
828 static HRESULT WINAPI
DataAdviseHolder_SendOnDataChange(
829 IDataAdviseHolder
* iface
,
830 IDataObject
* pDataObject
,
834 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
839 TRACE("(%p)->(%p,%08x,%08x)\n", This
, pDataObject
, dwReserved
, advf
);
841 for(index
= 0; index
< This
->maxCons
; index
++) {
842 if(This
->Connections
[index
].sink
!= NULL
) {
843 memset(&stg
, 0, sizeof(stg
));
844 if(!(This
->Connections
[index
].advf
& ADVF_NODATA
)) {
845 TRACE("Calling IDataObject_GetData\n");
846 res
= IDataObject_GetData(pDataObject
,
847 &(This
->Connections
[index
].fmat
),
849 TRACE("returns %08x\n", res
);
851 TRACE("Calling IAdviseSink_OnDataChange\n");
852 IAdviseSink_OnDataChange(This
->Connections
[index
].sink
,
853 &(This
->Connections
[index
].fmat
),
855 TRACE("Done IAdviseSink_OnDataChange\n");
856 if(This
->Connections
[index
].advf
& ADVF_ONLYONCE
) {
857 TRACE("Removing connection\n");
858 DataAdviseHolder_Unadvise(iface
, index
+1);
865 /**************************************************************************
866 * DataAdviseHolderImpl_VTable
868 static const IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable
=
870 DataAdviseHolder_QueryInterface
,
871 DataAdviseHolder_AddRef
,
872 DataAdviseHolder_Release
,
873 DataAdviseHolder_Advise
,
874 DataAdviseHolder_Unadvise
,
875 DataAdviseHolder_EnumAdvise
,
876 DataAdviseHolder_SendOnDataChange
879 HRESULT
DataAdviseHolder_OnConnect(IDataAdviseHolder
*iface
, IDataObject
*pDelegate
)
881 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
885 for(index
= 0; index
< This
->maxCons
; index
++)
887 if(This
->Connections
[index
].sink
!= NULL
)
889 hr
= IDataObject_DAdvise(pDelegate
, &This
->Connections
[index
].fmat
,
890 This
->Connections
[index
].advf
,
891 This
->Connections
[index
].sink
,
892 &This
->Connections
[index
].remote_connection
);
893 if (FAILED(hr
)) break;
894 This
->Connections
[index
].advf
|= WINE_ADVF_REMOTE
;
897 This
->delegate
= pDelegate
;
901 void DataAdviseHolder_OnDisconnect(IDataAdviseHolder
*iface
)
903 DataAdviseHolder
*This
= (DataAdviseHolder
*)iface
;
906 for(index
= 0; index
< This
->maxCons
; index
++)
908 if((This
->Connections
[index
].sink
!= NULL
) &&
909 (This
->Connections
[index
].advf
& WINE_ADVF_REMOTE
))
911 IDataObject_DUnadvise(This
->delegate
,
912 This
->Connections
[index
].remote_connection
);
913 This
->Connections
[index
].advf
&= ~WINE_ADVF_REMOTE
;
916 This
->delegate
= NULL
;
919 /******************************************************************************
920 * DataAdviseHolder_Constructor
922 static IDataAdviseHolder
* DataAdviseHolder_Constructor(void)
924 DataAdviseHolder
* newHolder
;
926 newHolder
= HeapAlloc(GetProcessHeap(), 0, sizeof(DataAdviseHolder
));
928 newHolder
->lpVtbl
= &DataAdviseHolderImpl_VTable
;
930 newHolder
->maxCons
= INITIAL_SINKS
;
931 newHolder
->Connections
= HeapAlloc(GetProcessHeap(),
934 sizeof(DataAdviseConnection
));
935 newHolder
->delegate
= NULL
;
937 TRACE("returning %p\n", newHolder
);
938 return (IDataAdviseHolder
*)newHolder
;
941 /***********************************************************************
945 /***********************************************************************
946 * CreateOleAdviseHolder [OLE32.@]
948 HRESULT WINAPI
CreateOleAdviseHolder(
949 LPOLEADVISEHOLDER
*ppOAHolder
)
951 TRACE("(%p)\n", ppOAHolder
);
956 if (ppOAHolder
==NULL
)
959 *ppOAHolder
= OleAdviseHolderImpl_Constructor ();
961 if (*ppOAHolder
!= NULL
)
964 return E_OUTOFMEMORY
;
967 /******************************************************************************
968 * CreateDataAdviseHolder [OLE32.@]
970 HRESULT WINAPI
CreateDataAdviseHolder(
971 LPDATAADVISEHOLDER
* ppDAHolder
)
973 TRACE("(%p)\n", ppDAHolder
);
978 if (ppDAHolder
==NULL
)
981 *ppDAHolder
= DataAdviseHolder_Constructor();
983 if (*ppDAHolder
!= NULL
)
986 return E_OUTOFMEMORY
;