#include "StdAfx.h"
#include "HTMLParserMS.h"
using _com_util::CheckError;
namespace
{
class CHTMLNode : public IHTMLNode
{
public:
typedef CComPtr TComPtr;
typedef CComPtr TDocumentPtr;
protected:
typedef CComPtr TElementCollectionPtr;
public:
CHTMLNode(const TComPtr& pElement,const TDocumentPtr& pDocument)
: m_pElement(pElement),m_pDocument(pDocument){}
virtual THTMLNodePtr GetElementByID(const tstring& rsID)const
{
if(m_pDocument)
{
CComPtr pElement;
if(SUCCEEDED(m_pDocument->getElementById(bstr_t(rsID.c_str()),&pElement))
&& pElement)
{
TComPtr p(pElement);
return THTMLNodePtr(new CHTMLNode(p,m_pDocument));
}
}
return THTMLNodePtr();
}
virtual size_t GetChildCount()const
{
TElementCollectionPtr pColl = GetElementCollectionPtr();
if(pColl)
{
LONG celem = 0;
HRESULT hr = pColl->get_length(&celem);
if(S_OK == hr)
{
return celem;
}
}
return 0;
}
virtual THTMLNodePtr GetChildPtr(size_t nIndex)
{
TElementCollectionPtr pColl = GetElementCollectionPtr();
if(pColl)
{
VARIANT varIndex;
varIndex.vt = VT_UINT;
varIndex.lVal = (LONG)nIndex;
VARIANT var2;
VariantInit(&var2);
TComPtr pDisp;
HRESULT hr = pColl->item(varIndex,var2,&pDisp);
if(S_OK == hr && pDisp)
{
return THTMLNodePtr(new CHTMLNode(pDisp,m_pDocument));
}
}
return THTMLNodePtr();
}
virtual bool Is(EType nType)const
{
switch(nType)
{
case Table:
{
CComPtr pTable;
return (SUCCEEDED(m_pElement->QueryInterface(IID_IHTMLTable,reinterpret_cast(&pTable))) && (pTable));
}
case TableRow:
{
CComPtr pRow;
return (SUCCEEDED(m_pElement->QueryInterface(IID_IHTMLTableRow,reinterpret_cast(&pRow))) && (pRow));
}
case TableColumn:
{
CComPtr pCol;
return (SUCCEEDED(m_pElement->QueryInterface(IID_IHTMLTableCol,reinterpret_cast(&pCol))) && (pCol));
}
}
return false;
}
virtual tstring GetAttribute(const tstring& rsAttrName)const
{
USES_CONVERSION;
tstring sAttr;
CComPtr pElement;
if(SUCCEEDED(m_pElement->QueryInterface(IID_IHTMLElement,reinterpret_cast(&pElement))) && pElement)
{
_variant_t vAttribute;
BSTR pbstrAttrName = T2BSTR(rsAttrName.c_str());
if(SUCCEEDED(pElement->getAttribute(pbstrAttrName,1,&vAttribute))
&& VT_NULL != vAttribute.vt && VT_EMPTY != vAttribute.vt)
{
try
{
_bstr_t b(vAttribute);
LPCTSTR psz = b;
if(psz)
{
sAttr = psz;
}
}
catch(_com_error&)
{
}
}
}
return sAttr;
}
virtual tstring GetText()const
{
// USES_CONVERSION;
tstring sText;
CComPtr pElement;
if(SUCCEEDED(m_pElement->QueryInterface(IID_IHTMLElement,reinterpret_cast(&pElement))) && pElement)
{
BSTR bstrText;
if(SUCCEEDED(pElement->get_innerText(&bstrText)) && bstrText)
{
try
{
sText = _bstr_t(bstrText);
}
catch(_com_error&)
{
}
::SysFreeString(bstrText);
}
}
return sText;
}
protected:
virtual TElementCollectionPtr GetElementCollectionPtr()const
{
TElementCollectionPtr pColl;
HRESULT hr = m_pElement->QueryInterface(IID_IHTMLElementCollection,reinterpret_cast(&pColl));
if(FAILED(hr))
{
CComPtr pElement;
if(SUCCEEDED(m_pElement->QueryInterface(IID_IHTMLElement,reinterpret_cast(&pElement))) && pElement)
{
CComPtr pDisp;
if(SUCCEEDED(pElement->get_children(&pDisp)) && pDisp)
{
hr = pDisp->QueryInterface(IID_IHTMLElementCollection,reinterpret_cast(&pColl));
}
}
}
return pColl;
}
private:
TComPtr m_pElement;
TDocumentPtr m_pDocument;
};
}
CHTMLParserMS::CHTMLParserMS() : m_bCallUninit(false)
{
try
{
CheckError(::CoInitialize(NULL));
m_bCallUninit = true;
_com_util::CheckError(
::CoCreateInstance(CLSID_HTMLDocument,
NULL,
CLSCTX_INPROC_SERVER,
IID_IHTMLDocument2,
(LPVOID*)&m_pDoc)
);
CComPtr pPersist;
_com_util::CheckError(m_pDoc->QueryInterface(IID_IPersistStreamInit,
(LPVOID*)&pPersist));
_com_util::CheckError(pPersist->InitNew());
_com_util::CheckError(m_pDoc->QueryInterface(IID_IMarkupServices,
(LPVOID*)&m_pMS));
if(m_pMS)
{
_com_util::CheckError(m_pMS->CreateMarkupPointer(&m_pMkStart));
_com_util::CheckError(m_pMS->CreateMarkupPointer(&m_pMkFinish));
}
}
catch(_com_error&/* e*/)
{
// show_com_error_msg(e);
}
}
CHTMLParserMS::~CHTMLParserMS()
{
if(true == m_bCallUninit)
{
::CoUninitialize();
}
}
CHTMLParserMS::THTMLNodePtr CHTMLParserMS::ParseString(const tstring& rsHTML)
{
USES_CONVERSION;
try
{
CGuard cs(m_cs);
OLECHAR* p = T2OLE(const_cast(rsHTML.c_str()));
CComPtr pMC;
_com_util::CheckError(m_pMS->ParseString(p,0,&pMC,m_pMkStart,m_pMkFinish));
if(pMC)
{
CComPtr pNewDoc;
_com_util::CheckError(pMC->QueryInterface(IID_IHTMLDocument,
(LPVOID*)&pNewDoc));
if(pNewDoc)
{
CComPtr pColl;
_com_util::CheckError(pNewDoc->get_all(&pColl));
CHTMLNode::TDocumentPtr pDoc;
pMC->QueryInterface(IID_IHTMLDocument3,(LPVOID*)&pDoc);
return THTMLNodePtr(new CHTMLNode(CHTMLNode::TComPtr(pColl),pDoc));
}
}
}
catch(_com_error&/* e*/)
{
// show_com_error_msg(e);
}
return THTMLNodePtr();
}
bool CHTMLParserMS::IsInstalled()
{
bool bResult = true;
bool bCallUninit = false;
try
{
CheckError(::CoInitialize(NULL));
bCallUninit = true;
CComPtr pDoc;
_com_util::CheckError(
::CoCreateInstance(CLSID_HTMLDocument,
NULL,
CLSCTX_INPROC_SERVER,
IID_IHTMLDocument2,
reinterpret_cast(&pDoc))
);
}
catch(_com_error&/* e*/)
{
bResult = false;
}
if(bCallUninit)
{
::CoUninitialize();
}
return bResult;
}
CHTMLEngineMS::CHTMLEngineMS()
{
}
CHTMLEngineMS::~CHTMLEngineMS()
{
}
CHTMLEngineMS::THTMLParserPtr CHTMLEngineMS::GetParserPtr()const
{
return THTMLParserPtr(new CHTMLParserMS);
}