Re: IHTMLAttributeCollection, IHTMLDOMAttribute, and E_NOINTERFACE (Source Program)
#include "StdAfx.h"
//
// Code basis was presented by Philip Patrick
// in 'Loading and parsing HTML using MSHTML'
//
// http://www.codeproject.com/internet/parse_html.asp
//
#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 = pDispatch->QueryInterface( IID_IHTMLDOMNode,
(VOID**)&pDOMNode );
if( FAILED( hr ) ) { throw __LINE__; }
CComPtr< IDispatch > pAttributes = NULL;
hr = pDOMNode->get_attributes( &pAttributes );
if( FAILED( hr ) ) { throw __LINE__; }
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++ )
{
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
CComPtr< IHTMLDOMAttribute > pAttribute = NULL;
hr = pAttributeCollection->QueryInterface(
IID_IHTMLDOMAttribute, (PVOID*)&pAttribute);
//if( FAILED( hr ) ) { throw __LINE__; }
if( FAILED( hr ) ) { continue; }
CComBSTR AttributeName( L"" );
CComVariant AttributeValue;
pAttribute->get_nodeName( &AttributeName );
pAttribute->get_nodeValue( &AttributeValue );
std::wcout << (wchar_t*)AttributeName << L"=";
std::wcout << (wchar_t*)AttributeValue << 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 );
}