2 * Implementation of event-related interfaces for WebBrowser 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
27 struct ConnectionPoint
{
28 IConnectionPoint IConnectionPoint_iface
;
30 IConnectionPointContainer
*container
;
38 /**********************************************************************
39 * Implement the IConnectionPointContainer interface
42 static inline ConnectionPointContainer
*impl_from_IConnectionPointContainer(IConnectionPointContainer
*iface
)
44 return CONTAINING_RECORD(iface
, ConnectionPointContainer
, IConnectionPointContainer_iface
);
47 static HRESULT WINAPI
ConnectionPointContainer_QueryInterface(IConnectionPointContainer
*iface
,
48 REFIID riid
, LPVOID
*ppv
)
50 ConnectionPointContainer
*This
= impl_from_IConnectionPointContainer(iface
);
51 return IUnknown_QueryInterface(This
->impl
, riid
, ppv
);
54 static ULONG WINAPI
ConnectionPointContainer_AddRef(IConnectionPointContainer
*iface
)
56 ConnectionPointContainer
*This
= impl_from_IConnectionPointContainer(iface
);
57 return IUnknown_AddRef(This
->impl
);
60 static ULONG WINAPI
ConnectionPointContainer_Release(IConnectionPointContainer
*iface
)
62 ConnectionPointContainer
*This
= impl_from_IConnectionPointContainer(iface
);
63 return IUnknown_Release(This
->impl
);
66 static HRESULT WINAPI
ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer
*iface
,
67 LPENUMCONNECTIONPOINTS
*ppEnum
)
69 ConnectionPointContainer
*This
= impl_from_IConnectionPointContainer(iface
);
70 FIXME("(%p)->(%p)\n", This
, ppEnum
);
74 static HRESULT WINAPI
ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer
*iface
,
75 REFIID riid
, LPCONNECTIONPOINT
*ppCP
)
77 ConnectionPointContainer
*This
= impl_from_IConnectionPointContainer(iface
);
80 WARN("ppCP == NULL\n");
86 if(IsEqualGUID(&DIID_DWebBrowserEvents2
, riid
)) {
87 TRACE("(%p)->(DIID_DWebBrowserEvents2 %p)\n", This
, ppCP
);
88 *ppCP
= &This
->wbe2
->IConnectionPoint_iface
;
89 }else if(IsEqualGUID(&DIID_DWebBrowserEvents
, riid
)) {
90 TRACE("(%p)->(DIID_DWebBrowserEvents %p)\n", This
, ppCP
);
91 *ppCP
= &This
->wbe
->IConnectionPoint_iface
;
92 }else if(IsEqualGUID(&IID_IPropertyNotifySink
, riid
)) {
93 TRACE("(%p)->(IID_IPropertyNotifySink %p)\n", This
, ppCP
);
94 *ppCP
= &This
->pns
->IConnectionPoint_iface
;
98 IConnectionPoint_AddRef(*ppCP
);
102 WARN("Unsupported IID %s\n", debugstr_guid(riid
));
103 return CONNECT_E_NOCONNECTION
;
106 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl
=
108 ConnectionPointContainer_QueryInterface
,
109 ConnectionPointContainer_AddRef
,
110 ConnectionPointContainer_Release
,
111 ConnectionPointContainer_EnumConnectionPoints
,
112 ConnectionPointContainer_FindConnectionPoint
116 /**********************************************************************
117 * Implement the IConnectionPoint interface
120 static inline ConnectionPoint
*impl_from_IConnectionPoint(IConnectionPoint
*iface
)
122 return CONTAINING_RECORD(iface
, ConnectionPoint
, IConnectionPoint_iface
);
126 IEnumConnections IEnumConnections_iface
;
134 static inline EnumConnections
*impl_from_IEnumConnections(IEnumConnections
*iface
)
136 return CONTAINING_RECORD(iface
, EnumConnections
, IEnumConnections_iface
);
139 static HRESULT WINAPI
EnumConnections_QueryInterface(IEnumConnections
*iface
, REFIID riid
, void **ppv
)
141 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
143 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
144 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
145 *ppv
= &This
->IEnumConnections_iface
;
146 }else if(IsEqualGUID(&IID_IEnumConnections
, riid
)) {
147 TRACE("(%p)->(IID_IEnumConnections %p)\n", This
, ppv
);
148 *ppv
= &This
->IEnumConnections_iface
;
150 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
152 return E_NOINTERFACE
;
155 IUnknown_AddRef((IUnknown
*)*ppv
);
159 static ULONG WINAPI
EnumConnections_AddRef(IEnumConnections
*iface
)
161 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
162 LONG ref
= InterlockedIncrement(&This
->ref
);
164 TRACE("(%p) ref=%d\n", This
, ref
);
169 static ULONG WINAPI
EnumConnections_Release(IEnumConnections
*iface
)
171 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
172 LONG ref
= InterlockedDecrement(&This
->ref
);
174 TRACE("(%p) ref=%d\n", This
, ref
);
177 IConnectionPoint_Release(&This
->cp
->IConnectionPoint_iface
);
184 static HRESULT WINAPI
EnumConnections_Next(IEnumConnections
*iface
, ULONG cConnections
, CONNECTDATA
*pgcd
, ULONG
*pcFetched
)
186 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
189 TRACE("(%p)->(%u %p %p)\n", This
, cConnections
, pgcd
, pcFetched
);
191 while(cConnections
--) {
192 while(This
->iter
< This
->cp
->sinks_size
&& !This
->cp
->sinks
[This
->iter
])
194 if(This
->iter
== This
->cp
->sinks_size
)
197 pgcd
[cnt
].pUnk
= (IUnknown
*)This
->cp
->sinks
[This
->iter
];
198 pgcd
[cnt
].dwCookie
= cnt
+1;
205 return cnt
? S_OK
: S_FALSE
;
208 static HRESULT WINAPI
EnumConnections_Skip(IEnumConnections
*iface
, ULONG cConnections
)
210 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
211 FIXME("(%p)->(%u)\n", This
, cConnections
);
215 static HRESULT WINAPI
EnumConnections_Reset(IEnumConnections
*iface
)
217 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
218 FIXME("(%p)\n", This
);
222 static HRESULT WINAPI
EnumConnections_Clone(IEnumConnections
*iface
, IEnumConnections
**ppEnum
)
224 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
225 FIXME("(%p)->(%p)\n", This
, ppEnum
);
229 static const IEnumConnectionsVtbl EnumConnectionsVtbl
= {
230 EnumConnections_QueryInterface
,
231 EnumConnections_AddRef
,
232 EnumConnections_Release
,
233 EnumConnections_Next
,
234 EnumConnections_Skip
,
235 EnumConnections_Reset
,
236 EnumConnections_Clone
239 static HRESULT WINAPI
ConnectionPoint_QueryInterface(IConnectionPoint
*iface
,
240 REFIID riid
, LPVOID
*ppv
)
242 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
246 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
247 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
248 *ppv
= &This
->IConnectionPoint_iface
;
249 }else if(IsEqualGUID(&IID_IConnectionPoint
, riid
)) {
250 TRACE("(%p)->(IID_IConnectionPoint %p)\n", This
, ppv
);
251 *ppv
= &This
->IConnectionPoint_iface
;
255 IConnectionPointContainer_AddRef(This
->container
);
259 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
260 return E_NOINTERFACE
;
263 static ULONG WINAPI
ConnectionPoint_AddRef(IConnectionPoint
*iface
)
265 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
266 return IConnectionPointContainer_AddRef(This
->container
);
269 static ULONG WINAPI
ConnectionPoint_Release(IConnectionPoint
*iface
)
271 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
272 return IConnectionPointContainer_Release(This
->container
);
275 static HRESULT WINAPI
ConnectionPoint_GetConnectionInterface(IConnectionPoint
*iface
, IID
*pIID
)
277 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
279 TRACE("(%p)->(%p)\n", This
, pIID
);
285 static HRESULT WINAPI
ConnectionPoint_GetConnectionPointContainer(IConnectionPoint
*iface
,
286 IConnectionPointContainer
**ppCPC
)
288 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
290 TRACE("(%p)->(%p)\n", This
, ppCPC
);
292 *ppCPC
= This
->container
;
293 IConnectionPointContainer_AddRef(This
->container
);
297 static HRESULT WINAPI
ConnectionPoint_Advise(IConnectionPoint
*iface
, IUnknown
*pUnkSink
,
300 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
305 TRACE("(%p)->(%p %p)\n", This
, pUnkSink
, pdwCookie
);
307 hres
= IUnknown_QueryInterface(pUnkSink
, &This
->iid
, (void**)&disp
);
309 hres
= IUnknown_QueryInterface(pUnkSink
, &IID_IDispatch
, (void**)&disp
);
311 return CONNECT_E_CANNOTCONNECT
;
315 for(i
=0; i
<This
->sinks_size
; i
++) {
320 if(i
== This
->sinks_size
)
321 This
->sinks
= heap_realloc(This
->sinks
,
322 (++This
->sinks_size
)*sizeof(*This
->sinks
));
324 This
->sinks
= heap_alloc(sizeof(*This
->sinks
));
325 This
->sinks_size
= 1;
329 This
->sinks
[i
] = disp
;
335 static HRESULT WINAPI
ConnectionPoint_Unadvise(IConnectionPoint
*iface
, DWORD dwCookie
)
337 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
339 TRACE("(%p)->(%d)\n", This
, dwCookie
);
341 if(!dwCookie
|| dwCookie
> This
->sinks_size
|| !This
->sinks
[dwCookie
-1])
342 return CONNECT_E_NOCONNECTION
;
344 IDispatch_Release(This
->sinks
[dwCookie
-1]);
345 This
->sinks
[dwCookie
-1] = NULL
;
350 static HRESULT WINAPI
ConnectionPoint_EnumConnections(IConnectionPoint
*iface
,
351 IEnumConnections
**ppEnum
)
353 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
354 EnumConnections
*ret
;
356 TRACE("(%p)->(%p)\n", This
, ppEnum
);
358 ret
= heap_alloc(sizeof(*ret
));
360 return E_OUTOFMEMORY
;
362 ret
->IEnumConnections_iface
.lpVtbl
= &EnumConnectionsVtbl
;
366 IConnectionPoint_AddRef(&This
->IConnectionPoint_iface
);
369 *ppEnum
= &ret
->IEnumConnections_iface
;
373 static const IConnectionPointVtbl ConnectionPointVtbl
=
375 ConnectionPoint_QueryInterface
,
376 ConnectionPoint_AddRef
,
377 ConnectionPoint_Release
,
378 ConnectionPoint_GetConnectionInterface
,
379 ConnectionPoint_GetConnectionPointContainer
,
380 ConnectionPoint_Advise
,
381 ConnectionPoint_Unadvise
,
382 ConnectionPoint_EnumConnections
385 void call_sink(ConnectionPoint
*This
, DISPID dispid
, DISPPARAMS
*dispparams
)
389 for(i
=0; i
<This
->sinks_size
; i
++) {
391 IDispatch_Invoke(This
->sinks
[i
], dispid
, &IID_NULL
, LOCALE_SYSTEM_DEFAULT
,
392 DISPATCH_METHOD
, dispparams
, NULL
, NULL
, NULL
);
396 static void ConnectionPoint_Create(REFIID riid
, ConnectionPoint
**cp
,
397 IConnectionPointContainer
*container
)
399 ConnectionPoint
*ret
= heap_alloc(sizeof(ConnectionPoint
));
401 ret
->IConnectionPoint_iface
.lpVtbl
= &ConnectionPointVtbl
;
405 ret
->container
= container
;
412 static void ConnectionPoint_Destroy(ConnectionPoint
*This
)
416 for(i
=0; i
<This
->sinks_size
; i
++) {
418 IDispatch_Release(This
->sinks
[i
]);
421 heap_free(This
->sinks
);
425 void ConnectionPointContainer_Init(ConnectionPointContainer
*This
, IUnknown
*impl
)
427 This
->IConnectionPointContainer_iface
.lpVtbl
= &ConnectionPointContainerVtbl
;
429 ConnectionPoint_Create(&DIID_DWebBrowserEvents2
, &This
->wbe2
, &This
->IConnectionPointContainer_iface
);
430 ConnectionPoint_Create(&DIID_DWebBrowserEvents
, &This
->wbe
, &This
->IConnectionPointContainer_iface
);
431 ConnectionPoint_Create(&IID_IPropertyNotifySink
, &This
->pns
, &This
->IConnectionPointContainer_iface
);
436 void ConnectionPointContainer_Destroy(ConnectionPointContainer
*This
)
438 ConnectionPoint_Destroy(This
->wbe2
);
439 ConnectionPoint_Destroy(This
->wbe
);
440 ConnectionPoint_Destroy(This
->pns
);