]> git.sesse.net Git - vlc/blob - activex/connectioncontainer.cpp
6fd504a6980bc8ab5af4af94cc737233bfd6c794
[vlc] / activex / connectioncontainer.cpp
1 /*****************************************************************************\r
2  * connectioncontainer.cpp: ActiveX control for VLC\r
3  *****************************************************************************\r
4  * Copyright (C) 2005 VideoLAN\r
5  *\r
6  * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>\r
7  *\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
12  *\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
17  *\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
22 \r
23 #include "plugin.h"\r
24 #include "connectioncontainer.h"\r
25 \r
26 #include "utils.h"\r
27 \r
28 using namespace std;\r
29 \r
30 ////////////////////////////////////////////////////////////////////////////////////////////////\r
31 \r
32 class VLCEnumConnections : public IEnumConnections\r
33 {\r
34 public:\r
35     VLCEnumConnections(vector<CONNECTDATA> &v) :\r
36         e(VLCEnum<CONNECTDATA>(IID_IEnumConnections, v))\r
37     { e.setRetainOperation((VLCEnum<CONNECTDATA>::retainer)&retain); };\r
38 \r
39     VLCEnumConnections(const VLCEnumConnections &vlcEnum) : e(vlcEnum.e) {};\r
40 \r
41     virtual ~VLCEnumConnections() {};\r
42 \r
43     // IUnknown methods\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
50 \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
62         };\r
63 \r
64 private:\r
65 \r
66     static void retain(CONNECTDATA cd)\r
67     {\r
68         cd.pUnk->AddRef();\r
69     };\r
70 \r
71     VLCEnum<CONNECTDATA> e;\r
72 };\r
73 \r
74 ////////////////////////////////////////////////////////////////////////////////////////////////\r
75 \r
76 STDMETHODIMP VLCConnectionPoint::GetConnectionInterface(IID *iid)\r
77 {\r
78     if( NULL == iid )\r
79         return E_POINTER;\r
80 \r
81     *iid = _iid;\r
82     return S_OK;\r
83 };\r
84 \r
85 STDMETHODIMP VLCConnectionPoint::GetConnectionPointContainer(LPCONNECTIONPOINTCONTAINER *ppCPC)\r
86 {\r
87     if( NULL == ppCPC )\r
88         return E_POINTER;\r
89 \r
90     _p_cpc->AddRef();\r
91     *ppCPC = _p_cpc;\r
92     return S_OK;\r
93 };\r
94 \r
95 STDMETHODIMP VLCConnectionPoint::Advise(IUnknown *pUnk, DWORD *pdwCookie)\r
96 {\r
97     if( (NULL == pUnk) || (NULL == pdwCookie) )\r
98         return E_POINTER;\r
99 \r
100     CONNECTDATA cd;\r
101 \r
102     pUnk->AddRef();\r
103     cd.pUnk = pUnk;\r
104     *pdwCookie = cd.dwCookie = _connections.size();\r
105 \r
106     _connections.push_back(cd);\r
107 \r
108     return S_OK;\r
109 };\r
110 \r
111 STDMETHODIMP VLCConnectionPoint::Unadvise(DWORD pdwCookie)\r
112 {\r
113     if( pdwCookie < _connections.size() )\r
114     {\r
115         CONNECTDATA cd = _connections[pdwCookie];\r
116         if( NULL != cd.pUnk )\r
117         {\r
118             cd.pUnk->Release();\r
119             cd.pUnk = NULL;\r
120             return S_OK;\r
121         }\r
122     }\r
123     return CONNECT_E_NOCONNECTION;\r
124 };\r
125 \r
126 STDMETHODIMP VLCConnectionPoint::EnumConnections(IEnumConnections **ppEnum)\r
127 {\r
128     if( NULL == ppEnum )\r
129         return E_POINTER;\r
130 \r
131     *ppEnum = dynamic_cast<LPENUMCONNECTIONS>(new VLCEnumConnections(_connections));\r
132 \r
133     return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;\r
134 };\r
135 \r
136 void VLCConnectionPoint::fireEvent(DISPID dispId, DISPPARAMS* pDispParams)\r
137 {\r
138     vector<CONNECTDATA>::iterator end = _connections.end();\r
139     vector<CONNECTDATA>::iterator iter = _connections.begin();\r
140 \r
141     while( iter != end )\r
142     {\r
143         CONNECTDATA cd = *iter;\r
144         if( NULL != cd.pUnk )\r
145         {\r
146             IDispatch *pDisp;\r
147             if( SUCCEEDED(cd.pUnk->QueryInterface(IID_IDispatch, (LPVOID *)&pDisp)) )\r
148             {\r
149                 pDisp->Invoke(dispId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, pDispParams, NULL, NULL, NULL);\r
150                 pDisp->Release();\r
151             }\r
152         }\r
153         ++iter;\r
154     }\r
155 };\r
156 \r
157 void VLCConnectionPoint::firePropChangedEvent(DISPID dispId)\r
158 {\r
159     vector<CONNECTDATA>::iterator end = _connections.end();\r
160     vector<CONNECTDATA>::iterator iter = _connections.begin();\r
161 \r
162     while( iter != end )\r
163     {\r
164         CONNECTDATA cd = *iter;\r
165         if( NULL != cd.pUnk )\r
166         {\r
167             IPropertyNotifySink *pPropSink;\r
168             if( SUCCEEDED(cd.pUnk->QueryInterface(IID_IPropertyNotifySink, (LPVOID *)&pPropSink)) )\r
169             {\r
170                 pPropSink->OnChanged(dispId);\r
171                 pPropSink->Release();\r
172             }\r
173         }\r
174         ++iter;\r
175     }\r
176 };\r
177 \r
178 ////////////////////////////////////////////////////////////////////////////////////////////////\r
179 \r
180 class VLCEnumConnectionPoints : public IEnumConnectionPoints\r
181 {\r
182 public:\r
183     VLCEnumConnectionPoints(vector<LPCONNECTIONPOINT> &v) :\r
184         e(VLCEnum<LPCONNECTIONPOINT>(IID_IEnumConnectionPoints, v))\r
185     { e.setRetainOperation((VLCEnum<LPCONNECTIONPOINT>::retainer)&retain); };\r
186 \r
187     VLCEnumConnectionPoints(const VLCEnumConnectionPoints &vlcEnum) : e(vlcEnum.e) {};\r
188 \r
189     virtual ~VLCEnumConnectionPoints() {};\r
190 \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
198 \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
210         };\r
211 \r
212 private:\r
213 \r
214     static void retain(LPCONNECTIONPOINT cp)\r
215     {\r
216         cp->AddRef();\r
217     };\r
218 \r
219     VLCEnum<LPCONNECTIONPOINT> e;\r
220 };\r
221 \r
222 ////////////////////////////////////////////////////////////////////////////////////////////////\r
223 \r
224 VLCConnectionPointContainer::VLCConnectionPointContainer(VLCPlugin *p_instance) :\r
225     _p_instance(p_instance)\r
226 {\r
227     _p_events = new VLCConnectionPoint(dynamic_cast<LPCONNECTIONPOINTCONTAINER>(this),\r
228             _p_instance->getDispEventID());\r
229 \r
230     _v_cps.push_back(dynamic_cast<LPCONNECTIONPOINT>(_p_events));\r
231 \r
232     _p_props = new VLCConnectionPoint(dynamic_cast<LPCONNECTIONPOINTCONTAINER>(this),\r
233             IID_IPropertyNotifySink);\r
234 \r
235     _v_cps.push_back(dynamic_cast<LPCONNECTIONPOINT>(_p_props));\r
236 };\r
237 \r
238 VLCConnectionPointContainer::~VLCConnectionPointContainer()\r
239 {\r
240     _v_cps.clear();\r
241     delete _p_props;\r
242     delete _p_events;\r
243 };\r
244 \r
245 STDMETHODIMP VLCConnectionPointContainer::EnumConnectionPoints(LPENUMCONNECTIONPOINTS *ppEnum)\r
246 {\r
247     if( NULL == ppEnum )\r
248         return E_POINTER;\r
249 \r
250     *ppEnum = dynamic_cast<LPENUMCONNECTIONPOINTS>(new VLCEnumConnectionPoints(_v_cps));\r
251 \r
252     return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;\r
253 };\r
254 \r
255 STDMETHODIMP VLCConnectionPointContainer::FindConnectionPoint(REFIID riid, IConnectionPoint **ppCP)\r
256 {\r
257     if( NULL == ppCP )\r
258         return E_POINTER;\r
259 \r
260     *ppCP = NULL;\r
261 \r
262     if( IID_IPropertyNotifySink == riid )\r
263     {\r
264         _p_props->AddRef();\r
265         *ppCP = dynamic_cast<LPCONNECTIONPOINT>(_p_props);\r
266     }\r
267     else if( _p_instance->getDispEventID() == riid )\r
268     {\r
269         _p_events->AddRef();\r
270         *ppCP = dynamic_cast<LPCONNECTIONPOINT>(_p_events);\r
271     }\r
272     else\r
273         return CONNECT_E_NOCONNECTION;\r
274 \r
275     return NOERROR;\r
276 };\r
277 \r
278 void VLCConnectionPointContainer::fireEvent(DISPID dispId, DISPPARAMS* pDispParams)\r
279 {\r
280     _p_events->fireEvent(dispId, pDispParams);\r
281 };\r
282 \r
283 void VLCConnectionPointContainer::firePropChangedEvent(DISPID dispId)\r
284 {\r
285     _p_props->firePropChangedEvent(dispId);\r
286 };\r
287 \r