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