1 /*****************************************************************************
2 * connectioncontainer.cpp: ActiveX control for VLC
3 *****************************************************************************
4 * Copyright (C) 2005 VideoLAN
6 * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
24 #include "connectioncontainer.h"
30 ////////////////////////////////////////////////////////////////////////////////////////////////
32 class VLCEnumConnections : public IEnumConnections
35 VLCEnumConnections(vector<CONNECTDATA> &v) :
36 e(VLCEnum<CONNECTDATA>(IID_IEnumConnections, v))
37 { e.setRetainOperation((VLCEnum<CONNECTDATA>::retainer)&retain); };
39 VLCEnumConnections(const VLCEnumConnections &vlcEnum) : e(vlcEnum.e) {};
41 virtual ~VLCEnumConnections() {};
44 STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
45 { return e.QueryInterface(riid, ppv); };
46 STDMETHODIMP_(ULONG) AddRef(void)
47 { return e.AddRef(); };
48 STDMETHODIMP_(ULONG) Release(void)
49 {return e.Release(); };
51 //IEnumConnectionPoints
52 STDMETHODIMP Next(ULONG celt, LPCONNECTDATA rgelt, ULONG *pceltFetched)
53 { return e.Next(celt, rgelt, pceltFetched); };
54 STDMETHODIMP Skip(ULONG celt)
55 { return e.Skip(celt);};
56 STDMETHODIMP Reset(void)
58 STDMETHODIMP Clone(LPENUMCONNECTIONS *ppenum)
59 { if( NULL == ppenum ) return E_POINTER;
60 *ppenum = dynamic_cast<LPENUMCONNECTIONS>(new VLCEnumConnections(*this));
61 return (NULL != *ppenum) ? S_OK : E_OUTOFMEMORY;
66 static void retain(CONNECTDATA cd)
71 VLCEnum<CONNECTDATA> e;
74 ////////////////////////////////////////////////////////////////////////////////////////////////
76 STDMETHODIMP VLCConnectionPoint::GetConnectionInterface(IID *iid)
85 STDMETHODIMP VLCConnectionPoint::GetConnectionPointContainer(LPCONNECTIONPOINTCONTAINER *ppCPC)
95 STDMETHODIMP VLCConnectionPoint::Advise(IUnknown *pUnk, DWORD *pdwCookie)
97 if( (NULL == pUnk) || (NULL == pdwCookie) )
104 *pdwCookie = cd.dwCookie = _connections.size();
106 _connections.push_back(cd);
111 STDMETHODIMP VLCConnectionPoint::Unadvise(DWORD pdwCookie)
113 if( pdwCookie < _connections.size() )
115 CONNECTDATA cd = _connections[pdwCookie];
116 if( NULL != cd.pUnk )
123 return CONNECT_E_NOCONNECTION;
126 STDMETHODIMP VLCConnectionPoint::EnumConnections(IEnumConnections **ppEnum)
131 *ppEnum = dynamic_cast<LPENUMCONNECTIONS>(new VLCEnumConnections(_connections));
133 return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
136 void VLCConnectionPoint::fireEvent(DISPID dispId, DISPPARAMS* pDispParams)
138 vector<CONNECTDATA>::iterator end = _connections.end();
139 vector<CONNECTDATA>::iterator iter = _connections.begin();
143 CONNECTDATA cd = *iter;
144 if( NULL != cd.pUnk )
147 if( SUCCEEDED(cd.pUnk->QueryInterface(IID_IDispatch, (LPVOID *)&pDisp)) )
149 pDisp->Invoke(dispId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, pDispParams, NULL, NULL, NULL);
157 void VLCConnectionPoint::firePropChangedEvent(DISPID dispId)
159 vector<CONNECTDATA>::iterator end = _connections.end();
160 vector<CONNECTDATA>::iterator iter = _connections.begin();
164 CONNECTDATA cd = *iter;
165 if( NULL != cd.pUnk )
167 IPropertyNotifySink *pPropSink;
168 if( SUCCEEDED(cd.pUnk->QueryInterface(IID_IPropertyNotifySink, (LPVOID *)&pPropSink)) )
170 pPropSink->OnChanged(dispId);
171 pPropSink->Release();
178 ////////////////////////////////////////////////////////////////////////////////////////////////
180 class VLCEnumConnectionPoints : public IEnumConnectionPoints
183 VLCEnumConnectionPoints(vector<LPCONNECTIONPOINT> &v) :
184 e(VLCEnum<LPCONNECTIONPOINT>(IID_IEnumConnectionPoints, v))
185 { e.setRetainOperation((VLCEnum<LPCONNECTIONPOINT>::retainer)&retain); };
187 VLCEnumConnectionPoints(const VLCEnumConnectionPoints &vlcEnum) : e(vlcEnum.e) {};
189 virtual ~VLCEnumConnectionPoints() {};
192 STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
193 { return e.QueryInterface(riid, ppv); };
194 STDMETHODIMP_(ULONG) AddRef(void)
195 { return e.AddRef(); };
196 STDMETHODIMP_(ULONG) Release(void)
197 {return e.Release(); };
199 //IEnumConnectionPoints
200 STDMETHODIMP Next(ULONG celt, LPCONNECTIONPOINT *rgelt, ULONG *pceltFetched)
201 { return e.Next(celt, rgelt, pceltFetched); };
202 STDMETHODIMP Skip(ULONG celt)
203 { return e.Skip(celt);};
204 STDMETHODIMP Reset(void)
205 { return e.Reset();};
206 STDMETHODIMP Clone(LPENUMCONNECTIONPOINTS *ppenum)
207 { if( NULL == ppenum ) return E_POINTER;
208 *ppenum = dynamic_cast<LPENUMCONNECTIONPOINTS>(new VLCEnumConnectionPoints(*this));
209 return (NULL != *ppenum) ? S_OK : E_OUTOFMEMORY;
214 static void retain(LPCONNECTIONPOINT cp)
219 VLCEnum<LPCONNECTIONPOINT> e;
222 ////////////////////////////////////////////////////////////////////////////////////////////////
224 VLCConnectionPointContainer::VLCConnectionPointContainer(VLCPlugin *p_instance) :
225 _p_instance(p_instance)
227 _p_events = new VLCConnectionPoint(dynamic_cast<LPCONNECTIONPOINTCONTAINER>(this),
228 _p_instance->getDispEventID());
230 _v_cps.push_back(dynamic_cast<LPCONNECTIONPOINT>(_p_events));
232 _p_props = new VLCConnectionPoint(dynamic_cast<LPCONNECTIONPOINTCONTAINER>(this),
233 IID_IPropertyNotifySink);
235 _v_cps.push_back(dynamic_cast<LPCONNECTIONPOINT>(_p_props));
238 VLCConnectionPointContainer::~VLCConnectionPointContainer()
245 STDMETHODIMP VLCConnectionPointContainer::EnumConnectionPoints(LPENUMCONNECTIONPOINTS *ppEnum)
250 *ppEnum = dynamic_cast<LPENUMCONNECTIONPOINTS>(new VLCEnumConnectionPoints(_v_cps));
252 return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
255 STDMETHODIMP VLCConnectionPointContainer::FindConnectionPoint(REFIID riid, IConnectionPoint **ppCP)
262 if( IID_IPropertyNotifySink == riid )
265 *ppCP = dynamic_cast<LPCONNECTIONPOINT>(_p_props);
267 else if( _p_instance->getDispEventID() == riid )
270 *ppCP = dynamic_cast<LPCONNECTIONPOINT>(_p_events);
273 return CONNECT_E_NOCONNECTION;
278 void VLCConnectionPointContainer::fireEvent(DISPID dispId, DISPPARAMS* pDispParams)
280 _p_events->fireEvent(dispId, pDispParams);
283 void VLCConnectionPointContainer::firePropChangedEvent(DISPID dispId)
285 _p_props->firePropChangedEvent(dispId);