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, LCID lcid, 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 unsigned int puArgErr;
\r
152 if( SUCCEEDED(pDisp->Invoke(dispId, IID_NULL, lcid, DISPATCH_METHOD, pDispParams, &vRes, NULL, &puArgErr)) )
\r
154 VariantClear(&vRes);
\r
163 void VLCConnectionPoint::firePropChangedEvent(DISPID dispId)
\r
165 vector<CONNECTDATA>::iterator end = _connections.end();
\r
166 vector<CONNECTDATA>::iterator iter = _connections.begin();
\r
168 while( iter != end )
\r
170 CONNECTDATA cd = *iter;
\r
171 if( NULL != cd.pUnk )
\r
173 IPropertyNotifySink *pPropSink;
\r
174 if( SUCCEEDED(cd.pUnk->QueryInterface(IID_IPropertyNotifySink, (LPVOID *)&pPropSink)) )
\r
176 pPropSink->OnChanged(dispId);
\r
177 pPropSink->Release();
\r
184 ////////////////////////////////////////////////////////////////////////////////////////////////
\r
186 class VLCEnumConnectionPoints : public IEnumConnectionPoints
\r
189 VLCEnumConnectionPoints(vector<LPCONNECTIONPOINT> &v) :
\r
190 e(VLCEnum<LPCONNECTIONPOINT>(IID_IEnumConnectionPoints, v))
\r
191 { e.setRetainOperation((VLCEnum<LPCONNECTIONPOINT>::retainer)&retain); };
\r
193 VLCEnumConnectionPoints(const VLCEnumConnectionPoints &vlcEnum) : e(vlcEnum.e) {};
\r
195 virtual ~VLCEnumConnectionPoints() {};
\r
197 // IUnknown methods
\r
198 STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
\r
199 { return e.QueryInterface(riid, ppv); };
\r
200 STDMETHODIMP_(ULONG) AddRef(void)
\r
201 { return e.AddRef(); };
\r
202 STDMETHODIMP_(ULONG) Release(void)
\r
203 {return e.Release(); };
\r
205 //IEnumConnectionPoints
\r
206 STDMETHODIMP Next(ULONG celt, LPCONNECTIONPOINT *rgelt, ULONG *pceltFetched)
\r
207 { return e.Next(celt, rgelt, pceltFetched); };
\r
208 STDMETHODIMP Skip(ULONG celt)
\r
209 { return e.Skip(celt);};
\r
210 STDMETHODIMP Reset(void)
\r
211 { return e.Reset();};
\r
212 STDMETHODIMP Clone(LPENUMCONNECTIONPOINTS *ppenum)
\r
213 { if( NULL == ppenum ) return E_POINTER;
\r
214 *ppenum = dynamic_cast<LPENUMCONNECTIONPOINTS>(new VLCEnumConnectionPoints(*this));
\r
215 return (NULL != *ppenum) ? S_OK : E_OUTOFMEMORY;
\r
220 static void retain(LPCONNECTIONPOINT cp)
\r
225 VLCEnum<LPCONNECTIONPOINT> e;
\r
228 ////////////////////////////////////////////////////////////////////////////////////////////////
\r
230 VLCConnectionPointContainer::VLCConnectionPointContainer(VLCPlugin *p_instance) :
\r
231 _p_instance(p_instance)
\r
233 _p_events = new VLCConnectionPoint(dynamic_cast<LPCONNECTIONPOINTCONTAINER>(this),
\r
234 _p_instance->getDispEventID());
\r
236 _v_cps.push_back(dynamic_cast<LPCONNECTIONPOINT>(_p_events));
\r
238 _p_props = new VLCConnectionPoint(dynamic_cast<LPCONNECTIONPOINTCONTAINER>(this),
\r
239 IID_IPropertyNotifySink);
\r
241 _v_cps.push_back(dynamic_cast<LPCONNECTIONPOINT>(_p_props));
\r
244 VLCConnectionPointContainer::~VLCConnectionPointContainer()
\r
251 STDMETHODIMP VLCConnectionPointContainer::EnumConnectionPoints(LPENUMCONNECTIONPOINTS *ppEnum)
\r
253 if( NULL == ppEnum )
\r
256 *ppEnum = dynamic_cast<LPENUMCONNECTIONPOINTS>(new VLCEnumConnectionPoints(_v_cps));
\r
258 return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
\r
261 STDMETHODIMP VLCConnectionPointContainer::FindConnectionPoint(REFIID riid, IConnectionPoint **ppCP)
\r
268 if( IID_IPropertyNotifySink == riid )
\r
270 _p_props->AddRef();
\r
271 *ppCP = dynamic_cast<LPCONNECTIONPOINT>(_p_props);
\r
273 else if( _p_instance->getDispEventID() == riid )
\r
275 _p_events->AddRef();
\r
276 *ppCP = dynamic_cast<LPCONNECTIONPOINT>(_p_events);
\r
279 return CONNECT_E_NOCONNECTION;
\r
284 void VLCConnectionPointContainer::fireEvent(DISPID dispId, LCID lcid, DISPPARAMS* pDispParams)
\r
286 _p_events->fireEvent(dispId,lcid, pDispParams);
\r
289 void VLCConnectionPointContainer::firePropChangedEvent(DISPID dispId)
\r
291 _p_props->firePropChangedEvent(dispId);
\r