Re: IHTMLAttributeCollection, IHTMLDOMAttribute, and E_NOINTERFACE (Fixed)
Hi All,
2 mistakes now fixed. Below dumps any non-NULL Name/Value pairs (both
Name and Value must not be NULL).
I miss VB's for/each construct...
Jeff
Jeffrey Walton
#define _WIN32_IE 0x0500 // IMarkupServices
#define _WIN32_DCOM // CoInitializeEx(...)
#pragma warning( disable: 4192 )
#pragma warning( disable: 4278 )
#import "mshtml.tlb" // MSHTML Namespace and Guids
#pragma warning( default: 4192 )
#pragma warning( default: 4278 )
#include <windows.h>
#include <atlbase.h> // CComPtr<>, CoInitializeEx, etc
#include <mshtml.h> // MSHTML Object and Interfaces
#include <assert.h>
// Standard C++ Library
#include <iostream>
HRESULT hr = S_OK;
int main(int argc, char* argv[])
{
CComBSTR Page = OLESTR( "<HTML>" );
Page += OLESTR( "<HEAD>" );
Page += OLESTR( "<TITLE>Hello World Title</TITLE>" );
Page += OLESTR( "</HEAD>" );
Page += OLESTR( "<BODY>" );
Page += OLESTR( "<P align=\"center\">Center Paragraph 1</P>" );
Page += OLESTR( "<P><I>Italic Paragraph 2</I></P>" );
Page += OLESTR( "<UL class=\"download\"><LI>List 1, Item 1</LI>" );
Page += OLESTR( "<LI>List 1, Item 2</LI></UL>" );
Page += OLESTR( "<UL><LI><U>List 2, Underline Item 1</U></LI>" );
Page += OLESTR( "<LI>List 2, Item 2</LI></UL>" );
Page += OLESTR( "</BODY>" );
Page += OLESTR( "</HTML>" );
try
{
// Get CComPtr< > in a try block so they can do their job
CComPtr< MSHTML::IHTMLDocument2 > pDocument = NULL;
CComPtr< IPersistStreamInit > pStream = NULL;
CComPtr< MSHTML::IMarkupServices > pMarkupServices = NULL;
CComPtr< MSHTML::IMarkupContainer > pContainer = NULL;
CComPtr< MSHTML::IMarkupPointer > pBegin = NULL;
CComPtr< MSHTML::IMarkupPointer > pEnd = NULL;
CComPtr< MSHTML::IHTMLDocument2 > pNewDocument = NULL;
CComPtr< MSHTML::IHTMLElementCollection > pCollection = NULL;
///////////////////////////////////////////////////////////////////
hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
// Create a Document to bootstrap the process
CoCreateInstance(CLSID_HTMLDocument, NULL,
CLSCTX_INPROC_SERVER, IID_IHTMLDocument2,
reinterpret_cast<PVOID*>( &pDocument) );
if( NULL == pDocument.p ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
hr = pDocument->QueryInterface( IID_IPersistStreamInit,
reinterpret_cast<PVOID*>( &pStream ) );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
hr = pStream->InitNew();
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
hr = pDocument->QueryInterface( IID_IMarkupServices,
reinterpret_cast<PVOID*>( &pMarkupServices ) ) ;
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
hr = pMarkupServices->CreateMarkupPointer( &pBegin );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
hr = pMarkupServices->CreateMarkupPointer( &pEnd );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
hr = pMarkupServices->ParseString( Page, 0, &pContainer, pBegin,
pEnd );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
pContainer->QueryInterface( IID_IHTMLDocument,
reinterpret_cast<PVOID*>( &pNewDocument ) );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
hr = pNewDocument->get_all( &pCollection );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
for( INT i = 0; i < pCollection->length; i++ )
{
CComVariant v;
v.intVal = i;
v.vt = VT_I4;
CComPtr< IDispatch > pDispatch = NULL;
pDispatch = pCollection->item( v );
if( NULL != pDispatch.p )
{
CComPtr< MSHTML::IHTMLElement > pElement = NULL;
CComPtr< MSHTML::IHTMLDOMNode > pDOMNode = NULL;
///////////////////////////////////////////////////////////
hr = pDispatch->QueryInterface( IID_IHTMLElement,
(VOID**)&pElement );
if( FAILED( hr ) ) { throw __LINE__; }
std::wcout << (wchar_t*)pElement->tagName << L":" << std::endl;
CComBSTR Text;
hr = pElement->get_innerText( &Text );
if( S_OK == hr && NULL != Text.m_str )
{
std::wcout << (wchar_t*)Text;
}
std::cout << std::endl << std::endl;
///////////////////////////////////////////////////////////
hr = pElement->QueryInterface( IID_IHTMLDOMNode,
(VOID**)&pDOMNode );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////
CComPtr< IDispatch > pAttributes = NULL;
hr = pDOMNode->get_attributes( &pAttributes );
if( FAILED( hr ) ) { throw __LINE__; }
v
CComPtr< IHTMLAttributeCollection > pAttributeCollection =
NULL;
hr = pAttributes->QueryInterface( IID_IHTMLAttributeCollection,
(PVOID*)&pAttributeCollection );
if( FAILED( hr ) ) { throw __LINE__; }
LONG length = 0;
hr = pAttributeCollection->get_length( &length );
if( FAILED( hr ) ) { length = 0; } // try to recover...
//for( INT j = 0; j < pAttributeCollection->length; j++ )
for( INT j = 0; j < length; j++ )
{
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
CComVariant v;
v.intVal = j;
v.vt = VT_I4;
CComPtr< IDispatch > pDispatch = NULL;
hr = pAttributeCollection->item( &v, &pDispatch );
if( NULL != pDispatch.p )
{
CComPtr< IHTMLDOMAttribute > pAttribute = NULL;
hr = pDispatch->QueryInterface(
IID_IHTMLDOMAttribute, (PVOID*)&pAttribute);
if( FAILED( hr ) ) { throw __LINE__; }
CComBSTR AttributeName;
CComVariant AttributeValue;
pAttribute->get_nodeName( &AttributeName );
pAttribute->get_nodeValue( &AttributeValue );
if( NULL != AttributeName.m_str && NULL !=
AttributeValue.bstrVal )
{
std::wcout << (wchar_t*)AttributeName << L"=";
std::wcout << (wchar_t*)AttributeValue.bstrVal <<
std::endl;
}
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
}
}
}
}
}
catch( UINT line )
{
std::wcout << std::endl;
std::wcout << L"COM Error near Line " << line << std::endl;
std::wcout << std::hex << L" 0x" <<hr;
std::wcout << L" (Win32: " << std::dec << HRESULT_CODE( hr );
std::wcout << L")" << std::endl;
}
CoUninitialize( );
return HRESULT_CODE( hr );
}