msxml3: Add IDispatchEx support for IXMLDOMNamedNodeMap.
This commit is contained in:
parent
5ea259e8e4
commit
70e0290dcf
|
@ -326,11 +326,6 @@ static dispex_data_t *get_dispex_data(DispatchEx *This)
|
|||
return This->data->data;
|
||||
}
|
||||
|
||||
static inline BOOL is_custom_dispid(DISPID id)
|
||||
{
|
||||
return MSXML_DISPID_CUSTOM_MIN <= id && id <= MSXML_DISPID_CUSTOM_MAX;
|
||||
}
|
||||
|
||||
static inline BOOL is_dynamic_dispid(DISPID id)
|
||||
{
|
||||
return DISPID_DYNPROP_0 <= id && id <= DISPID_DYNPROP_MAX;
|
||||
|
@ -523,8 +518,10 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
|||
|
||||
TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
|
||||
|
||||
if(is_custom_dispid(id) && This->data->vtbl && This->data->vtbl->invoke)
|
||||
return This->data->vtbl->invoke(This->outer, id, lcid, wFlags, pdp, pvarRes, pei);
|
||||
if(This->data->vtbl && This->data->vtbl->invoke) {
|
||||
hres = This->data->vtbl->invoke(This->outer, id, lcid, wFlags, pdp, pvarRes, pei);
|
||||
if (hres != DISP_E_UNKNOWNNAME) return hres;
|
||||
}
|
||||
|
||||
if(wFlags == DISPATCH_CONSTRUCT) {
|
||||
FIXME("DISPATCH_CONSTRUCT not implemented\n");
|
||||
|
|
|
@ -130,9 +130,6 @@ extern void release_typelib(void) DECLSPEC_HIDDEN;
|
|||
typedef struct dispex_data_t dispex_data_t;
|
||||
typedef struct dispex_dynamic_data_t dispex_dynamic_data_t;
|
||||
|
||||
#define MSXML_DISPID_CUSTOM_MIN 0x60000000
|
||||
#define MSXML_DISPID_CUSTOM_MAX 0x6fffffff
|
||||
|
||||
typedef struct {
|
||||
HRESULT (*get_dispid)(IUnknown*,BSTR,DWORD,DISPID*);
|
||||
HRESULT (*invoke)(IUnknown*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "winnls.h"
|
||||
#include "ole2.h"
|
||||
#include "msxml6.h"
|
||||
#include "msxml2did.h"
|
||||
|
||||
#include "msxml_private.h"
|
||||
|
||||
|
@ -45,6 +46,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
|
|||
|
||||
typedef struct _xmlnodemap
|
||||
{
|
||||
DispatchEx dispex;
|
||||
IXMLDOMNamedNodeMap IXMLDOMNamedNodeMap_iface;
|
||||
ISupportErrorInfo ISupportErrorInfo_iface;
|
||||
LONG ref;
|
||||
|
@ -76,6 +78,10 @@ static HRESULT WINAPI xmlnodemap_QueryInterface(
|
|||
{
|
||||
*ppvObject = iface;
|
||||
}
|
||||
else if (dispex_query_interface(&This->dispex, riid, ppvObject))
|
||||
{
|
||||
return *ppvObject ? S_OK : E_NOINTERFACE;
|
||||
}
|
||||
else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
|
||||
{
|
||||
*ppvObject = &This->ISupportErrorInfo_iface;
|
||||
|
@ -111,6 +117,7 @@ static ULONG WINAPI xmlnodemap_Release(
|
|||
if ( ref == 0 )
|
||||
{
|
||||
xmldoc_release( This->node->doc );
|
||||
release_dispex(&This->dispex);
|
||||
heap_free( This );
|
||||
}
|
||||
|
||||
|
@ -516,23 +523,92 @@ static const struct ISupportErrorInfoVtbl support_error_vtbl =
|
|||
support_error_InterfaceSupportsErrorInfo
|
||||
};
|
||||
|
||||
static HRESULT xmlnodemap_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 xmlnodemap_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
|
||||
VARIANT *res, EXCEPINFO *ei)
|
||||
{
|
||||
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( (IXMLDOMNamedNodeMap*)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;
|
||||
|
||||
IXMLDOMNamedNodeMap_get_item(&This->IXMLDOMNamedNodeMap_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 xmlnodemap_dispex_vtbl = {
|
||||
xmlnodemap_get_dispid,
|
||||
xmlnodemap_invoke
|
||||
};
|
||||
|
||||
static const tid_t xmlnodemap_iface_tids[] = {
|
||||
IXMLDOMNamedNodeMap_tid,
|
||||
0
|
||||
};
|
||||
|
||||
static dispex_static_data_t xmlnodemap_dispex = {
|
||||
&xmlnodemap_dispex_vtbl,
|
||||
IXMLDOMNamedNodeMap_tid,
|
||||
NULL,
|
||||
xmlnodemap_iface_tids
|
||||
};
|
||||
|
||||
IXMLDOMNamedNodeMap *create_nodemap( const xmlNodePtr node )
|
||||
{
|
||||
xmlnodemap *nodemap;
|
||||
xmlnodemap *This;
|
||||
|
||||
nodemap = heap_alloc( sizeof *nodemap );
|
||||
if ( !nodemap )
|
||||
This = heap_alloc( sizeof *This );
|
||||
if ( !This )
|
||||
return NULL;
|
||||
|
||||
nodemap->IXMLDOMNamedNodeMap_iface.lpVtbl = &xmlnodemap_vtbl;
|
||||
nodemap->ISupportErrorInfo_iface.lpVtbl = &support_error_vtbl;
|
||||
nodemap->node = node;
|
||||
nodemap->ref = 1;
|
||||
nodemap->iterator = 0;
|
||||
This->IXMLDOMNamedNodeMap_iface.lpVtbl = &xmlnodemap_vtbl;
|
||||
This->ISupportErrorInfo_iface.lpVtbl = &support_error_vtbl;
|
||||
This->node = node;
|
||||
This->ref = 1;
|
||||
This->iterator = 0;
|
||||
|
||||
init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMNamedNodeMap_iface, &xmlnodemap_dispex);
|
||||
|
||||
xmldoc_add_ref(node->doc);
|
||||
|
||||
return &nodemap->IXMLDOMNamedNodeMap_iface;
|
||||
return &This->IXMLDOMNamedNodeMap_iface;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "winuser.h"
|
||||
#include "ole2.h"
|
||||
#include "msxml6.h"
|
||||
#include "msxml2did.h"
|
||||
|
||||
#include "msxml_private.h"
|
||||
|
||||
|
@ -617,7 +618,7 @@ static HRESULT domselection_get_dispid(IUnknown *iface, BSTR name, DWORD flags,
|
|||
if(idx >= xmlXPathNodeSetGetLength(This->result->nodesetval))
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
|
||||
*dispid = MSXML_DISPID_CUSTOM_MIN + idx;
|
||||
*dispid = DISPID_DOM_COLLECTION_BASE + idx;
|
||||
TRACE("ret %x\n", *dispid);
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -632,13 +633,16 @@ static HRESULT domselection_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD f
|
|||
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;
|
||||
|
||||
domselection_get_item(&This->IXMLDOMSelection_iface, id - MSXML_DISPID_CUSTOM_MIN, &disp);
|
||||
domselection_get_item(&This->IXMLDOMSelection_iface, id - DISPID_DOM_COLLECTION_BASE, &disp);
|
||||
V_DISPATCH(res) = (IDispatch*)disp;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1731,7 +1731,7 @@ SZ_EMAIL_DTD
|
|||
static const char xpath_simple_list[] =
|
||||
"<?xml version=\"1.0\"?>"
|
||||
"<root>"
|
||||
" <a/>"
|
||||
" <a attr1=\"1\" attr2=\"2\" />"
|
||||
" <b/>"
|
||||
" <c/>"
|
||||
" <d/>"
|
||||
|
@ -10628,9 +10628,15 @@ static void test_dispex(void)
|
|||
const DOMNodeType *type = dispex_types_test;
|
||||
IXMLDOMNodeList *node_list;
|
||||
IXMLDOMParseError *error;
|
||||
IXMLDOMNamedNodeMap *map;
|
||||
IXMLDOMDocument *doc;
|
||||
IXMLDOMElement *elem;
|
||||
IDispatchEx *dispex;
|
||||
IXMLDOMNode *node;
|
||||
VARIANT_BOOL b;
|
||||
IUnknown *unk;
|
||||
HRESULT hr;
|
||||
DISPID did;
|
||||
|
||||
doc = create_document(&IID_IXMLDOMDocument);
|
||||
|
||||
|
@ -10672,6 +10678,58 @@ static void test_dispex(void)
|
|||
IUnknown_Release(unk);
|
||||
IXMLDOMParseError_Release(error);
|
||||
|
||||
/* IXMLDOMNamedNodeMap */
|
||||
hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
|
||||
hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/a"), &node_list);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
IXMLDOMNodeList_Release(node_list);
|
||||
|
||||
hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
IXMLDOMNode_Release(node);
|
||||
hr = IXMLDOMElement_get_attributes(elem, &map);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk);
|
||||
test_domobj_dispex(unk);
|
||||
IUnknown_Release(unk);
|
||||
/* collection dispex test */
|
||||
hr = IXMLDOMNamedNodeMap_QueryInterface(map, &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);
|
||||
IDispatchEx_Release(dispex);
|
||||
|
||||
hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/b"), &node_list);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
IXMLDOMNodeList_Release(node_list);
|
||||
hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
IXMLDOMNode_Release(node);
|
||||
hr = IXMLDOMElement_get_attributes(elem, &map);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
/* collection dispex test, empty collection */
|
||||
hr = IXMLDOMNamedNodeMap_QueryInterface(map, &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);
|
||||
|
||||
IXMLDOMNamedNodeMap_Release(map);
|
||||
IXMLDOMElement_Release(elem);
|
||||
|
||||
IXMLDOMDocument_Release(doc);
|
||||
free_bstrs();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue