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
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(ieframe
);
33 struct ConnectionPoint
{
34 IConnectionPoint IConnectionPoint_iface
;
36 IConnectionPointContainer
*container
;
44 /**********************************************************************
45 * Implement the IConnectionPointContainer interface
48 static inline ConnectionPointContainer
*impl_from_IConnectionPointContainer(IConnectionPointContainer
*iface
)
50 return CONTAINING_RECORD(iface
, ConnectionPointContainer
, IConnectionPointContainer_iface
);
53 static HRESULT WINAPI
ConnectionPointContainer_QueryInterface(IConnectionPointContainer
*iface
,
54 REFIID riid
, LPVOID
*ppv
)
56 ConnectionPointContainer
*This
= impl_from_IConnectionPointContainer(iface
);
57 return IUnknown_QueryInterface(This
->impl
, riid
, ppv
);
60 static ULONG WINAPI
ConnectionPointContainer_AddRef(IConnectionPointContainer
*iface
)
62 ConnectionPointContainer
*This
= impl_from_IConnectionPointContainer(iface
);
63 return IUnknown_AddRef(This
->impl
);
66 static ULONG WINAPI
ConnectionPointContainer_Release(IConnectionPointContainer
*iface
)
68 ConnectionPointContainer
*This
= impl_from_IConnectionPointContainer(iface
);
69 return IUnknown_Release(This
->impl
);
72 static HRESULT WINAPI
ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer
*iface
,
73 LPENUMCONNECTIONPOINTS
*ppEnum
)
75 ConnectionPointContainer
*This
= impl_from_IConnectionPointContainer(iface
);
76 FIXME("(%p)->(%p)\n", This
, ppEnum
);
80 static HRESULT WINAPI
ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer
*iface
,
81 REFIID riid
, LPCONNECTIONPOINT
*ppCP
)
83 ConnectionPointContainer
*This
= impl_from_IConnectionPointContainer(iface
);
86 WARN("ppCP == NULL\n");
92 if(IsEqualGUID(&DIID_DWebBrowserEvents2
, riid
)) {
93 TRACE("(%p)->(DIID_DWebBrowserEvents2 %p)\n", This
, ppCP
);
94 *ppCP
= &This
->wbe2
->IConnectionPoint_iface
;
95 }else if(IsEqualGUID(&DIID_DWebBrowserEvents
, riid
)) {
96 TRACE("(%p)->(DIID_DWebBrowserEvents %p)\n", This
, ppCP
);
97 *ppCP
= &This
->wbe
->IConnectionPoint_iface
;
98 }else if(IsEqualGUID(&IID_IPropertyNotifySink
, riid
)) {
99 TRACE("(%p)->(IID_IPropertyNotifySink %p)\n", This
, ppCP
);
100 *ppCP
= &This
->pns
->IConnectionPoint_iface
;
104 IConnectionPoint_AddRef(*ppCP
);
108 WARN("Unsupported IID %s\n", debugstr_guid(riid
));
109 return CONNECT_E_NOCONNECTION
;
112 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl
=
114 ConnectionPointContainer_QueryInterface
,
115 ConnectionPointContainer_AddRef
,
116 ConnectionPointContainer_Release
,
117 ConnectionPointContainer_EnumConnectionPoints
,
118 ConnectionPointContainer_FindConnectionPoint
122 /**********************************************************************
123 * Implement the IConnectionPoint interface
126 static inline ConnectionPoint
*impl_from_IConnectionPoint(IConnectionPoint
*iface
)
128 return CONTAINING_RECORD(iface
, ConnectionPoint
, IConnectionPoint_iface
);
132 IEnumConnections IEnumConnections_iface
;
140 static inline EnumConnections
*impl_from_IEnumConnections(IEnumConnections
*iface
)
142 return CONTAINING_RECORD(iface
, EnumConnections
, IEnumConnections_iface
);
145 static HRESULT WINAPI
EnumConnections_QueryInterface(IEnumConnections
*iface
, REFIID riid
, void **ppv
)
147 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
149 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
150 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
151 *ppv
= &This
->IEnumConnections_iface
;
152 }else if(IsEqualGUID(&IID_IEnumConnections
, riid
)) {
153 TRACE("(%p)->(IID_IEnumConnections %p)\n", This
, ppv
);
154 *ppv
= &This
->IEnumConnections_iface
;
156 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
158 return E_NOINTERFACE
;
161 IUnknown_AddRef((IUnknown
*)*ppv
);
165 static ULONG WINAPI
EnumConnections_AddRef(IEnumConnections
*iface
)
167 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
168 LONG ref
= InterlockedIncrement(&This
->ref
);
170 TRACE("(%p) ref=%ld\n", This
, ref
);
175 static ULONG WINAPI
EnumConnections_Release(IEnumConnections
*iface
)
177 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
178 LONG ref
= InterlockedDecrement(&This
->ref
);
180 TRACE("(%p) ref=%ld\n", This
, ref
);
183 IConnectionPoint_Release(&This
->cp
->IConnectionPoint_iface
);
190 static HRESULT WINAPI
EnumConnections_Next(IEnumConnections
*iface
, ULONG cConnections
, CONNECTDATA
*pgcd
, ULONG
*pcFetched
)
192 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
195 TRACE("(%p)->(%lu %p %p)\n", This
, cConnections
, pgcd
, pcFetched
);
197 while(cConnections
--) {
198 while(This
->iter
< This
->cp
->sinks_size
&& !This
->cp
->sinks
[This
->iter
])
200 if(This
->iter
== This
->cp
->sinks_size
)
203 pgcd
[cnt
].pUnk
= (IUnknown
*)This
->cp
->sinks
[This
->iter
];
204 pgcd
[cnt
].dwCookie
= cnt
+1;
211 return cnt
? S_OK
: S_FALSE
;
214 static HRESULT WINAPI
EnumConnections_Skip(IEnumConnections
*iface
, ULONG cConnections
)
216 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
217 FIXME("(%p)->(%lu)\n", This
, cConnections
);
221 static HRESULT WINAPI
EnumConnections_Reset(IEnumConnections
*iface
)
223 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
224 FIXME("(%p)\n", This
);
228 static HRESULT WINAPI
EnumConnections_Clone(IEnumConnections
*iface
, IEnumConnections
**ppEnum
)
230 EnumConnections
*This
= impl_from_IEnumConnections(iface
);
231 FIXME("(%p)->(%p)\n", This
, ppEnum
);
235 static const IEnumConnectionsVtbl EnumConnectionsVtbl
= {
236 EnumConnections_QueryInterface
,
237 EnumConnections_AddRef
,
238 EnumConnections_Release
,
239 EnumConnections_Next
,
240 EnumConnections_Skip
,
241 EnumConnections_Reset
,
242 EnumConnections_Clone
245 static HRESULT WINAPI
ConnectionPoint_QueryInterface(IConnectionPoint
*iface
,
246 REFIID riid
, LPVOID
*ppv
)
248 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
252 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
253 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
254 *ppv
= &This
->IConnectionPoint_iface
;
255 }else if(IsEqualGUID(&IID_IConnectionPoint
, riid
)) {
256 TRACE("(%p)->(IID_IConnectionPoint %p)\n", This
, ppv
);
257 *ppv
= &This
->IConnectionPoint_iface
;
261 IConnectionPointContainer_AddRef(This
->container
);
265 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
266 return E_NOINTERFACE
;
269 static ULONG WINAPI
ConnectionPoint_AddRef(IConnectionPoint
*iface
)
271 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
272 return IConnectionPointContainer_AddRef(This
->container
);
275 static ULONG WINAPI
ConnectionPoint_Release(IConnectionPoint
*iface
)
277 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
278 return IConnectionPointContainer_Release(This
->container
);
281 static HRESULT WINAPI
ConnectionPoint_GetConnectionInterface(IConnectionPoint
*iface
, IID
*pIID
)
283 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
285 TRACE("(%p)->(%p)\n", This
, pIID
);
291 static HRESULT WINAPI
ConnectionPoint_GetConnectionPointContainer(IConnectionPoint
*iface
,
292 IConnectionPointContainer
**ppCPC
)
294 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
296 TRACE("(%p)->(%p)\n", This
, ppCPC
);
298 *ppCPC
= This
->container
;
299 IConnectionPointContainer_AddRef(This
->container
);
303 static HRESULT WINAPI
ConnectionPoint_Advise(IConnectionPoint
*iface
, IUnknown
*pUnkSink
,
306 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
311 TRACE("(%p)->(%p %p)\n", This
, pUnkSink
, pdwCookie
);
313 hres
= IUnknown_QueryInterface(pUnkSink
, &This
->iid
, (void**)&disp
);
315 hres
= IUnknown_QueryInterface(pUnkSink
, &IID_IDispatch
, (void**)&disp
);
317 return CONNECT_E_CANNOTCONNECT
;
321 for(i
=0; i
<This
->sinks_size
; i
++) {
326 if(i
== This
->sinks_size
)
327 This
->sinks
= heap_realloc(This
->sinks
,
328 (++This
->sinks_size
)*sizeof(*This
->sinks
));
330 This
->sinks
= heap_alloc(sizeof(*This
->sinks
));
331 This
->sinks_size
= 1;
335 This
->sinks
[i
] = disp
;
341 static HRESULT WINAPI
ConnectionPoint_Unadvise(IConnectionPoint
*iface
, DWORD dwCookie
)
343 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
345 TRACE("(%p)->(%ld)\n", This
, dwCookie
);
347 if(!dwCookie
|| dwCookie
> This
->sinks_size
|| !This
->sinks
[dwCookie
-1])
348 return CONNECT_E_NOCONNECTION
;
350 IDispatch_Release(This
->sinks
[dwCookie
-1]);
351 This
->sinks
[dwCookie
-1] = NULL
;
356 static HRESULT WINAPI
ConnectionPoint_EnumConnections(IConnectionPoint
*iface
,
357 IEnumConnections
**ppEnum
)
359 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
360 EnumConnections
*ret
;
362 TRACE("(%p)->(%p)\n", This
, ppEnum
);
364 ret
= heap_alloc(sizeof(*ret
));
366 return E_OUTOFMEMORY
;
368 ret
->IEnumConnections_iface
.lpVtbl
= &EnumConnectionsVtbl
;
372 IConnectionPoint_AddRef(&This
->IConnectionPoint_iface
);
375 *ppEnum
= &ret
->IEnumConnections_iface
;
379 static const IConnectionPointVtbl ConnectionPointVtbl
=
381 ConnectionPoint_QueryInterface
,
382 ConnectionPoint_AddRef
,
383 ConnectionPoint_Release
,
384 ConnectionPoint_GetConnectionInterface
,
385 ConnectionPoint_GetConnectionPointContainer
,
386 ConnectionPoint_Advise
,
387 ConnectionPoint_Unadvise
,
388 ConnectionPoint_EnumConnections
391 void call_sink(ConnectionPoint
*This
, DISPID dispid
, DISPPARAMS
*dispparams
)
395 for(i
=0; i
<This
->sinks_size
; i
++) {
397 IDispatch_Invoke(This
->sinks
[i
], dispid
, &IID_NULL
, LOCALE_SYSTEM_DEFAULT
,
398 DISPATCH_METHOD
, dispparams
, NULL
, NULL
, NULL
);
402 static void ConnectionPoint_Create(REFIID riid
, ConnectionPoint
**cp
,
403 IConnectionPointContainer
*container
)
405 ConnectionPoint
*ret
= heap_alloc(sizeof(ConnectionPoint
));
407 ret
->IConnectionPoint_iface
.lpVtbl
= &ConnectionPointVtbl
;
411 ret
->container
= container
;
418 static void ConnectionPoint_Destroy(ConnectionPoint
*This
)
422 for(i
=0; i
<This
->sinks_size
; i
++) {
424 IDispatch_Release(This
->sinks
[i
]);
427 heap_free(This
->sinks
);
431 void ConnectionPointContainer_Init(ConnectionPointContainer
*This
, IUnknown
*impl
)
433 This
->IConnectionPointContainer_iface
.lpVtbl
= &ConnectionPointContainerVtbl
;
435 ConnectionPoint_Create(&DIID_DWebBrowserEvents2
, &This
->wbe2
, &This
->IConnectionPointContainer_iface
);
436 ConnectionPoint_Create(&DIID_DWebBrowserEvents
, &This
->wbe
, &This
->IConnectionPointContainer_iface
);
437 ConnectionPoint_Create(&IID_IPropertyNotifySink
, &This
->pns
, &This
->IConnectionPointContainer_iface
);
442 void ConnectionPointContainer_Destroy(ConnectionPointContainer
*This
)
444 ConnectionPoint_Destroy(This
->wbe2
);
445 ConnectionPoint_Destroy(This
->wbe
);
446 ConnectionPoint_Destroy(This
->pns
);