2 * Copyright 2006 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wine/debug.h"
30 #include "mshtml_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
34 #define CONPOINT(x) ((IConnectionPoint*) &(x)->lpConnectionPointVtbl);
36 static const char *debugstr_cp_guid(REFIID riid
)
39 if(IsEqualGUID(riid, &x)) \
42 X(IID_IPropertyNotifySink
);
43 X(DIID_HTMLDocumentEvents
);
44 X(DIID_HTMLDocumentEvents2
);
45 X(DIID_HTMLTableEvents
);
46 X(DIID_HTMLTextContainerEvents
);
50 return debugstr_guid(riid
);
53 void call_property_onchanged(ConnectionPoint
*This
, DISPID dispid
)
57 for(i
=0; i
<This
->sinks_size
; i
++) {
58 if(This
->sinks
[i
].propnotif
)
59 IPropertyNotifySink_OnChanged(This
->sinks
[i
].propnotif
, dispid
);
63 #define CONPOINT_THIS(iface) DEFINE_THIS(ConnectionPoint, ConnectionPoint, iface)
65 static HRESULT WINAPI
ConnectionPoint_QueryInterface(IConnectionPoint
*iface
,
66 REFIID riid
, LPVOID
*ppv
)
68 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
72 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
73 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
74 *ppv
= CONPOINT(This
);
75 }else if(IsEqualGUID(&IID_IConnectionPoint
, riid
)) {
76 TRACE("(%p)->(IID_IConnectionPoint %p)\n", This
, ppv
);
77 *ppv
= CONPOINT(This
);
81 IUnknown_AddRef((IUnknown
*)*ppv
);
85 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
89 static ULONG WINAPI
ConnectionPoint_AddRef(IConnectionPoint
*iface
)
91 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
92 return IConnectionPointContainer_AddRef(CONPTCONT(This
->container
));
95 static ULONG WINAPI
ConnectionPoint_Release(IConnectionPoint
*iface
)
97 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
98 return IConnectionPointContainer_Release(CONPTCONT(This
->container
));
101 static HRESULT WINAPI
ConnectionPoint_GetConnectionInterface(IConnectionPoint
*iface
, IID
*pIID
)
103 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
105 TRACE("(%p)->(%p)\n", This
, pIID
);
114 static HRESULT WINAPI
ConnectionPoint_GetConnectionPointContainer(IConnectionPoint
*iface
,
115 IConnectionPointContainer
**ppCPC
)
117 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
119 TRACE("(%p)->(%p)\n", This
, ppCPC
);
124 *ppCPC
= CONPTCONT(This
->container
);
125 IConnectionPointContainer_AddRef(*ppCPC
);
129 static HRESULT WINAPI
ConnectionPoint_Advise(IConnectionPoint
*iface
, IUnknown
*pUnkSink
,
132 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
137 TRACE("(%p)->(%p %p)\n", This
, pUnkSink
, pdwCookie
);
139 hres
= IUnknown_QueryInterface(pUnkSink
, This
->iid
, (void**)&sink
);
140 if(FAILED(hres
) && !IsEqualGUID(&IID_IPropertyNotifySink
, This
->iid
))
141 hres
= IUnknown_QueryInterface(pUnkSink
, &IID_IDispatch
, (void**)&sink
);
143 return CONNECT_E_CANNOTCONNECT
;
146 for(i
=0; i
<This
->sinks_size
; i
++) {
147 if(!This
->sinks
[i
].unk
)
151 if(i
== This
->sinks_size
)
152 This
->sinks
= heap_realloc(This
->sinks
,(++This
->sinks_size
)*sizeof(*This
->sinks
));
154 This
->sinks
= heap_alloc(sizeof(*This
->sinks
));
155 This
->sinks_size
= 1;
159 This
->sinks
[i
].unk
= sink
;
162 if(!i
&& This
->data
&& This
->data
->on_advise
)
163 This
->data
->on_advise(This
->container
->outer
, This
->data
);
168 static HRESULT WINAPI
ConnectionPoint_Unadvise(IConnectionPoint
*iface
, DWORD dwCookie
)
170 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
171 TRACE("(%p)->(%d)\n", This
, dwCookie
);
173 if(!dwCookie
|| dwCookie
> This
->sinks_size
|| !This
->sinks
[dwCookie
-1].unk
)
174 return CONNECT_E_NOCONNECTION
;
176 IUnknown_Release(This
->sinks
[dwCookie
-1].unk
);
177 This
->sinks
[dwCookie
-1].unk
= NULL
;
182 static HRESULT WINAPI
ConnectionPoint_EnumConnections(IConnectionPoint
*iface
,
183 IEnumConnections
**ppEnum
)
185 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
186 FIXME("(%p)->(%p)\n", This
, ppEnum
);
192 static const IConnectionPointVtbl ConnectionPointVtbl
=
194 ConnectionPoint_QueryInterface
,
195 ConnectionPoint_AddRef
,
196 ConnectionPoint_Release
,
197 ConnectionPoint_GetConnectionInterface
,
198 ConnectionPoint_GetConnectionPointContainer
,
199 ConnectionPoint_Advise
,
200 ConnectionPoint_Unadvise
,
201 ConnectionPoint_EnumConnections
204 void ConnectionPoint_Init(ConnectionPoint
*cp
, ConnectionPointContainer
*container
, REFIID riid
, cp_static_data_t
*data
)
206 cp
->lpConnectionPointVtbl
= &ConnectionPointVtbl
;
207 cp
->container
= container
;
214 cp
->next
= container
->cp_list
;
215 container
->cp_list
= cp
;
218 static void ConnectionPoint_Destroy(ConnectionPoint
*This
)
222 for(i
=0; i
<This
->sinks_size
; i
++) {
223 if(This
->sinks
[i
].unk
)
224 IUnknown_Release(This
->sinks
[i
].unk
);
227 heap_free(This
->sinks
);
230 #define CONPTCONT_THIS(iface) DEFINE_THIS(ConnectionPointContainer, ConnectionPointContainer, iface)
232 static HRESULT WINAPI
ConnectionPointContainer_QueryInterface(IConnectionPointContainer
*iface
,
233 REFIID riid
, void **ppv
)
235 ConnectionPointContainer
*This
= CONPTCONT_THIS(iface
);
236 return IUnknown_QueryInterface(This
->outer
, riid
, ppv
);
239 static ULONG WINAPI
ConnectionPointContainer_AddRef(IConnectionPointContainer
*iface
)
241 ConnectionPointContainer
*This
= CONPTCONT_THIS(iface
);
242 return IUnknown_AddRef(This
->outer
);
245 static ULONG WINAPI
ConnectionPointContainer_Release(IConnectionPointContainer
*iface
)
247 ConnectionPointContainer
*This
= CONPTCONT_THIS(iface
);
248 return IUnknown_Release(This
->outer
);
251 static HRESULT WINAPI
ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer
*iface
,
252 IEnumConnectionPoints
**ppEnum
)
254 ConnectionPointContainer
*This
= CONPTCONT_THIS(iface
);
255 FIXME("(%p)->(%p)\n", This
, ppEnum
);
259 static HRESULT WINAPI
ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer
*iface
,
260 REFIID riid
, IConnectionPoint
**ppCP
)
262 ConnectionPointContainer
*This
= CONPTCONT_THIS(iface
);
263 ConnectionPoint
*iter
;
265 TRACE("(%p)->(%s %p)\n", This
, debugstr_cp_guid(riid
), ppCP
);
267 if(This
->forward_container
)
268 return IConnectionPointContainer_FindConnectionPoint(CONPTCONT(This
), riid
, ppCP
);
272 for(iter
= This
->cp_list
; iter
; iter
= iter
->next
) {
273 if(IsEqualGUID(iter
->iid
, riid
))
274 *ppCP
= CONPOINT(iter
);
278 IConnectionPoint_AddRef(*ppCP
);
282 FIXME("unsupported riid %s\n", debugstr_cp_guid(riid
));
283 return CONNECT_E_NOCONNECTION
;
286 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl
= {
287 ConnectionPointContainer_QueryInterface
,
288 ConnectionPointContainer_AddRef
,
289 ConnectionPointContainer_Release
,
290 ConnectionPointContainer_EnumConnectionPoints
,
291 ConnectionPointContainer_FindConnectionPoint
294 #undef CONPTCONT_THIS
296 void ConnectionPointContainer_Init(ConnectionPointContainer
*This
, IUnknown
*outer
)
298 This
->lpConnectionPointContainerVtbl
= &ConnectionPointContainerVtbl
;
299 This
->cp_list
= NULL
;
303 void ConnectionPointContainer_Destroy(ConnectionPointContainer
*This
)
305 ConnectionPoint
*iter
= This
->cp_list
;
308 ConnectionPoint_Destroy(iter
);