Nikolay Sivov : msxml3: Store document event handler for ready state notification.
Alexandre Julliard
julliard at winehq.org
Tue Feb 22 10:36:10 CST 2011
Module: wine
Branch: master
Commit: df08e9b4f63064e017f6f1058cec87f1fb7a6dd4
URL: http://source.winehq.org/git/wine.git/?a=commit;h=df08e9b4f63064e017f6f1058cec87f1fb7a6dd4
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Sat Feb 19 17:09:58 2011 +0300
msxml3: Store document event handler for ready state notification.
---
dlls/msxml3/domdoc.c | 54 +++++++++++++++++++++++++++++++++++++++----
dlls/msxml3/tests/domdoc.c | 51 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 100 insertions(+), 5 deletions(-)
diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index f5bfaa4..417b988 100644
--- a/dlls/msxml3/domdoc.c
+++ b/dlls/msxml3/domdoc.c
@@ -105,6 +105,13 @@ struct ConnectionPoint
DWORD sinks_size;
};
+typedef enum {
+ EVENTID_READYSTATECHANGE = 0,
+ EVENTID_DATAAVAILABLE,
+ EVENTID_TRANSFORMNODE,
+ EVENTID_LAST
+} eventid_t;
+
struct domdoc
{
xmlnode node;
@@ -136,8 +143,37 @@ struct domdoc
ConnectionPoint cp_domdocevents;
ConnectionPoint cp_propnotif;
ConnectionPoint cp_dispatch;
+
+ /* events */
+ IDispatch *events[EVENTID_LAST];
};
+static HRESULT set_doc_event(domdoc *doc, eventid_t eid, const VARIANT *v)
+{
+ IDispatch *disp;
+
+ switch (V_VT(v))
+ {
+ case VT_UNKNOWN:
+ if (V_UNKNOWN(v))
+ IUnknown_QueryInterface(V_UNKNOWN(v), &IID_IDispatch, (void**)&disp);
+ else
+ disp = NULL;
+ break;
+ case VT_DISPATCH:
+ disp = V_DISPATCH(v);
+ if (disp) IDispatch_AddRef(disp);
+ break;
+ default:
+ return DISP_E_TYPEMISMATCH;
+ }
+
+ if (doc->events[eid]) IDispatch_Release(doc->events[eid]);
+ doc->events[eid] = disp;
+
+ return S_OK;
+}
+
static inline ConnectionPoint *impl_from_IConnectionPoint(IConnectionPoint *iface)
{
return (ConnectionPoint *)((char*)iface - FIELD_OFFSET(ConnectionPoint, lpVtblConnectionPoint));
@@ -909,6 +945,8 @@ static ULONG WINAPI domdoc_Release(
if ( ref == 0 )
{
+ int eid;
+
if(This->bsc)
detach_bsc(This->bsc);
@@ -917,6 +955,10 @@ static ULONG WINAPI domdoc_Release(
destroy_xmlnode(&This->node);
if (This->stream)
IStream_Release(This->stream);
+
+ for (eid = 0; eid < EVENTID_LAST; eid++)
+ if (This->events[eid]) IDispatch_Release(This->events[eid]);
+
heap_free(This);
}
@@ -2470,13 +2512,14 @@ static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
}
-static HRESULT WINAPI domdoc_put_onReadyStateChange(
+static HRESULT WINAPI domdoc_put_onreadystatechange(
IXMLDOMDocument3 *iface,
- VARIANT readyStateChangeSink )
+ VARIANT event )
{
domdoc *This = impl_from_IXMLDOMDocument3( iface );
- FIXME("%p\n", This);
- return E_NOTIMPL;
+
+ TRACE("(%p)->(%s)\n", This, debugstr_variant(&event));
+ return set_doc_event(This, EVENTID_READYSTATECHANGE, &event);
}
@@ -3040,7 +3083,7 @@ static const struct IXMLDOMDocument3Vtbl domdoc_vtbl =
domdoc_put_resolveExternals,
domdoc_get_preserveWhiteSpace,
domdoc_put_preserveWhiteSpace,
- domdoc_put_onReadyStateChange,
+ domdoc_put_onreadystatechange,
domdoc_put_onDataAvailable,
domdoc_put_onTransformNode,
domdoc_get_namespaces,
@@ -3402,6 +3445,7 @@ HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **docu
doc->safeopt = 0;
doc->bsc = NULL;
doc->cp_list = NULL;
+ memset(doc->events, 0, sizeof(doc->events));
/* events connection points */
ConnectionPoint_Init(&doc->cp_dispatch, doc, &IID_IDispatch);
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index e38d3b5..eee20a6 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -7530,6 +7530,9 @@ static void test_events(void)
IConnectionPoint *point;
IXMLDOMDocument *doc;
HRESULT hr;
+ VARIANT v;
+ IDispatch *event;
+ ULONG ref;
doc = create_document(&IID_IXMLDOMDocument);
if (!doc) return;
@@ -7549,6 +7552,54 @@ static void test_events(void)
IConnectionPointContainer_Release(conn);
+ /* ready state callback */
+ VariantInit(&v);
+ hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
+ ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
+
+ event = create_dispevent();
+ V_VT(&v) = VT_UNKNOWN;
+ V_UNKNOWN(&v) = (IUnknown*)event;
+
+ hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ref = IDispatch_AddRef(event);
+ IDispatch_Release(event);
+ ok(ref == 3, "got %d\n", ref);
+
+ V_VT(&v) = VT_DISPATCH;
+ V_DISPATCH(&v) = event;
+
+ hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ref = IDispatch_AddRef(event);
+ IDispatch_Release(event);
+ ok(ref == 3, "got %d\n", ref);
+
+ /* VT_NULL doesn't reset event handler */
+ V_VT(&v) = VT_NULL;
+ hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
+ ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
+ ref = IDispatch_AddRef(event);
+ IDispatch_Release(event);
+ ok(ref == 3, "got %d\n", ref);
+
+ V_VT(&v) = VT_DISPATCH;
+ V_DISPATCH(&v) = NULL;
+
+ hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ref = IDispatch_AddRef(event);
+ IDispatch_Release(event);
+ ok(ref == 2, "got %d\n", ref);
+
+ V_VT(&v) = VT_UNKNOWN;
+ V_DISPATCH(&v) = NULL;
+ hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ IDispatch_Release(event);
+
IXMLDOMDocument_Release(doc);
}
More information about the wine-cvs
mailing list