2 * Implementation of event-related interfaces for WMP control:
4 * - IConnectionPointContainer
7 * Copyright 2001 John R. Sheets (for CodeWeavers)
8 * Copyright 2006 Jacek Caban for CodeWeavers
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wmp_private.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(wmp
);
31 static inline WindowsMediaPlayer
*impl_from_IConnectionPointContainer(IConnectionPointContainer
*iface
)
33 return CONTAINING_RECORD(iface
, WindowsMediaPlayer
, IConnectionPointContainer_iface
);
36 static HRESULT WINAPI
ConnectionPointContainer_QueryInterface(IConnectionPointContainer
*iface
,
37 REFIID riid
, LPVOID
*ppv
)
39 WindowsMediaPlayer
*This
= impl_from_IConnectionPointContainer(iface
);
40 return IOleObject_QueryInterface(&This
->IOleObject_iface
, riid
, ppv
);
43 static ULONG WINAPI
ConnectionPointContainer_AddRef(IConnectionPointContainer
*iface
)
45 WindowsMediaPlayer
*This
= impl_from_IConnectionPointContainer(iface
);
46 return IOleObject_AddRef(&This
->IOleObject_iface
);
49 static ULONG WINAPI
ConnectionPointContainer_Release(IConnectionPointContainer
*iface
)
51 WindowsMediaPlayer
*This
= impl_from_IConnectionPointContainer(iface
);
52 return IOleObject_Release(&This
->IOleObject_iface
);
55 static HRESULT WINAPI
ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer
*iface
,
56 IEnumConnectionPoints
**ppEnum
)
58 WindowsMediaPlayer
*This
= impl_from_IConnectionPointContainer(iface
);
59 FIXME("(%p)->(%p)\n", This
, ppEnum
);
63 static HRESULT WINAPI
ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer
*iface
,
64 REFIID riid
, IConnectionPoint
**ppCP
){
65 WindowsMediaPlayer
*This
= impl_from_IConnectionPointContainer(iface
);
68 WARN("ppCP == NULL\n");
74 if(IsEqualGUID(&IID__WMPOCXEvents
, riid
)) {
75 TRACE("(%p)->(IID__WMPOCXEvents %p)\n", This
, ppCP
);
76 *ppCP
= &This
->wmpocx
->IConnectionPoint_iface
;
80 IConnectionPoint_AddRef(*ppCP
);
84 WARN("Unsupported IID %s\n", debugstr_guid(riid
));
85 return CONNECT_E_NOCONNECTION
;
88 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl
=
90 ConnectionPointContainer_QueryInterface
,
91 ConnectionPointContainer_AddRef
,
92 ConnectionPointContainer_Release
,
93 ConnectionPointContainer_EnumConnectionPoints
,
94 ConnectionPointContainer_FindConnectionPoint
97 static inline ConnectionPoint
*impl_from_IConnectionPoint(IConnectionPoint
*iface
)
99 return CONTAINING_RECORD(iface
, ConnectionPoint
, IConnectionPoint_iface
);
103 IEnumConnections IEnumConnections_iface
;
111 static inline EnumConnections
*impl_from_IEnumConnections(IEnumConnections
*iface
)
113 return CONTAINING_RECORD(iface
, EnumConnections
, IEnumConnections_iface
);
116 static HRESULT WINAPI
EnumConnections_QueryInterface(IEnumConnections
*iface
, REFIID riid
, void **ppv
)
118 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
120 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
121 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
122 *ppv
= &This
->IEnumConnections_iface
;
123 }else if(IsEqualGUID(&IID_IEnumConnections
, riid
)) {
124 TRACE("(%p)->(IID_IEnumConnections %p)\n", This
, ppv
);
125 *ppv
= &This
->IEnumConnections_iface
;
127 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
129 return E_NOINTERFACE
;
132 IUnknown_AddRef((IUnknown
*)*ppv
);
136 static ULONG WINAPI
EnumConnections_AddRef(IEnumConnections
*iface
)
138 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
139 LONG ref
= InterlockedIncrement(&This
->ref
);
141 TRACE("(%p) ref=%d\n", This
, ref
);
146 static ULONG WINAPI
EnumConnections_Release(IEnumConnections
*iface
)
148 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
149 LONG ref
= InterlockedDecrement(&This
->ref
);
151 TRACE("(%p) ref=%d\n", This
, ref
);
154 IConnectionPoint_Release(&This
->cp
->IConnectionPoint_iface
);
161 static HRESULT WINAPI
EnumConnections_Next(IEnumConnections
*iface
, ULONG cConnections
, CONNECTDATA
*pgcd
, ULONG
*pcFetched
)
163 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
166 TRACE("(%p)->(%u %p %p)\n", This
, cConnections
, pgcd
, pcFetched
);
168 while(cConnections
--) {
169 while(This
->iter
< This
->cp
->sinks_size
&& !This
->cp
->sinks
[This
->iter
])
171 if(This
->iter
== This
->cp
->sinks_size
)
174 pgcd
[cnt
].pUnk
= (IUnknown
*)This
->cp
->sinks
[This
->iter
];
175 pgcd
[cnt
].dwCookie
= cnt
+1;
178 IUnknown_AddRef(pgcd
[cnt
].pUnk
);
183 return cnt
? S_OK
: S_FALSE
;
186 static HRESULT WINAPI
EnumConnections_Skip(IEnumConnections
*iface
, ULONG cConnections
)
188 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
189 FIXME("(%p)->(%u)\n", This
, cConnections
);
193 static HRESULT WINAPI
EnumConnections_Reset(IEnumConnections
*iface
)
195 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
196 FIXME("(%p)\n", This
);
200 static HRESULT WINAPI
EnumConnections_Clone(IEnumConnections
*iface
, IEnumConnections
**ppEnum
)
202 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
203 FIXME("(%p)->(%p)\n", This
, ppEnum
);
207 static const IEnumConnectionsVtbl EnumConnectionsVtbl
= {
208 EnumConnections_QueryInterface
,
209 EnumConnections_AddRef
,
210 EnumConnections_Release
,
211 EnumConnections_Next
,
212 EnumConnections_Skip
,
213 EnumConnections_Reset
,
214 EnumConnections_Clone
217 static HRESULT WINAPI
ConnectionPoint_QueryInterface(IConnectionPoint
*iface
,
218 REFIID riid
, LPVOID
*ppv
)
220 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
224 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
225 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
226 *ppv
= &This
->IConnectionPoint_iface
;
227 }else if(IsEqualGUID(&IID_IConnectionPoint
, riid
)) {
228 TRACE("(%p)->(IID_IConnectionPoint %p)\n", This
, ppv
);
229 *ppv
= &This
->IConnectionPoint_iface
;
233 IConnectionPointContainer_AddRef(This
->container
);
237 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
238 return E_NOINTERFACE
;
241 static ULONG WINAPI
ConnectionPoint_AddRef(IConnectionPoint
*iface
)
243 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
244 return IConnectionPointContainer_AddRef(This
->container
);
247 static ULONG WINAPI
ConnectionPoint_Release(IConnectionPoint
*iface
)
249 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
250 return IConnectionPointContainer_Release(This
->container
);
253 static HRESULT WINAPI
ConnectionPoint_GetConnectionInterface(IConnectionPoint
*iface
, IID
*pIID
)
255 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
257 TRACE("(%p)->(%p)\n", This
, pIID
);
263 static HRESULT WINAPI
ConnectionPoint_GetConnectionPointContainer(IConnectionPoint
*iface
,
264 IConnectionPointContainer
**ppCPC
)
266 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
268 TRACE("(%p)->(%p)\n", This
, ppCPC
);
270 *ppCPC
= This
->container
;
271 IConnectionPointContainer_AddRef(This
->container
);
275 static HRESULT WINAPI
ConnectionPoint_Advise(IConnectionPoint
*iface
, IUnknown
*pUnkSink
,
278 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
283 TRACE("(%p)->(%p %p)\n", This
, pUnkSink
, pdwCookie
);
285 hres
= IUnknown_QueryInterface(pUnkSink
, &This
->iid
, (void**)&disp
);
287 hres
= IUnknown_QueryInterface(pUnkSink
, &IID_IDispatch
, (void**)&disp
);
289 return CONNECT_E_CANNOTCONNECT
;
293 for(i
=0; i
<This
->sinks_size
; i
++) {
298 if(i
== This
->sinks_size
)
299 This
->sinks
= heap_realloc(This
->sinks
,
300 (++This
->sinks_size
)*sizeof(*This
->sinks
));
302 This
->sinks
= heap_alloc(sizeof(*This
->sinks
));
303 This
->sinks_size
= 1;
307 This
->sinks
[i
] = disp
;
313 static HRESULT WINAPI
ConnectionPoint_Unadvise(IConnectionPoint
*iface
, DWORD dwCookie
)
315 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
317 TRACE("(%p)->(%d)\n", This
, dwCookie
);
319 if(!dwCookie
|| dwCookie
> This
->sinks_size
|| !This
->sinks
[dwCookie
-1])
320 return CONNECT_E_NOCONNECTION
;
322 IDispatch_Release(This
->sinks
[dwCookie
-1]);
323 This
->sinks
[dwCookie
-1] = NULL
;
328 static HRESULT WINAPI
ConnectionPoint_EnumConnections(IConnectionPoint
*iface
,
329 IEnumConnections
**ppEnum
)
331 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
332 EnumConnections
*ret
;
334 TRACE("(%p)->(%p)\n", This
, ppEnum
);
336 ret
= heap_alloc(sizeof(*ret
));
338 return E_OUTOFMEMORY
;
340 ret
->IEnumConnections_iface
.lpVtbl
= &EnumConnectionsVtbl
;
344 IConnectionPoint_AddRef(&This
->IConnectionPoint_iface
);
347 *ppEnum
= &ret
->IEnumConnections_iface
;
352 static const IConnectionPointVtbl ConnectionPointVtbl
=
354 ConnectionPoint_QueryInterface
,
355 ConnectionPoint_AddRef
,
356 ConnectionPoint_Release
,
357 ConnectionPoint_GetConnectionInterface
,
358 ConnectionPoint_GetConnectionPointContainer
,
359 ConnectionPoint_Advise
,
360 ConnectionPoint_Unadvise
,
361 ConnectionPoint_EnumConnections
364 static void ConnectionPoint_Destroy(ConnectionPoint
*This
)
368 for(i
=0; i
<This
->sinks_size
; i
++) {
370 IDispatch_Release(This
->sinks
[i
]);
373 heap_free(This
->sinks
);
377 static void ConnectionPoint_Create(REFIID riid
, ConnectionPoint
**cp
,
378 IConnectionPointContainer
*container
)
380 ConnectionPoint
*ret
= heap_alloc(sizeof(ConnectionPoint
));
382 ret
->IConnectionPoint_iface
.lpVtbl
= &ConnectionPointVtbl
;
386 ret
->container
= container
;
393 void ConnectionPointContainer_Init(WindowsMediaPlayer
*wmp
)
395 wmp
->IConnectionPointContainer_iface
.lpVtbl
= &ConnectionPointContainerVtbl
;
396 ConnectionPoint_Create(&IID__WMPOCXEvents
, &wmp
->wmpocx
, &wmp
->IConnectionPointContainer_iface
);
399 void ConnectionPointContainer_Destroy(WindowsMediaPlayer
*wmp
)
401 ConnectionPoint_Destroy(wmp
->wmpocx
);
404 void call_sink(ConnectionPoint
*This
, DISPID dispid
, DISPPARAMS
*dispparams
)
408 for(i
=0; i
<This
->sinks_size
; i
++) {
410 IDispatch_Invoke(This
->sinks
[i
], dispid
, &IID_NULL
, LOCALE_SYSTEM_DEFAULT
,
411 DISPATCH_METHOD
, dispparams
, NULL
, NULL
, NULL
);