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);