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
31 #include "wine/debug.h"
33 #include "mshtml_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
37 #define CONPOINT(x) ((IConnectionPoint*) &(x)->lpConnectionPointVtbl);
39 struct ConnectionPoint
{
40 const IConnectionPointVtbl
*lpConnectionPointVtbl
;
47 IPropertyNotifySink
*propnotif
;
54 void call_property_onchanged(ConnectionPoint
*This
, DISPID dispid
)
58 for(i
=0; i
<This
->sinks_size
; i
++) {
59 if(This
->sinks
[i
].propnotif
)
60 IPropertyNotifySink_OnChanged(This
->sinks
[i
].propnotif
, dispid
);
64 #define CONPOINT_THIS(iface) DEFINE_THIS(ConnectionPoint, ConnectionPoint, iface)
66 static HRESULT WINAPI
ConnectionPoint_QueryInterface(IConnectionPoint
*iface
,
67 REFIID riid
, LPVOID
*ppv
)
69 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
73 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
74 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
75 *ppv
= CONPOINT(This
);
76 }else if(IsEqualGUID(&IID_IConnectionPoint
, riid
)) {
77 TRACE("(%p)->(IID_IConnectionPoint %p)\n", This
, ppv
);
78 *ppv
= CONPOINT(This
);
82 IUnknown_AddRef((IUnknown
*)*ppv
);
86 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
90 static ULONG WINAPI
ConnectionPoint_AddRef(IConnectionPoint
*iface
)
92 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
93 return IHTMLDocument2_AddRef(HTMLDOC(This
->doc
));
96 static ULONG WINAPI
ConnectionPoint_Release(IConnectionPoint
*iface
)
98 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
99 return IHTMLDocument2_Release(HTMLDOC(This
->doc
));
102 static HRESULT WINAPI
ConnectionPoint_GetConnectionInterface(IConnectionPoint
*iface
, IID
*pIID
)
104 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
106 TRACE("(%p)->(%p)\n", This
, pIID
);
111 memcpy(pIID
, &This
->iid
, sizeof(IID
));
115 static HRESULT WINAPI
ConnectionPoint_GetConnectionPointContainer(IConnectionPoint
*iface
,
116 IConnectionPointContainer
**ppCPC
)
118 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
120 TRACE("(%p)->(%p)\n", This
, ppCPC
);
125 *ppCPC
= CONPTCONT(This
->doc
);
126 IConnectionPointContainer_AddRef(*ppCPC
);
130 static HRESULT WINAPI
ConnectionPoint_Advise(IConnectionPoint
*iface
, IUnknown
*pUnkSink
,
133 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
138 TRACE("(%p)->(%p %p)\n", This
, pUnkSink
, pdwCookie
);
140 hres
= IUnknown_QueryInterface(pUnkSink
, &This
->iid
, (void**)&sink
);
141 if(FAILED(hres
) && !IsEqualGUID(&IID_IPropertyNotifySink
, &This
->iid
))
142 hres
= IUnknown_QueryInterface(pUnkSink
, &IID_IDispatch
, (void**)&sink
);
144 return CONNECT_E_CANNOTCONNECT
;
147 for(i
=0; i
<This
->sinks_size
; i
++) {
148 if(!This
->sinks
[i
].unk
)
152 if(i
== This
->sinks_size
)
153 This
->sinks
= mshtml_realloc(This
->sinks
,(++This
->sinks_size
)*sizeof(*This
->sinks
));
155 This
->sinks
= mshtml_alloc(sizeof(*This
->sinks
));
156 This
->sinks_size
= 1;
160 This
->sinks
[i
].unk
= sink
;
166 static HRESULT WINAPI
ConnectionPoint_Unadvise(IConnectionPoint
*iface
, DWORD dwCookie
)
168 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
169 TRACE("(%p)->(%d)\n", This
, dwCookie
);
171 if(!dwCookie
|| dwCookie
> This
->sinks_size
|| !This
->sinks
[dwCookie
-1].unk
)
172 return CONNECT_E_NOCONNECTION
;
174 IUnknown_Release(This
->sinks
[dwCookie
-1].unk
);
175 This
->sinks
[dwCookie
-1].unk
= NULL
;
180 static HRESULT WINAPI
ConnectionPoint_EnumConnections(IConnectionPoint
*iface
,
181 IEnumConnections
**ppEnum
)
183 ConnectionPoint
*This
= CONPOINT_THIS(iface
);
184 FIXME("(%p)->(%p)\n", This
, ppEnum
);
190 static const IConnectionPointVtbl ConnectionPointVtbl
=
192 ConnectionPoint_QueryInterface
,
193 ConnectionPoint_AddRef
,
194 ConnectionPoint_Release
,
195 ConnectionPoint_GetConnectionInterface
,
196 ConnectionPoint_GetConnectionPointContainer
,
197 ConnectionPoint_Advise
,
198 ConnectionPoint_Unadvise
,
199 ConnectionPoint_EnumConnections
202 static void ConnectionPoint_Create(HTMLDocument
*doc
, REFIID riid
, ConnectionPoint
**cp
)
204 ConnectionPoint
*ret
= mshtml_alloc(sizeof(ConnectionPoint
));
206 ret
->lpConnectionPointVtbl
= &ConnectionPointVtbl
;
210 memcpy(&ret
->iid
, riid
, sizeof(IID
));
215 static void ConnectionPoint_Destroy(ConnectionPoint
*This
)
219 for(i
=0; i
<This
->sinks_size
; i
++) {
220 if(This
->sinks
[i
].unk
)
221 IUnknown_Release(This
->sinks
[i
].unk
);
224 mshtml_free(This
->sinks
);
228 #define CONPTCONT_THIS(iface) DEFINE_THIS(HTMLDocument, ConnectionPointContainer, iface)
230 static HRESULT WINAPI
ConnectionPointContainer_QueryInterface(IConnectionPointContainer
*iface
,
231 REFIID riid
, void **ppv
)
233 HTMLDocument
*This
= CONPTCONT_THIS(iface
);
234 return IHTMLDocument2_QueryInterface(HTMLDOC(This
), riid
, ppv
);
237 static ULONG WINAPI
ConnectionPointContainer_AddRef(IConnectionPointContainer
*iface
)
239 HTMLDocument
*This
= CONPTCONT_THIS(iface
);
240 return IHTMLDocument2_AddRef(HTMLDOC(This
));
243 static ULONG WINAPI
ConnectionPointContainer_Release(IConnectionPointContainer
*iface
)
245 HTMLDocument
*This
= CONPTCONT_THIS(iface
);
246 return IHTMLDocument2_Release(HTMLDOC(This
));
249 static HRESULT WINAPI
ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer
*iface
,
250 IEnumConnectionPoints
**ppEnum
)
252 HTMLDocument
*This
= CONPTCONT_THIS(iface
);
253 FIXME("(%p)->(%p)\n", This
, ppEnum
);
257 static HRESULT WINAPI
ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer
*iface
,
258 REFIID riid
, IConnectionPoint
**ppCP
)
260 HTMLDocument
*This
= CONPTCONT_THIS(iface
);
264 if(IsEqualGUID(&DIID_HTMLDocumentEvents
, riid
)) {
265 TRACE("(%p)->(DIID_HTMLDocumentEvents %p)\n", This
, ppCP
);
266 *ppCP
= CONPOINT(This
->cp_htmldocevents
);
267 }else if(IsEqualGUID(&DIID_HTMLDocumentEvents2
, riid
)) {
268 TRACE("(%p)->(DIID_HTMLDocumentEvents2 %p)\n", This
, ppCP
);
269 *ppCP
= CONPOINT(This
->cp_htmldocevents2
);
270 }else if(IsEqualGUID(&IID_IPropertyNotifySink
, riid
)) {
271 TRACE("(%p)->(IID_IPropertyNotifySink %p)\n", This
, ppCP
);
272 *ppCP
= CONPOINT(This
->cp_propnotif
);
276 IConnectionPoint_AddRef(*ppCP
);
280 FIXME("(%p)->(%s %p) unsupported riid\n", This
, debugstr_guid(riid
), ppCP
);
281 return CONNECT_E_NOCONNECTION
;
284 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl
= {
285 ConnectionPointContainer_QueryInterface
,
286 ConnectionPointContainer_AddRef
,
287 ConnectionPointContainer_Release
,
288 ConnectionPointContainer_EnumConnectionPoints
,
289 ConnectionPointContainer_FindConnectionPoint
292 #undef CONPTCONT_THIS
294 void HTMLDocument_ConnectionPoints_Init(HTMLDocument
*This
)
296 This
->lpConnectionPointContainerVtbl
= &ConnectionPointContainerVtbl
;
298 ConnectionPoint_Create(This
, &IID_IPropertyNotifySink
, &This
->cp_propnotif
);
299 ConnectionPoint_Create(This
, &DIID_HTMLDocumentEvents
, &This
->cp_htmldocevents
);
300 ConnectionPoint_Create(This
, &DIID_HTMLDocumentEvents2
, &This
->cp_htmldocevents2
);
303 void HTMLDocument_ConnectionPoints_Destroy(HTMLDocument
*This
)
305 ConnectionPoint_Destroy(This
->cp_propnotif
);
306 ConnectionPoint_Destroy(This
->cp_htmldocevents
);
307 ConnectionPoint_Destroy(This
->cp_htmldocevents2
);