Module: wine Branch: master Commit: 85ce39ddca6744bfa364058f7e25270b42288823 URL: http://source.winehq.org/git/wine.git/?a=commit;h=85ce39ddca6744bfa364058f7e...
Author: Nikolay Sivov nsivov@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);