Nikolay Sivov : msxml3: Support IDispatchEx for IXMLDOMNodeList too.
Alexandre Julliard
julliard at winehq.org
Mon Nov 21 11:10:07 CST 2011
Module: wine
Branch: master
Commit: 85ce39ddca6744bfa364058f7e25270b42288823
URL: http://source.winehq.org/git/wine.git/?a=commit;h=85ce39ddca6744bfa364058f7e25270b42288823
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Sat Nov 19 20:55:30 2011 +0300
msxml3: Support IDispatchEx for IXMLDOMNodeList too.
---
dlls/msxml3/nodelist.c | 148 +++++++++++++++++++++++++++-----------------
dlls/msxml3/selection.c | 2 +-
dlls/msxml3/tests/domdoc.c | 21 ++++++
3 files changed, 114 insertions(+), 57 deletions(-)
diff --git a/dlls/msxml3/nodelist.c b/dlls/msxml3/nodelist.c
index 6a25463..5710d48 100644
--- a/dlls/msxml3/nodelist.c
+++ b/dlls/msxml3/nodelist.c
@@ -33,6 +33,7 @@
#include "winuser.h"
#include "ole2.h"
#include "msxml6.h"
+#include "msxml2did.h"
#include "msxml_private.h"
@@ -53,6 +54,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
typedef struct _xmlnodelist
{
+ DispatchEx dispex;
IXMLDOMNodeList IXMLDOMNodeList_iface;
LONG ref;
xmlNodePtr parent;
@@ -69,7 +71,9 @@ static HRESULT WINAPI xmlnodelist_QueryInterface(
REFIID riid,
void** ppvObject )
{
- TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject);
+ xmlnodelist *This = impl_from_IXMLDOMNodeList( iface );
+
+ TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
if ( IsEqualGUID( riid, &IID_IUnknown ) ||
IsEqualGUID( riid, &IID_IDispatch ) ||
@@ -77,6 +81,10 @@ static HRESULT WINAPI xmlnodelist_QueryInterface(
{
*ppvObject = iface;
}
+ else if (dispex_query_interface(&This->dispex, riid, ppvObject))
+ {
+ return *ppvObject ? S_OK : E_NOINTERFACE;
+ }
else
{
TRACE("interface %s not implemented\n", debugstr_guid(riid));
@@ -119,12 +127,7 @@ static HRESULT WINAPI xmlnodelist_GetTypeInfoCount(
UINT* pctinfo )
{
xmlnodelist *This = impl_from_IXMLDOMNodeList( iface );
-
- TRACE("(%p)->(%p)\n", This, pctinfo);
-
- *pctinfo = 1;
-
- return S_OK;
+ return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
}
static HRESULT WINAPI xmlnodelist_GetTypeInfo(
@@ -134,13 +137,8 @@ static HRESULT WINAPI xmlnodelist_GetTypeInfo(
ITypeInfo** ppTInfo )
{
xmlnodelist *This = impl_from_IXMLDOMNodeList( iface );
- HRESULT hr;
-
- TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
-
- hr = get_typeinfo(IXMLDOMNodeList_tid, ppTInfo);
-
- return hr;
+ return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
+ iTInfo, lcid, ppTInfo);
}
static HRESULT WINAPI xmlnodelist_GetIDsOfNames(
@@ -152,23 +150,8 @@ static HRESULT WINAPI xmlnodelist_GetIDsOfNames(
DISPID* rgDispId )
{
xmlnodelist *This = impl_from_IXMLDOMNodeList( iface );
- ITypeInfo *typeinfo;
- HRESULT hr;
-
- TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
- lcid, rgDispId);
-
- if(!rgszNames || cNames == 0 || !rgDispId)
- return E_INVALIDARG;
-
- hr = get_typeinfo(IXMLDOMNodeList_tid, &typeinfo);
- if(SUCCEEDED(hr))
- {
- hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
- ITypeInfo_Release(typeinfo);
- }
-
- return hr;
+ return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
+ riid, rgszNames, cNames, lcid, rgDispId);
}
static HRESULT WINAPI xmlnodelist_Invoke(
@@ -183,21 +166,8 @@ static HRESULT WINAPI xmlnodelist_Invoke(
UINT* puArgErr )
{
xmlnodelist *This = impl_from_IXMLDOMNodeList( iface );
- ITypeInfo *typeinfo;
- HRESULT hr;
-
- TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
- lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
-
- hr = get_typeinfo(IXMLDOMNodeList_tid, &typeinfo);
- if(SUCCEEDED(hr))
- {
- hr = ITypeInfo_Invoke(typeinfo, &This->IXMLDOMNodeList_iface, dispIdMember, wFlags,
- pDispParams, pVarResult, pExcepInfo, puArgErr);
- ITypeInfo_Release(typeinfo);
- }
-
- return hr;
+ return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
+ dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
}
static HRESULT WINAPI xmlnodelist_get_item(
@@ -298,7 +268,6 @@ static HRESULT WINAPI xmlnodelist__newEnum(
return E_NOTIMPL;
}
-
static const struct IXMLDOMNodeListVtbl xmlnodelist_vtbl =
{
xmlnodelist_QueryInterface,
@@ -315,22 +284,89 @@ static const struct IXMLDOMNodeListVtbl xmlnodelist_vtbl =
xmlnodelist__newEnum,
};
+static HRESULT xmlnodelist_get_dispid(IUnknown *iface, BSTR name, DWORD flags, DISPID *dispid)
+{
+ WCHAR *ptr;
+ int idx = 0;
+
+ for(ptr = name; *ptr && isdigitW(*ptr); ptr++)
+ idx = idx*10 + (*ptr-'0');
+ if(*ptr)
+ return DISP_E_UNKNOWNNAME;
+
+ *dispid = DISPID_DOM_COLLECTION_BASE + idx;
+ TRACE("ret %x\n", *dispid);
+ return S_OK;
+}
+
+static HRESULT xmlnodelist_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
+ VARIANT *res, EXCEPINFO *ei)
+{
+ xmlnodelist *This = impl_from_IXMLDOMNodeList( (IXMLDOMNodeList*)iface );
+
+ TRACE("(%p)->(%x %x %x %p %p %p)\n", This, id, lcid, flags, params, res, ei);
+
+ V_VT(res) = VT_DISPATCH;
+ V_DISPATCH(res) = NULL;
+
+ if (id < DISPID_DOM_COLLECTION_BASE || id > DISPID_DOM_COLLECTION_MAX)
+ return DISP_E_UNKNOWNNAME;
+
+ switch(flags)
+ {
+ case INVOKE_PROPERTYGET:
+ {
+ IXMLDOMNode *disp = NULL;
+
+ IXMLDOMNodeList_get_item(&This->IXMLDOMNodeList_iface, id - DISPID_DOM_COLLECTION_BASE, &disp);
+ V_DISPATCH(res) = (IDispatch*)disp;
+ break;
+ }
+ default:
+ {
+ FIXME("unimplemented flags %x\n", flags);
+ break;
+ }
+ }
+
+ TRACE("ret %p\n", V_DISPATCH(res));
+
+ return S_OK;
+}
+
+static const dispex_static_data_vtbl_t xmlnodelist_dispex_vtbl = {
+ xmlnodelist_get_dispid,
+ xmlnodelist_invoke
+};
+
+static const tid_t xmlnodelist_iface_tids[] = {
+ IXMLDOMNodeList_tid,
+ 0
+};
+static dispex_static_data_t xmlnodelist_dispex = {
+ &xmlnodelist_dispex_vtbl,
+ IXMLDOMNodeList_tid,
+ NULL,
+ xmlnodelist_iface_tids
+};
+
IXMLDOMNodeList* create_children_nodelist( xmlNodePtr node )
{
- xmlnodelist *nodelist;
+ xmlnodelist *This;
- nodelist = heap_alloc( sizeof *nodelist );
- if ( !nodelist )
+ This = heap_alloc( sizeof *This );
+ if ( !This )
return NULL;
- nodelist->IXMLDOMNodeList_iface.lpVtbl = &xmlnodelist_vtbl;
- nodelist->ref = 1;
- nodelist->parent = node;
- nodelist->current = node->children;
-
+ This->IXMLDOMNodeList_iface.lpVtbl = &xmlnodelist_vtbl;
+ This->ref = 1;
+ This->parent = node;
+ This->current = node->children;
xmldoc_add_ref( node->doc );
- return &nodelist->IXMLDOMNodeList_iface;
+ init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMNodeList_iface, &xmlnodelist_dispex);
+
+ return &This->IXMLDOMNodeList_iface;
}
#endif
diff --git a/dlls/msxml3/selection.c b/dlls/msxml3/selection.c
index aba8e7d..8871817 100644
--- a/dlls/msxml3/selection.c
+++ b/dlls/msxml3/selection.c
@@ -600,7 +600,7 @@ static HRESULT domselection_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD f
{
IXMLDOMNode *disp = NULL;
- domselection_get_item(&This->IXMLDOMSelection_iface, id - DISPID_DOM_COLLECTION_BASE, &disp);
+ IXMLDOMSelection_get_item(&This->IXMLDOMSelection_iface, id - DISPID_DOM_COLLECTION_BASE, &disp);
V_DISPATCH(res) = (IDispatch*)disp;
break;
}
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index abd0b37..e72e1f3 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -10531,6 +10531,27 @@ static void test_dispex(void)
IUnknown_Release(unk);
IXMLDOMNodeList_Release(node_list);
+ /* IXMLDOMNodeList for children list */
+ hr = IXMLDOMDocument_get_childNodes(doc, &node_list);
+ EXPECT_HR(hr, S_OK);
+ IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
+ test_domobj_dispex(unk);
+ IUnknown_Release(unk);
+
+ /* collection dispex test, empty collection */
+ hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatchEx, (void**)&dispex);
+ EXPECT_HR(hr, S_OK);
+ did = 0;
+ hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
+ EXPECT_HR(hr, S_OK);
+ ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
+ hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
+ EXPECT_HR(hr, S_OK);
+ ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
+ IDispatchEx_Release(dispex);
+
+ IXMLDOMNodeList_Release(node_list);
+
/* IXMLDOMParseError */
hr = IXMLDOMDocument_get_parseError(doc, &error);
EXPECT_HR(hr, S_OK);
More information about the wine-cvs
mailing list