我在基于对话框的MFC项目中添加了一个Web浏览器控件(IE)。现在我需要让它从内存中显示我的HTML标记。这似乎很简单,但我不能让它发挥作用。我一直在寻找将其设置为网页的代码like this。
经过进一步研究,我看到人们通过覆盖DownloadComplete
事件来设置它。所以我首先使用Navigate方法设置我的网页以显示空白页面,然后尝试从DownloadComplete
设置它:
CString gm_SomeGlobalVar;
void CMyDialogDlg::SetWebBrowserCtrlWithHTML(CString* pHTML)
{
gm_SomeGlobalVar = *pHTML;
COleVariant varNull;
COleVariant varUrl = urlForEmptyWebPage;
m_browser.Navigate2(varUrl, varNull, varNull, varNull, varNull);
}
BEGIN_EVENTSINK_MAP(CMyDialogDlg, CDialog)
ON_EVENT(CMyDialogDlg, IDC_EXPLORER1, 104, CMyDialogDlg::DownloadCompleteExplorer1, VTS_NONE)
END_EVENTSINK_MAP()
void CMyDialogDlg::DownloadCompleteExplorer1()
{
// TODO: Add your message handler code here
SetHTMLCtrlBody(&gm_SomeGlobalVar);
}
BOOL CMyDialogDlg::SetHTMLCtrlBody(CString* pStrHTML)
{
BOOL bRes = FALSE;
TRY
{
if(pStrHTML)
{
HRESULT hr;
LPDISPATCH pDisp = m_browser.get_Document();
if(pDisp != NULL)
{
CComPtr<IHTMLDocument2> pIDoc2;
if(SUCCEEDED(hr = pDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pIDoc2)))
{
CComPtr<IHTMLElement> pBody;
if(SUCCEEDED(hr = pIDoc2->get_body(&pBody)))
{
//For some dumb reason 'pBody' can still be NULL here
if(pBody)
{
BSTR htmlBStr = pStrHTML->AllocSysString();
if(htmlBStr)
{
if(SUCCEEDED(hr = pBody->put_innerHTML(htmlBStr)))
{
bRes = TRUE;
}
SysFreeString(htmlBStr);
}
}
}
}
pDisp->Release();
}
}
}
CATCH_ALL(e)
{
//Failed
ASSERT(NULL);
bRes = FALSE;
}
END_CATCH_ALL
return bRes;
}
但这会带来更多问题:
DownloadComplete
以某种方式被调用两次。
然后我尝试使用get_ReadyState查看文档状态何时报告为READYSTATE_COMPLETE
,但它永远不会。我收到READYSTATE_LOADING
和READYSTATE_INTERACTIVE
。
此外,它是一个非常不优雅的解决方案,即当我的SetWebBrowserCtrlWithHTML()
方法返回时,HTML可能尚未设置。
最后,在SetHTMLCtrlBody()
返回后立即从SetWebBrowserCtrlWithHTML()
致电我的m_browser.Navigate2()
会产生TRUE
,但HTML标记未显示在网络中浏览器控制。
所以我想知道,必须有更好的方法吗?