First working version, hurrah!
git-svn-id: svn://10.0.0.236/trunk@36597 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -1,21 +1,41 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#define XML_UNICODE
|
||||
#include "xmlparse.h"
|
||||
|
||||
#ifdef XML_UNICODE
|
||||
#define X2OLE W2COLE
|
||||
#define X2T W2T
|
||||
#else
|
||||
#define X2OLE A2COLE
|
||||
#define X2T A2T
|
||||
#endif
|
||||
|
||||
|
||||
struct ParserState
|
||||
{
|
||||
CComQIPtr<IXMLDocument, &IID_IXMLDocument> spXMLDocument;
|
||||
CComQIPtr<IXMLElement, &IID_IXMLElement> spXMLRoot;
|
||||
CComQIPtr<IXMLElement, &IID_IXMLElement> spXMLParent;
|
||||
};
|
||||
|
||||
ParserState cParserState;
|
||||
static ParserState cParserState;
|
||||
|
||||
|
||||
// XML data handlers
|
||||
static void OnStartElement(void *userData, const XML_Char *name, const XML_Char **atts);
|
||||
static void OnEndElement(void *userData, const XML_Char *name);
|
||||
static void OnCharacterData(void *userData, const XML_Char *s, int len);
|
||||
static void OnDefault(void *userData, const XML_Char *s, int len);
|
||||
|
||||
|
||||
HRESULT ParseExpat(const char *pBuffer, unsigned long cbBufSize, IXMLDocument *pDocument)
|
||||
struct ParseData
|
||||
{
|
||||
CComQIPtr<IXMLDocument, &IID_IXMLDocument> spDocument;
|
||||
CComQIPtr<IXMLElement, &IID_IXMLElement> spRoot;
|
||||
};
|
||||
|
||||
HRESULT ParseExpat(const char *pBuffer, unsigned long cbBufSize, IXMLDocument *pDocument, IXMLElement **ppElement)
|
||||
{
|
||||
if (pDocument == NULL)
|
||||
{
|
||||
@@ -26,16 +46,20 @@ HRESULT ParseExpat(const char *pBuffer, unsigned long cbBufSize, IXMLDocument *p
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
cParserState.spXMLDocument = pDocument;
|
||||
pDocument->get_root(&cParserState.spXMLParent);
|
||||
|
||||
// Initialise the XML parser
|
||||
XML_SetUserData(parser, &cParserState);
|
||||
|
||||
// Initialise the data handlers
|
||||
XML_SetElementHandler(parser, OnStartElement, OnEndElement);
|
||||
XML_SetCharacterDataHandler(parser, OnCharacterData);
|
||||
XML_SetDefaultHandler(parser, OnDefault);
|
||||
|
||||
// Parse the data
|
||||
if (!XML_Parse(parser, pBuffer, cbBufSize, 1))
|
||||
{
|
||||
/* TODO Print error message
|
||||
/* TODO Create error code
|
||||
fprintf(stderr,
|
||||
"%s at line %d\n",
|
||||
XML_ErrorString(XML_GetErrorCode(parser)),
|
||||
@@ -46,6 +70,8 @@ HRESULT ParseExpat(const char *pBuffer, unsigned long cbBufSize, IXMLDocument *p
|
||||
|
||||
// Cleanup
|
||||
XML_ParserFree(parser);
|
||||
|
||||
cParserState.spXMLRoot->QueryInterface(IID_IXMLElement, (void **) ppElement);
|
||||
cParserState.spXMLDocument.Release();
|
||||
cParserState.spXMLParent.Release();
|
||||
|
||||
@@ -53,6 +79,9 @@ HRESULT ParseExpat(const char *pBuffer, unsigned long cbBufSize, IXMLDocument *p
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void OnStartElement(void *userData, const XML_Char *name, const XML_Char **atts)
|
||||
{
|
||||
ParserState *pState = (ParserState *) userData;
|
||||
@@ -65,7 +94,7 @@ void OnStartElement(void *userData, const XML_Char *name, const XML_Char **atts)
|
||||
// Create a new element
|
||||
pState->spXMLDocument->createElement(
|
||||
CComVariant(XMLELEMTYPE_ELEMENT),
|
||||
CComVariant(A2OLE(name)),
|
||||
CComVariant(X2OLE(name)),
|
||||
&spXMLElement);
|
||||
|
||||
if (spXMLElement)
|
||||
@@ -75,17 +104,40 @@ void OnStartElement(void *userData, const XML_Char *name, const XML_Char **atts)
|
||||
{
|
||||
const XML_Char *pszName = atts[i];
|
||||
const XML_Char *pszValue = atts[i+1];
|
||||
spXMLElement->setAttribute(A2OLE(pszName), CComVariant(A2OLE(pszValue)));
|
||||
spXMLElement->setAttribute((BSTR) X2OLE(pszName), CComVariant(X2OLE(pszValue)));
|
||||
}
|
||||
|
||||
// Add the element to the end of the list
|
||||
pState->spXMLParent->addChild(spXMLElement, -1, -1);
|
||||
if (pState->spXMLRoot == NULL)
|
||||
{
|
||||
pState->spXMLRoot = spXMLElement;
|
||||
}
|
||||
if (pState->spXMLParent)
|
||||
{
|
||||
// Add the element to the end of the list
|
||||
pState->spXMLParent->addChild(spXMLElement, -1, -1);
|
||||
}
|
||||
pState->spXMLParent = spXMLElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OnEndElement(void *userData, const XML_Char *name)
|
||||
{
|
||||
ParserState *pState = (ParserState *) userData;
|
||||
if (pState)
|
||||
{
|
||||
CComQIPtr<IXMLElement, &IID_IXMLElement> spNewParent;
|
||||
if (pState->spXMLParent)
|
||||
{
|
||||
pState->spXMLParent->get_parent(&spNewParent);
|
||||
pState->spXMLParent = spNewParent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OnDefault(void *userData, const XML_Char *s, int len)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -21,11 +21,19 @@
|
||||
extern CComModule _Module;
|
||||
#include <atlcom.h>
|
||||
|
||||
#include "activexml.h"
|
||||
//#include "activexml.h"
|
||||
|
||||
extern const CLSID CLSID_MozXMLElement;
|
||||
extern const CLSID CLSID_MozXMLDocument;
|
||||
extern const CLSID CLSID_MozXMLElementCollection;
|
||||
extern const IID LIBID_MozActiveXMLLib;
|
||||
|
||||
#include "XMLElement.h"
|
||||
#include "XMLElementCollection.h"
|
||||
#include "XMLDocument.h"
|
||||
|
||||
extern HRESULT ParseExpat(const char *pBuffer, unsigned long cbBufSize, IXMLDocument *pDocument, IXMLElement **ppElement);
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// XMLDocument.cpp : Implementation of CXMLDocument
|
||||
#include "stdafx.h"
|
||||
#include "Activexml.h"
|
||||
//#include "Activexml.h"
|
||||
#include "XMLDocument.h"
|
||||
|
||||
|
||||
CXMLDocument::CXMLDocument()
|
||||
{
|
||||
ATLTRACE(_T("CXMLDocument::CXMLDocument()\n"));
|
||||
m_nReadyState = READYSTATE_COMPLETE;
|
||||
}
|
||||
|
||||
@@ -40,7 +41,34 @@ STDMETHODIMP CXMLDocument::InterfaceSupportsErrorInfo(REFIID riid)
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CXMLDocument::Load(/* [in] */ LPSTREAM pStm)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
if (pStm == NULL)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Load the XML from the stream
|
||||
STATSTG statstg;
|
||||
pStm->Stat(&statstg, STATFLAG_NONAME);
|
||||
|
||||
ULONG cbBufSize = statstg.cbSize.LowPart;
|
||||
|
||||
char *pBuffer = new char[cbBufSize];
|
||||
if (pBuffer == NULL)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
memset(pBuffer, 0, cbBufSize);
|
||||
pStm->Read(pBuffer, cbBufSize, NULL);
|
||||
|
||||
m_spRoot.Release();
|
||||
ParseExpat(pBuffer, cbBufSize, (IXMLDocument *) this, &m_spRoot);
|
||||
|
||||
delete []pBuffer;
|
||||
|
||||
m_nReadyState = READYSTATE_LOADED;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +86,7 @@ HRESULT STDMETHODCALLTYPE CXMLDocument::GetSizeMax(/* [out] */ ULARGE_INTEGER __
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CXMLDocument::InitNew(void)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -90,8 +118,16 @@ HRESULT STDMETHODCALLTYPE CXMLDocument::Load(/* [in] */ BOOL fFullyAvailable, /*
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// pimkName->BindToStorage(pibc, NULL, iid, pObj)
|
||||
return E_NOTIMPL;
|
||||
m_nReadyState = READYSTATE_LOADING;
|
||||
|
||||
// Bind to the stream specified by the moniker
|
||||
CComQIPtr<IStream, &IID_IStream> spIStream;
|
||||
if (FAILED(pimkName->BindToStorage(pibc, NULL, IID_IStream, (void **) &spIStream)))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return Load(spIStream);
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +163,16 @@ HRESULT STDMETHODCALLTYPE CXMLDocument::GetErrorInfo(XML_ERROR __RPC_FAR *pError
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CXMLDocument::get_root(/* [out][retval] */ IXMLElement __RPC_FAR *__RPC_FAR *p)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
if (p == NULL)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
*p = NULL;
|
||||
if (m_spRoot)
|
||||
{
|
||||
m_spRoot->QueryInterface(IID_IXMLElement, (void **) p);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -151,13 +196,46 @@ HRESULT STDMETHODCALLTYPE CXMLDocument::get_fileUpdatedDate(/* [out][retval] */
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CXMLDocument::get_URL(/* [out][retval] */ BSTR __RPC_FAR *p)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
if (p == NULL)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
USES_CONVERSION;
|
||||
*p = SysAllocString(A2OLE(m_szURL.c_str()));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CXMLDocument::put_URL(/* [in] */ BSTR p)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
if (p == NULL)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
USES_CONVERSION;
|
||||
m_szURL = OLE2A(p);
|
||||
|
||||
// Destroy old document
|
||||
CComQIPtr<IMoniker, &IID_IMoniker> spIMoniker;
|
||||
if (FAILED(CreateURLMoniker(NULL, A2W(m_szURL.c_str()), &spIMoniker)))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
CComQIPtr<IBindCtx, &IID_IBindCtx> spIBindCtx;
|
||||
if (FAILED(CreateBindCtx(0, &spIBindCtx)))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (FAILED(Load(TRUE, spIMoniker, spIBindCtx, 0)))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -225,8 +303,26 @@ HRESULT STDMETHODCALLTYPE CXMLDocument::createElement(/* [in] */ VARIANT vType,
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
IXMLElement *pElement = NULL;
|
||||
if (FAILED(pInstance->QueryInterface(IID_IXMLElement, (void **) &pElement)))
|
||||
{
|
||||
pInstance->Release();
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
// Set the element type
|
||||
long nType = vType.intVal;
|
||||
pInstance->PutType(nType);
|
||||
|
||||
// Set the tag name
|
||||
if (var1.vt == VT_BSTR)
|
||||
{
|
||||
pInstance->put_tagName(var1.bstrVal);
|
||||
}
|
||||
|
||||
return pInstance->QueryInterface(IID_IXMLElement, (void **) ppElem);
|
||||
*ppElem = pElement;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
CXMLDocument();
|
||||
virtual ~CXMLDocument();
|
||||
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_XMLDOCUMENT)
|
||||
|
||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
@@ -28,20 +29,22 @@ BEGIN_COM_MAP(CXMLDocument)
|
||||
COM_INTERFACE_ENTRY(IDispatch)
|
||||
COM_INTERFACE_ENTRY(IPersistMoniker)
|
||||
COM_INTERFACE_ENTRY(IPersistStreamInit)
|
||||
COM_INTERFACE_ENTRY(ISupportErrorInfo)
|
||||
// COM_INTERFACE_ENTRY(ISupportErrorInfo)
|
||||
END_COM_MAP()
|
||||
|
||||
LONG m_nReadyState;
|
||||
std::string m_szURL;
|
||||
CComQIPtr<IXMLElement, &IID_IXMLElement> m_spRoot;
|
||||
|
||||
// ISupportsErrorInfo
|
||||
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
|
||||
|
||||
// IPersistStreamInit
|
||||
//virtual HRESULT STDMETHODCALLTYPE IsDirty(void);
|
||||
virtual HRESULT STDMETHODCALLTYPE Load(/* [in] */ LPSTREAM pStm);
|
||||
virtual HRESULT STDMETHODCALLTYPE Save(/* [in] */ LPSTREAM pStm, /* [in] */ BOOL fClearDirty);
|
||||
virtual HRESULT STDMETHODCALLTYPE GetSizeMax(/* [out] */ ULARGE_INTEGER __RPC_FAR *pCbSize);
|
||||
virtual HRESULT STDMETHODCALLTYPE InitNew(void);
|
||||
HRESULT STDMETHODCALLTYPE Load(/* [in] */ LPSTREAM pStm);
|
||||
HRESULT STDMETHODCALLTYPE Save(/* [in] */ LPSTREAM pStm, /* [in] */ BOOL fClearDirty);
|
||||
HRESULT STDMETHODCALLTYPE GetSizeMax(/* [out] */ ULARGE_INTEGER __RPC_FAR *pCbSize);
|
||||
HRESULT STDMETHODCALLTYPE InitNew(void);
|
||||
|
||||
// IPersistMoniker
|
||||
HRESULT STDMETHODCALLTYPE GetClassID(/* [out] */ CLSID __RPC_FAR *pClassID);
|
||||
@@ -51,8 +54,6 @@ END_COM_MAP()
|
||||
HRESULT STDMETHODCALLTYPE SaveCompleted(/* [in] */ IMoniker __RPC_FAR *pimkName, /* [in] */ LPBC pibc);
|
||||
HRESULT STDMETHODCALLTYPE GetCurMoniker(/* [out] */ IMoniker __RPC_FAR *__RPC_FAR *ppimkName);
|
||||
|
||||
|
||||
|
||||
// IXMLError
|
||||
HRESULT STDMETHODCALLTYPE GetErrorInfo(XML_ERROR __RPC_FAR *pErrorReturn);
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
HKCR
|
||||
{
|
||||
Mozilla.XMLDocument.1 = s 'XMLDocument Class'
|
||||
Mozilla.XMLDocument.1 = s 'Mozilla XMLDocument Class'
|
||||
{
|
||||
CLSID = s '{45E5B41D-2805-11D3-9425-000000000000}'
|
||||
}
|
||||
Mozilla.XMLDocument = s 'XMLDocument Class'
|
||||
Mozilla.XMLDocument = s 'Mozilla XMLDocument Class'
|
||||
{
|
||||
CLSID = s '{45E5B41D-2805-11D3-9425-000000000000}'
|
||||
CurVer = s 'Mozilla.XMLDocument.1'
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {45E5B41D-2805-11D3-9425-000000000000} = s 'XMLDocument Class'
|
||||
ForceRemove {45E5B41D-2805-11D3-9425-000000000000} = s 'Mozilla XMLDocument Class'
|
||||
{
|
||||
ProgID = s 'Mozilla.XMLDocument.1'
|
||||
VersionIndependentProgID = s 'Mozilla.XMLDocument'
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// XMLElement.cpp : Implementation of CXMLElement
|
||||
#include "stdafx.h"
|
||||
#include "Activexml.h"
|
||||
//#include "Activexml.h"
|
||||
#include "XMLElement.h"
|
||||
|
||||
|
||||
CXMLElement::CXMLElement()
|
||||
{
|
||||
m_nType = 0;
|
||||
m_pParent = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +23,14 @@ HRESULT CXMLElement::SetParent(IXMLElement *pParent)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CXMLElement::PutType(long nType)
|
||||
{
|
||||
m_nType = nType;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CXMLElement::ReleaseAll()
|
||||
{
|
||||
// Release all children
|
||||
@@ -33,6 +42,8 @@ HRESULT CXMLElement::ReleaseAll()
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CXMLElement
|
||||
|
||||
|
||||
// Return the element's tag name
|
||||
HRESULT STDMETHODCALLTYPE CXMLElement::get_tagName(/* [out][retval] */ BSTR __RPC_FAR *p)
|
||||
{
|
||||
if (p == NULL)
|
||||
@@ -45,6 +56,7 @@ HRESULT STDMETHODCALLTYPE CXMLElement::get_tagName(/* [out][retval] */ BSTR __RP
|
||||
}
|
||||
|
||||
|
||||
// Store the tag name
|
||||
HRESULT STDMETHODCALLTYPE CXMLElement::put_tagName(/* [in] */ BSTR p)
|
||||
{
|
||||
if (p == NULL)
|
||||
@@ -57,6 +69,7 @@ HRESULT STDMETHODCALLTYPE CXMLElement::put_tagName(/* [in] */ BSTR p)
|
||||
}
|
||||
|
||||
|
||||
// Returns the parent element
|
||||
HRESULT STDMETHODCALLTYPE CXMLElement::get_parent(/* [out][retval] */ IXMLElement __RPC_FAR *__RPC_FAR *ppParent)
|
||||
{
|
||||
if (ppParent == NULL)
|
||||
@@ -74,6 +87,7 @@ HRESULT STDMETHODCALLTYPE CXMLElement::get_parent(/* [out][retval] */ IXMLElemen
|
||||
}
|
||||
|
||||
|
||||
// Set the specified attribute value
|
||||
HRESULT STDMETHODCALLTYPE CXMLElement::setAttribute(/* [in] */ BSTR strPropertyName, /* [in] */ VARIANT PropertyValue)
|
||||
{
|
||||
if (strPropertyName == NULL || PropertyValue.vt != VT_BSTR)
|
||||
@@ -90,6 +104,7 @@ HRESULT STDMETHODCALLTYPE CXMLElement::setAttribute(/* [in] */ BSTR strPropertyN
|
||||
}
|
||||
|
||||
|
||||
// Return the requested attribute
|
||||
HRESULT STDMETHODCALLTYPE CXMLElement::getAttribute(/* [in] */ BSTR strPropertyName, /* [out][retval] */ VARIANT __RPC_FAR *PropertyValue)
|
||||
{
|
||||
if (strPropertyName == NULL || PropertyValue == NULL)
|
||||
@@ -111,6 +126,7 @@ HRESULT STDMETHODCALLTYPE CXMLElement::getAttribute(/* [in] */ BSTR strPropertyN
|
||||
}
|
||||
|
||||
|
||||
// Find and remove the specified attribute
|
||||
HRESULT STDMETHODCALLTYPE CXMLElement::removeAttribute(/* [in] */ BSTR strPropertyName)
|
||||
{
|
||||
if (strPropertyName == NULL)
|
||||
@@ -132,10 +148,25 @@ HRESULT STDMETHODCALLTYPE CXMLElement::removeAttribute(/* [in] */ BSTR strProper
|
||||
}
|
||||
|
||||
|
||||
// Return the child collection for this element
|
||||
HRESULT STDMETHODCALLTYPE CXMLElement::get_children(/* [out][retval] */ IXMLElementCollection __RPC_FAR *__RPC_FAR *pp)
|
||||
{
|
||||
// TODO
|
||||
return E_NOTIMPL;
|
||||
CXMLElementCollectionInstance *pCollection = NULL;
|
||||
CXMLElementCollectionInstance::CreateInstance(&pCollection);
|
||||
if (pCollection == NULL)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
// Add children to the collection
|
||||
for (ElementList::iterator i = m_cChildren.begin(); i != m_cChildren.end(); i++)
|
||||
{
|
||||
pCollection->Add(*i);
|
||||
}
|
||||
|
||||
pCollection->QueryInterface(IID_IXMLElementCollection, (void **) pp);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,8 +200,21 @@ HRESULT STDMETHODCALLTYPE CXMLElement::addChild(/* [in] */ IXMLElement __RPC_FAR
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
//TODO
|
||||
return E_NOTIMPL;
|
||||
// Set the child's parent to be this element
|
||||
((CXMLElement *) pChildElem)->SetParent(this);
|
||||
|
||||
if (lIndex < 0 || lIndex >= m_cChildren.size())
|
||||
{
|
||||
// Append to end
|
||||
m_cChildren.push_back(pChildElem);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO m_cChildren.insert(&m_cChildren[lIndex]);
|
||||
m_cChildren.push_back(pChildElem);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <map>
|
||||
|
||||
typedef std::map<std::string, std::string> StringMap;
|
||||
typedef std::vector< CComQIPtr<IXMLElement, &IID_IXMLElement> > ElementList;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CXMLElement
|
||||
@@ -21,7 +22,7 @@ class ATL_NO_VTABLE CXMLElement :
|
||||
// Pointer to parent
|
||||
IXMLElement *m_pParent;
|
||||
// List of children
|
||||
std::vector< CComQIPtr<IXMLElement, &IID_IXMLElement> > m_cChildren;
|
||||
ElementList m_cChildren;
|
||||
// Tag name
|
||||
std::string m_szTagName;
|
||||
// Text
|
||||
@@ -36,6 +37,7 @@ public:
|
||||
virtual ~CXMLElement();
|
||||
|
||||
virtual HRESULT SetParent(IXMLElement *pParent);
|
||||
virtual HRESULT PutType(long nType);
|
||||
virtual HRESULT ReleaseAll();
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_XMLELEMENT)
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
HKCR
|
||||
{
|
||||
Mozilla..XMLElement.1 = s 'XMLElement Class'
|
||||
Mozilla.XMLElement.1 = s 'MozillaXMLElement Class'
|
||||
{
|
||||
CLSID = s '{45E5B420-2805-11D3-9425-000000000000}'
|
||||
}
|
||||
Mozilla..XMLElement = s 'XMLElement Class'
|
||||
Mozilla..MLElement = s 'MozillaXMLElement Class'
|
||||
{
|
||||
CLSID = s '{45E5B420-2805-11D3-9425-000000000000}'
|
||||
CurVer = s 'Mozilla..XMLElement.1'
|
||||
CurVer = s 'Mozilla.XMLElement.1'
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {45E5B420-2805-11D3-9425-000000000000} = s 'XMLElement Class'
|
||||
ForceRemove {45E5B420-2805-11D3-9425-000000000000} = s 'Mozilla XMLElement Class'
|
||||
{
|
||||
ProgID = s 'Mozilla..XMLElement.1'
|
||||
VersionIndependentProgID = s 'Mozilla..XMLElement'
|
||||
ProgID = s 'Mozilla.XMLElement.1'
|
||||
VersionIndependentProgID = s 'Mozilla.XMLElement'
|
||||
ForceRemove 'Programmable'
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
|
||||
@@ -1,32 +1,164 @@
|
||||
// XMLElementCollection.cpp : Implementation of CXMLElementCollection
|
||||
#include "stdafx.h"
|
||||
#include "Activexml.h"
|
||||
//#include "Activexml.h"
|
||||
#include "XMLElementCollection.h"
|
||||
|
||||
CXMLElementCollection::CXMLElementCollection()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CXMLElementCollection::~CXMLElementCollection()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HRESULT CXMLElementCollection::Add(IXMLElement *pElement)
|
||||
{
|
||||
if (pElement == NULL)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
m_cElements.push_back( CComQIPtr<IXMLElement, &IID_IXMLElement>(pElement));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CXMLElementCollection
|
||||
|
||||
HRESULT STDMETHODCALLTYPE put_length(/* [in] */ long v)
|
||||
HRESULT STDMETHODCALLTYPE CXMLElementCollection::put_length(/* [in] */ long v)
|
||||
{
|
||||
// Why does MS define a method that has no purpose?
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CXMLElementCollection::get_length(/* [out][retval] */ long __RPC_FAR *p)
|
||||
{
|
||||
if (p == NULL)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
*p = m_cElements.size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CXMLElementCollection::get__newEnum(/* [out][retval] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE get_length(/* [out][retval] */ long __RPC_FAR *p)
|
||||
// Perhaps the most overly complicated method ever...
|
||||
HRESULT STDMETHODCALLTYPE CXMLElementCollection::item(/* [in][optional] */ VARIANT var1, /* [in][optional] */ VARIANT var2, /* [out][retval] */ IDispatch __RPC_FAR *__RPC_FAR *ppDisp)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
if (ppDisp == NULL)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
*ppDisp;
|
||||
|
||||
CComVariant vIndex;
|
||||
|
||||
// If var1 is a number, the caller wants the element at the specified index
|
||||
|
||||
if (vIndex.ChangeType(VT_I4, &var1) == S_OK)
|
||||
{
|
||||
long nIndex = vIndex.intVal;
|
||||
if (nIndex < 0 || nIndex >= m_cElements.size())
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
// Get the element at the specified index
|
||||
m_cElements[nIndex]->QueryInterface(IID_IDispatch, (void **) ppDisp);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// If var1 is a string, the caller wants a collection of all elements with
|
||||
// the matching tagname, unless var2 contains an index or if there is only
|
||||
// one in which case just the element is returned.
|
||||
|
||||
CComVariant vName;
|
||||
if (FAILED(vName.ChangeType(VT_BSTR, &var1)))
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Compile a list of elements matching the name
|
||||
ElementList cElements;
|
||||
ElementList::iterator i;
|
||||
|
||||
for (i = m_cElements.begin(); i != m_cElements.end(); i++)
|
||||
{
|
||||
CComQIPtr<IXMLElement, &IID_IXMLElement> spElement;
|
||||
BSTR bstrTagName = NULL;
|
||||
(*i)->get_tagName(&bstrTagName);
|
||||
if (bstrTagName)
|
||||
{
|
||||
if (wcscmp(bstrTagName, vName.bstrVal) == 0)
|
||||
{
|
||||
cElements.push_back(*i);
|
||||
}
|
||||
SysFreeString(bstrTagName);
|
||||
}
|
||||
}
|
||||
|
||||
// Are there any matching elements?
|
||||
if (cElements.empty())
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Does var2 contain an index?
|
||||
if (var2.vt == VT_I4)
|
||||
{
|
||||
long nIndex = var2.vt;
|
||||
if (nIndex < 0 || nIndex >= cElements.size())
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Get the element at the specified index
|
||||
cElements[nIndex]->QueryInterface(IID_IDispatch, (void **) ppDisp);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Is there more than one element?
|
||||
if (cElements.size() > 1)
|
||||
{
|
||||
// Create another collection
|
||||
CXMLElementCollectionInstance *pCollection = NULL;
|
||||
CXMLElementCollectionInstance::CreateInstance(&pCollection);
|
||||
if (pCollection == NULL)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (FAILED(pCollection->QueryInterface(IID_IDispatch, (void **) ppDisp)))
|
||||
{
|
||||
pCollection->Release();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Add elements to the collection
|
||||
for (i = cElements.begin(); i != cElements.end(); i++)
|
||||
{
|
||||
pCollection->Add(*i);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Return the pointer to the element
|
||||
if (FAILED(cElements[0]->QueryInterface(IID_IDispatch, (void **) ppDisp)))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE get__newEnum(/* [out][retval] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE item(/* [in][optional] */ VARIANT var1, /* [in][optional] */ VARIANT var2, /* [out][retval] */ IDispatch __RPC_FAR *__RPC_FAR *ppDisp)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,13 +10,14 @@
|
||||
class ATL_NO_VTABLE CXMLElementCollection :
|
||||
public CComObjectRootEx<CComSingleThreadModel>,
|
||||
public CComCoClass<CXMLElementCollection, &CLSID_MozXMLElementCollection>,
|
||||
public IDispatchImpl<IXMLElementCollection, &IID_IXMLElementCollection, &LIBID_MozActiveXMLLib>,
|
||||
public IPersistMoniker
|
||||
public IDispatchImpl<IXMLElementCollection, &IID_IXMLElementCollection, &LIBID_MozActiveXMLLib>
|
||||
{
|
||||
// List of elements
|
||||
ElementList m_cElements;
|
||||
|
||||
public:
|
||||
CXMLElementCollection()
|
||||
{
|
||||
}
|
||||
CXMLElementCollection();
|
||||
virtual ~CXMLElementCollection();
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_XMLELEMENTCOLLECTION)
|
||||
|
||||
@@ -34,6 +35,7 @@ END_COM_MAP()
|
||||
virtual HRESULT STDMETHODCALLTYPE item(/* [in][optional] */ VARIANT var1, /* [in][optional] */ VARIANT var2, /* [out][retval] */ IDispatch __RPC_FAR *__RPC_FAR *ppDisp);
|
||||
|
||||
public:
|
||||
HRESULT Add(IXMLElement *pElement);
|
||||
};
|
||||
|
||||
typedef CComObject<CXMLElementCollection> CXMLElementCollectionInstance;
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
HKCR
|
||||
{
|
||||
Mozilla.XMLElementCollection.1 = s 'XMLElementCollection Class'
|
||||
Mozilla.XMLElementCollection.1 = s 'Mozilla XMLElementCollection Class'
|
||||
{
|
||||
CLSID = s '{45E5B422-2805-11D3-9425-000000000000}'
|
||||
}
|
||||
Mozilla.XMLElementCollection = s 'XMLElementCollection Class'
|
||||
Mozilla.XMLElementCollection = s 'Mozilla XMLElementCollection Class'
|
||||
{
|
||||
CLSID = s '{45E5B422-2805-11D3-9425-000000000000}'
|
||||
CurVer = s 'Mozilla.XMLElementCollection.1'
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {45E5B422-2805-11D3-9425-000000000000} = s 'XMLElementCollection Class'
|
||||
ForceRemove {45E5B422-2805-11D3-9425-000000000000} = s 'Mozilla XMLElementCollection Class'
|
||||
{
|
||||
ProgID = s 'Mozilla.XMLElementCollection.1'
|
||||
VersionIndependentProgID = s 'Mozilla.XMLElementCollection'
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "resource.h"
|
||||
#include <initguid.h>
|
||||
#include "activexml.h"
|
||||
//#include <initguid.h>
|
||||
//#include "activexml.h"
|
||||
|
||||
#include "activexml_i.c"
|
||||
#include "XMLDocument.h"
|
||||
@@ -19,9 +19,9 @@
|
||||
CComModule _Module;
|
||||
|
||||
BEGIN_OBJECT_MAP(ObjectMap)
|
||||
OBJECT_ENTRY(CLSID_XMLDocument, CXMLDocument)
|
||||
//OBJECT_ENTRY(CLSID_XMLElement, CXMLElement)
|
||||
//OBJECT_ENTRY(CLSID_XMLElementCollection, CXMLElementCollection)
|
||||
OBJECT_ENTRY(CLSID_MozXMLDocument, CXMLDocument)
|
||||
//OBJECT_ENTRY(CLSID_MozXMLElement, CXMLElement)
|
||||
//OBJECT_ENTRY(CLSID_MozXMLElementCollection, CXMLElementCollection)
|
||||
END_OBJECT_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -47,7 +47,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "M:\moz\mozilla\dist\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "M:\moz\mozilla\dist\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -55,7 +55,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib M:\moz\mozilla\dist\WIN32_D.OBJ\lib\expat.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib Urlmon.lib M:\moz\mozilla\dist\WIN32_D.OBJ\lib\expat.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# Begin Custom Build - Performing registration
|
||||
OutDir=.\Debug
|
||||
TargetPath=.\Debug\activexml.dll
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
// This file will be processed by the MIDL tool to
|
||||
// produce the type library (activexml.tlb) and marshalling code.
|
||||
|
||||
import "oaidl.idl";
|
||||
import "ocidl.idl";
|
||||
import "msxml.idl";
|
||||
#include "msxmldid.h"
|
||||
|
||||
//import "oaidl.idl";
|
||||
//import "ocidl.idl";
|
||||
|
||||
[
|
||||
uuid(45E5B410-2805-11D3-9425-000000000000),
|
||||
@@ -18,6 +19,99 @@ library MozActiveXMLLib
|
||||
importlib("stdole32.tlb");
|
||||
importlib("stdole2.tlb");
|
||||
|
||||
typedef enum mozxmlelemTYPE {
|
||||
XMLELEMTYPE_ELEMENT,
|
||||
XMLELEMTYPE_TEXT,
|
||||
XMLELEMTYPE_COMMENT,
|
||||
XMLELEMTYPE_DOCUMENT,
|
||||
XMLELEMTYPE_DTD,
|
||||
XMLELEMTYPE_PI,
|
||||
XMLELEMTYPE_OTHER
|
||||
} XMLELEM_TYPE;
|
||||
|
||||
interface IXMLElement;
|
||||
|
||||
[
|
||||
object,
|
||||
local,
|
||||
uuid(65725580-9B5D-11d0-9BFE-00C04FC99C8E) // IID_IXMLElementCollection
|
||||
]
|
||||
interface IXMLElementCollection : IDispatch
|
||||
{
|
||||
[propput, id(DISPID_XMLELEMENTCOLLECTION_LENGTH)] HRESULT length([in] long v);
|
||||
[propget, id(DISPID_XMLELEMENTCOLLECTION_LENGTH)] HRESULT length([retval, out] long * p);
|
||||
[propget, restricted, hidden, id(DISPID_XMLELEMENTCOLLECTION_NEWENUM)] HRESULT _newEnum([retval, out] IUnknown ** ppUnk);
|
||||
[id(DISPID_XMLELEMENTCOLLECTION_ITEM)] HRESULT item([optional, in] VARIANT var1,[optional, in] VARIANT var2,[retval, out] IDispatch ** ppDisp);
|
||||
};
|
||||
|
||||
[
|
||||
object,
|
||||
local,
|
||||
uuid(F52E2B61-18A1-11d1-B105-00805F49916B) // IID_IXMLDocument
|
||||
]
|
||||
interface IXMLDocument : IDispatch
|
||||
{
|
||||
[propget, id(DISPID_XMLDOCUMENT_ROOT)] HRESULT root ([retval, out] IXMLElement * * p);
|
||||
[propget, id(DISPID_XMLDOCUMENT_FILESIZE)] HRESULT fileSize([retval, out] BSTR * p);
|
||||
[propget, id(DISPID_XMLDOCUMENT_FILEMODIFIEDDATE)] HRESULT fileModifiedDate([retval, out] BSTR * p);
|
||||
[propget, id(DISPID_XMLDOCUMENT_FILEUPDATEDDATE)] HRESULT fileUpdatedDate([retval, out] BSTR * p);
|
||||
[propget, id(DISPID_XMLDOCUMENT_URL)] HRESULT URL([retval, out] BSTR * p);
|
||||
[propput, id(DISPID_XMLDOCUMENT_URL)] HRESULT URL([in] BSTR p);
|
||||
[propget, id(DISPID_XMLDOCUMENT_MIMETYPE)] HRESULT mimeType([retval, out] BSTR * p);
|
||||
[propget, id(DISPID_XMLDOCUMENT_READYSTATE)] HRESULT readyState([retval, out]long *pl);
|
||||
[propget, id(DISPID_XMLDOCUMENT_CHARSET)] HRESULT charset([retval, out]BSTR *p);
|
||||
[propput, id(DISPID_XMLDOCUMENT_CHARSET)] HRESULT charset([in]BSTR p);
|
||||
[propget, id(DISPID_XMLDOCUMENT_VERSION)] HRESULT version([retval, out]BSTR *p);
|
||||
[propget, id(DISPID_XMLDOCUMENT_DOCTYPE)] HRESULT doctype([retval, out]BSTR *p);
|
||||
[propget, id(DISPID_XMLDOCUMENT_DTDURL)] HRESULT dtdURL([retval, out]BSTR *p);
|
||||
[id(DISPID_XMLDOCUMENT_CREATEELEMENT)] HRESULT createElement([in] VARIANT vType, [optional, in] VARIANT var1, [retval, out] IXMLElement * * ppElem);
|
||||
};
|
||||
|
||||
|
||||
[
|
||||
object,
|
||||
local,
|
||||
uuid(3F7F31AC-E15F-11d0-9C25-00C04FC99C8E) // IID_IXMLElement
|
||||
]
|
||||
interface IXMLElement : IDispatch
|
||||
{
|
||||
[propget, id(DISPID_XMLELEMENT_TAGNAME)] HRESULT tagName([retval, out] BSTR * p);
|
||||
[propput, id(DISPID_XMLELEMENT_TAGNAME)] HRESULT tagName([in] BSTR p);
|
||||
[propget, id(DISPID_XMLELEMENT_PARENT)] HRESULT parent([retval, out]IXMLElement **ppParent);
|
||||
[id(DISPID_XMLELEMENT_SETATTRIBUTE)] HRESULT setAttribute([in] BSTR strPropertyName,[in] VARIANT PropertyValue);
|
||||
[id(DISPID_XMLELEMENT_GETATTRIBUTE)] HRESULT getAttribute([in] BSTR strPropertyName,[retval, out] VARIANT* PropertyValue);
|
||||
[id(DISPID_XMLELEMENT_REMOVEATTRIBUTE)] HRESULT removeAttribute([in] BSTR strPropertyName);
|
||||
[propget, id(DISPID_XMLELEMENT_CHILDREN)] HRESULT children([retval, out] IXMLElementCollection * * pp);
|
||||
[propget, id(DISPID_XMLELEMENT_TYPE)] HRESULT type([retval, out] long *plType);
|
||||
[propget, id(DISPID_XMLELEMENT_TEXT)] HRESULT text([retval, out] BSTR *p);
|
||||
[propput, id(DISPID_XMLELEMENT_TEXT)] HRESULT text([in] BSTR p);
|
||||
[id(DISPID_XMLELEMENT_ADDCHILD)] HRESULT addChild([in] IXMLElement *pChildElem, long lIndex, long lReserved); // lReserved must be -1
|
||||
[id(DISPID_XMLELEMENT_REMOVECHILD)] HRESULT removeChild([in]IXMLElement *pChildElem);
|
||||
}
|
||||
|
||||
typedef struct __xml_error {
|
||||
unsigned _nLine; // line number
|
||||
BSTR _pchBuf; // current input buffer
|
||||
unsigned _cchBuf; // number of chars in buffer
|
||||
unsigned _ich; // index of the char when error occurred
|
||||
BSTR _pszFound; // token found
|
||||
BSTR _pszExpected; // token expected
|
||||
DWORD _reserved1; // reserved
|
||||
DWORD _reserved2; // reserved
|
||||
} XML_ERROR;
|
||||
|
||||
[
|
||||
object,
|
||||
local,
|
||||
uuid(948C5AD3-C58D-11d0-9C0B-00C04FC99C8E) // IID_IXMLError
|
||||
]
|
||||
|
||||
interface IXMLError : IUnknown
|
||||
{
|
||||
HRESULT GetErrorInfo(XML_ERROR *pErrorReturn);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[
|
||||
uuid(45E5B41D-2805-11D3-9425-000000000000),
|
||||
@@ -25,8 +119,8 @@ library MozActiveXMLLib
|
||||
]
|
||||
coclass MozXMLDocument
|
||||
{
|
||||
[default] interface IDispatch;
|
||||
// [default] interface IXMLDocument;
|
||||
interface IDispatch;
|
||||
[default] interface IXMLDocument;
|
||||
};
|
||||
[
|
||||
uuid(45E5B420-2805-11D3-9425-000000000000),
|
||||
@@ -34,8 +128,8 @@ library MozActiveXMLLib
|
||||
]
|
||||
coclass MozXMLElement
|
||||
{
|
||||
[default] interface IDispatch;
|
||||
// [default] interface IXMLElement;
|
||||
interface IDispatch;
|
||||
[default] interface IXMLElement;
|
||||
};
|
||||
[
|
||||
uuid(45E5B422-2805-11D3-9425-000000000000),
|
||||
@@ -43,7 +137,7 @@ library MozActiveXMLLib
|
||||
]
|
||||
coclass MozXMLElementCollection
|
||||
{
|
||||
[default] interface IDispatch;
|
||||
// [default] interface IXMLElementCollection;
|
||||
interface IDispatch;
|
||||
[default] interface IXMLElementCollection;
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user