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;
|
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)
|
static inline BOOL is_dynamic_dispid(DISPID id)
|
||||||
{
|
{
|
||||||
return DISPID_DYNPROP_0 <= id && id <= DISPID_DYNPROP_MAX;
|
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);
|
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)
|
if(This->data->vtbl && This->data->vtbl->invoke) {
|
||||||
return This->data->vtbl->invoke(This->outer, id, lcid, wFlags, pdp, pvarRes, pei);
|
hres = This->data->vtbl->invoke(This->outer, id, lcid, wFlags, pdp, pvarRes, pei);
|
||||||
|
if (hres != DISP_E_UNKNOWNNAME) return hres;
|
||||||
|
}
|
||||||
|
|
||||||
if(wFlags == DISPATCH_CONSTRUCT) {
|
if(wFlags == DISPATCH_CONSTRUCT) {
|
||||||
FIXME("DISPATCH_CONSTRUCT not implemented\n");
|
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_data_t dispex_data_t;
|
||||||
typedef struct dispex_dynamic_data_t dispex_dynamic_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 {
|
typedef struct {
|
||||||
HRESULT (*get_dispid)(IUnknown*,BSTR,DWORD,DISPID*);
|
HRESULT (*get_dispid)(IUnknown*,BSTR,DWORD,DISPID*);
|
||||||
HRESULT (*invoke)(IUnknown*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*);
|
HRESULT (*invoke)(IUnknown*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*);
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
#include "ole2.h"
|
#include "ole2.h"
|
||||||
#include "msxml6.h"
|
#include "msxml6.h"
|
||||||
|
#include "msxml2did.h"
|
||||||
|
|
||||||
#include "msxml_private.h"
|
#include "msxml_private.h"
|
||||||
|
|
||||||
|
@ -45,6 +46,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
|
||||||
|
|
||||||
typedef struct _xmlnodemap
|
typedef struct _xmlnodemap
|
||||||
{
|
{
|
||||||
|
DispatchEx dispex;
|
||||||
IXMLDOMNamedNodeMap IXMLDOMNamedNodeMap_iface;
|
IXMLDOMNamedNodeMap IXMLDOMNamedNodeMap_iface;
|
||||||
ISupportErrorInfo ISupportErrorInfo_iface;
|
ISupportErrorInfo ISupportErrorInfo_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
@ -76,6 +78,10 @@ static HRESULT WINAPI xmlnodemap_QueryInterface(
|
||||||
{
|
{
|
||||||
*ppvObject = iface;
|
*ppvObject = iface;
|
||||||
}
|
}
|
||||||
|
else if (dispex_query_interface(&This->dispex, riid, ppvObject))
|
||||||
|
{
|
||||||
|
return *ppvObject ? S_OK : E_NOINTERFACE;
|
||||||
|
}
|
||||||
else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
|
else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
|
||||||
{
|
{
|
||||||
*ppvObject = &This->ISupportErrorInfo_iface;
|
*ppvObject = &This->ISupportErrorInfo_iface;
|
||||||
|
@ -111,6 +117,7 @@ static ULONG WINAPI xmlnodemap_Release(
|
||||||
if ( ref == 0 )
|
if ( ref == 0 )
|
||||||
{
|
{
|
||||||
xmldoc_release( This->node->doc );
|
xmldoc_release( This->node->doc );
|
||||||
|
release_dispex(&This->dispex);
|
||||||
heap_free( This );
|
heap_free( This );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,23 +523,92 @@ static const struct ISupportErrorInfoVtbl support_error_vtbl =
|
||||||
support_error_InterfaceSupportsErrorInfo
|
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 )
|
IXMLDOMNamedNodeMap *create_nodemap( const xmlNodePtr node )
|
||||||
{
|
{
|
||||||
xmlnodemap *nodemap;
|
xmlnodemap *This;
|
||||||
|
|
||||||
nodemap = heap_alloc( sizeof *nodemap );
|
This = heap_alloc( sizeof *This );
|
||||||
if ( !nodemap )
|
if ( !This )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
nodemap->IXMLDOMNamedNodeMap_iface.lpVtbl = &xmlnodemap_vtbl;
|
This->IXMLDOMNamedNodeMap_iface.lpVtbl = &xmlnodemap_vtbl;
|
||||||
nodemap->ISupportErrorInfo_iface.lpVtbl = &support_error_vtbl;
|
This->ISupportErrorInfo_iface.lpVtbl = &support_error_vtbl;
|
||||||
nodemap->node = node;
|
This->node = node;
|
||||||
nodemap->ref = 1;
|
This->ref = 1;
|
||||||
nodemap->iterator = 0;
|
This->iterator = 0;
|
||||||
|
|
||||||
|
init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMNamedNodeMap_iface, &xmlnodemap_dispex);
|
||||||
|
|
||||||
xmldoc_add_ref(node->doc);
|
xmldoc_add_ref(node->doc);
|
||||||
|
|
||||||
return &nodemap->IXMLDOMNamedNodeMap_iface;
|
return &This->IXMLDOMNamedNodeMap_iface;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
#include "ole2.h"
|
#include "ole2.h"
|
||||||
#include "msxml6.h"
|
#include "msxml6.h"
|
||||||
|
#include "msxml2did.h"
|
||||||
|
|
||||||
#include "msxml_private.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))
|
if(idx >= xmlXPathNodeSetGetLength(This->result->nodesetval))
|
||||||
return DISP_E_UNKNOWNNAME;
|
return DISP_E_UNKNOWNNAME;
|
||||||
|
|
||||||
*dispid = MSXML_DISPID_CUSTOM_MIN + idx;
|
*dispid = DISPID_DOM_COLLECTION_BASE + idx;
|
||||||
TRACE("ret %x\n", *dispid);
|
TRACE("ret %x\n", *dispid);
|
||||||
return S_OK;
|
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_VT(res) = VT_DISPATCH;
|
||||||
V_DISPATCH(res) = NULL;
|
V_DISPATCH(res) = NULL;
|
||||||
|
|
||||||
|
if (id < DISPID_DOM_COLLECTION_BASE || id > DISPID_DOM_COLLECTION_MAX)
|
||||||
|
return DISP_E_UNKNOWNNAME;
|
||||||
|
|
||||||
switch(flags)
|
switch(flags)
|
||||||
{
|
{
|
||||||
case INVOKE_PROPERTYGET:
|
case INVOKE_PROPERTYGET:
|
||||||
{
|
{
|
||||||
IXMLDOMNode *disp = NULL;
|
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;
|
V_DISPATCH(res) = (IDispatch*)disp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1731,7 +1731,7 @@ SZ_EMAIL_DTD
|
||||||
static const char xpath_simple_list[] =
|
static const char xpath_simple_list[] =
|
||||||
"<?xml version=\"1.0\"?>"
|
"<?xml version=\"1.0\"?>"
|
||||||
"<root>"
|
"<root>"
|
||||||
" <a/>"
|
" <a attr1=\"1\" attr2=\"2\" />"
|
||||||
" <b/>"
|
" <b/>"
|
||||||
" <c/>"
|
" <c/>"
|
||||||
" <d/>"
|
" <d/>"
|
||||||
|
@ -10628,9 +10628,15 @@ static void test_dispex(void)
|
||||||
const DOMNodeType *type = dispex_types_test;
|
const DOMNodeType *type = dispex_types_test;
|
||||||
IXMLDOMNodeList *node_list;
|
IXMLDOMNodeList *node_list;
|
||||||
IXMLDOMParseError *error;
|
IXMLDOMParseError *error;
|
||||||
|
IXMLDOMNamedNodeMap *map;
|
||||||
IXMLDOMDocument *doc;
|
IXMLDOMDocument *doc;
|
||||||
|
IXMLDOMElement *elem;
|
||||||
|
IDispatchEx *dispex;
|
||||||
|
IXMLDOMNode *node;
|
||||||
|
VARIANT_BOOL b;
|
||||||
IUnknown *unk;
|
IUnknown *unk;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
DISPID did;
|
||||||
|
|
||||||
doc = create_document(&IID_IXMLDOMDocument);
|
doc = create_document(&IID_IXMLDOMDocument);
|
||||||
|
|
||||||
|
@ -10672,6 +10678,58 @@ static void test_dispex(void)
|
||||||
IUnknown_Release(unk);
|
IUnknown_Release(unk);
|
||||||
IXMLDOMParseError_Release(error);
|
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);
|
IXMLDOMDocument_Release(doc);
|
||||||
free_bstrs();
|
free_bstrs();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue