Re: IStorage and hr = 80000050 (File Already Exists)
Hi Igor,
Almost there.
IMarkupServices, ParseString() Method. How does one request document
parsing on a IStream rather than a BSTR (or has it been accomplished)?
Jeff
#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 )
#pragma comment( lib, "urlmon" ) // URLOpenBlockingStream
#include <windows.h>
#include <atlbase.h> // CComPtr<>, CoInitializeEx, etc
#include <mshtml.h> // MSHTML Object and Interfaces
#include <assert.h>
#include <Urlmon.h> // URLOpenBlockingStream
// Standard C++ Library
#include <iostream>
#include <iomanip>
int main(int argc, char* argv[])
{
HRESULT hr = S_OK;
CComBSTR Page;
try
{
///////////////////////////////////////////////////////////////////
hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
// Create a Document to bootstrap the process
CComPtr< MSHTML::IHTMLDocument2 > pDocument;
CoCreateInstance( CLSID_HTMLDocument, NULL,
CLSCTX_INPROC_SERVER, IID_IHTMLDocument2,
reinterpret_cast<PVOID*>( &pDocument ) );
if( NULL == pDocument.p ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
CComBSTR protocol = OLESTR("file:///");
CComBSTR filename = OLESTR( "C:\\Test.html" );
CComBSTR protofile = protocol;
protofile += filename;
///////////////////////////////////////////////////////////////////
// From Igor Tandetnik
CComPtr< IStream > pFileStream;
hr = URLOpenBlockingStream( NULL /*Controlling IUnknown*/,
(wchar_t*)protofile, &pFileStream, 0 /*Reserved*/,
NULL /*IBindStatusCallback*/ );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
CComPtr< IPersistStreamInit > pPersistStream;
hr = pDocument->QueryInterface( IID_IPersistStreamInit,
reinterpret_cast<PVOID*>( &pPersistStream ) );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
// From MSDN
hr = pPersistStream->InitNew();
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
// From MSDN
hr = pPersistStream->Load( pFileStream );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
CComPtr< MSHTML::IMarkupServices > pMarkupServices;
hr = pDocument->QueryInterface( IID_IMarkupServices,
reinterpret_cast<PVOID*>( &pMarkupServices ) ) ;
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
CComPtr< MSHTML::IMarkupPointer > pBegin;
hr = pMarkupServices->CreateMarkupPointer( &pBegin );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
hr = pMarkupServices->CreateMarkupPointer( &pEnd );
CComPtr< MSHTML::IMarkupPointer > pEnd;
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
CComPtr< MSHTML::IMarkupContainer > pContainer;
hr = pMarkupServices->ParseString( Page, 0, &pContainer,
pBegin, pEnd );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
CComPtr< MSHTML::IHTMLDocument2 > pNewDocument;
pContainer->QueryInterface( IID_IHTMLDocument,
reinterpret_cast<PVOID*>( &pNewDocument ) );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
CComPtr< MSHTML::IHTMLElementCollection > pElementCollection;
hr = pNewDocument->get_all( &pElementCollection );
if( FAILED( hr ) ) { throw __LINE__; }
///////////////////////////////////////////////////////////////////
for( INT i = 0; i < pElementCollection->length; i++ )
{
////////////////////////////////////////////////////////////////
CComPtr< IDispatch > pDispatch = NULL;
CComVariant v;
v.intVal = i;
v.vt = VT_I4;
pDispatch = pElementCollection->item( v );
if( NULL == pDispatch.p ){ throw __LINE__; }
////////////////////////////////////////////////////////////////
CComPtr< MSHTML::IHTMLElement > pElement = NULL;
hr = pDispatch->QueryInterface( IID_IHTMLElement,
reinterpret_cast<PVOID*>( &pElement ) );
if( FAILED( hr ) ) { throw __LINE__; }
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
std::wcout << (wchar_t*)pElement->tagName << L":" <<
std::endl;;
CComBSTR Text;
hr = pElement->get_innerText( &Text );
// If NULL = Text.m_str, use getName(BSTR*)
// to retreive the element's name.
// See MSDN for details
if( S_OK == hr && NULL != Text.m_str )
{
std::wcout << (wchar_t*)Text << std::endl;
}
std::cout << std::endl;
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
}
}
catch( _com_error* e )
{
std::wcout << std::endl;
std::wcout << L"COM Error: " << e->ErrorMessage() << std::endl;
std::wcout << std::hex << L" 0x" << std::setw( 8 ) << e->Error();
std::wcout << L" (Win32: " << std::dec << HRESULT_CODE(
e->Error() );
std::wcout << L")" << std::endl;
}
catch( INT line )
{
std::wcout << std::endl;
std::wcout << L"COM Error near Line " << line << std::endl;
std::wcout << std::hex << L" 0x" << std::setw( 8 ) << hr;
std::wcout << L" (Win32: " << std::dec << HRESULT_CODE( hr );
std::wcout << L")" << std::endl;
}
catch( ... )
{
std::wcout << std::endl;
std::wcout << L"COM Error:" << std::endl;
std::wcout << std::hex << L" 0x" << std::setw( 8 );
std::wcout << std::setfill( L'0' ) << hr;
std::wcout << L" (Win32: " << std::dec << HRESULT_CODE( hr );
std::wcout << L")" << std::endl;
}
CoUninitialize( );
return HRESULT_CODE( hr );
}