I have noticed that that if you use IPersistStreamInit to
stream some HTML to the WebBrowser, the URL property
changes to "about:blank". This obviously affects all
hyperlinks within the document causing them to open
as "about:blankmylink.htm" (for instance)
Anyone have ideas on a workaround/alternate solution?
steps to reproduce:
i) use IWebBrowser2::Navigate(), to navigate to a file on
your harddrive.
pIE->Navigate(strHomePage, &CComVariant(), &CComVariant
(), &CComVariant(), &CComVariant());
ii) stream a new file (generated dynamically) using:
static HRESULT SetHTML( IWebBrowser2* m_spIE, LPCOLESTR
psz )
{
CComPtr<IDispatch> spDispDoc;
HRESULT hr = E_FAIL;
m_spIE->get_Document( &spDispDoc );
ASSERT(spDispDoc!=NULL);
if (!spDispDoc)
return E_FAIL;
// allocate global memory to copy the HTML
content to
HGLOBAL hHTMLContent = ::GlobalAlloc( GPTR,
( ::wcslen( psz ) + 1 ) * sizeof(wchar_t) + 2 );
if (!hHTMLContent)
return E_FAIL;
((wchar_t*) hHTMLContent)[0] = 0xfeff; // mark
this string as UNICODE
::wcscpy( ((wchar_t*) hHTMLContent)+1, psz );
// create a stream object based on the HTML
content
CComPtr<IStream> spStream;
hr = ::CreateStreamOnHGlobal( hHTMLContent, TRUE,
&spStream );
if (spStream)
{
// request the IPersistStreamInit
interface
CComQIPtr<IPersistStreamInit> spPSI(
spDispDoc );
if (spPSI)
{
// initialize the persist stream
object
hr = spPSI->InitNew();
if (SUCCEEDED(hr))
{
// load the data into it
hr = spPSI->Load(
spStream );
}
}
}
return hr;
}
"BUG: document.write from Automation Client May Change
URL to about:blank"
This affects IE5.0 and later.
It's obviously still a bug in IE6.
And if you (like me) have applied recent security patches
(Q822925), then any urls that you may have pointing to
the file system will no longer work.
This is because the recent IE patches indicate
that "about:blank" and "file://C:/xxx.htm" are no longer
on the same domain and you will get "Access Violations".
IMHO the recent web browser patch (Q822925) is buggy.
Cheers all.
See
http://groups.google.com/groups?threadm=uK%24I6nz5CHA.2364%40TK2MSFTNGP10.phx.gbl
--
With best wishes,
Igor Tandetnik
"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken
For posterity (my humble way of saying thanks) I also
attach an ATL implementation that appears to work well.
Note that I return E_NOTIMPL for ALL of the other methods
in IMoniker as none of them appear to be called. Note
that the object is not QI'd for anything else either.
///////////////////////////////////////////////
// init the moniker object
HRESULT CHTMLMoniker::SetHTML(LPCOLESTR pszHTML,
LPCOLESTR pszBaseURL)
{
m_strBaseURL = pszBaseURL;
m_spStream.Release();
// allocate global memory to copy the HTML content to
HGLOBAL hHTMLContent = ::GlobalAlloc( GPTR,
( ::wcslen( pszHTML ) + 1 ) *
sizeof(wchar_t) + 2 );
if (!hHTMLContent)
return E_FAIL;
// mark this string as UNICODE
((wchar_t*) hHTMLContent)[0] = 0xfeff;
::wcscpy( ((wchar_t*) hHTMLContent)+1, pszHTML );
CComPtr<IStream> spStream;
return ::CreateStreamOnHGlobal( hHTMLContent,
TRUE, &m_spStream );
}
///////////////////////////////////////////////
// IMoniker implementation
STDMETHODIMP CHTMLMoniker::BindToStorage(IBindCtx* pbc,
IMoniker* pmkToLeft,
REFIID riid, void** ppvObj)
{
// NB: only IID_IStream seems to be used
return m_spStream->QueryInterface(riid, ppvObj);
}
STDMETHODIMP CHTMLMoniker::GetDisplayName(IBindCtx* pbc,
IMoniker* pmkToLeft,
LPOLESTR* ppszDisplayName)
{
if (!ppszDisplayName) return E_INVALIDARG;
*ppszDisplayName = NULL;
CComPtr<IMalloc> spMalloc;
CoGetMalloc(1, &spMalloc);
LPOLESTR psz = (LPOLESTR) spMalloc->Alloc(
(m_strBaseURL.Length()+1)*2 );
*psz = 0;
if (m_strBaseURL.Length())
wcscpy(psz, m_strBaseURL);
*ppszDisplayName = psz;
return S_OK;
}
>.
>