Internet explorer Webbrowser控件-使用“显示文本”;写下;
我正在使用IWebBrowser2接口从运行时创建的HTML字符串呈现页面。我已经编写了一个方法(我们称之为displaythmlstring),它接受一个HTML字符串并呈现它,如中所示。该方法还首先使用“about:blank”调用Navigate2,以确保文档存在,并在调用write后调用close 第一次调用DisplayHtmlString时,页面始终正确呈现,即浏览器根据我传递的字符串显示HTML。问题是后续调用有时不能正常工作,而是呈现一个空白页。这可能是什么原因造成的Internet explorer Webbrowser控件-使用“显示文本”;写下;,internet-explorer,webbrowser-control,ihtmldocument2,Internet Explorer,Webbrowser Control,Ihtmldocument2,我正在使用IWebBrowser2接口从运行时创建的HTML字符串呈现页面。我已经编写了一个方法(我们称之为displaythmlstring),它接受一个HTML字符串并呈现它,如中所示。该方法还首先使用“about:blank”调用Navigate2,以确保文档存在,并在调用write后调用close 第一次调用DisplayHtmlString时,页面始终正确呈现,即浏览器根据我传递的字符串显示HTML。问题是后续调用有时不能正常工作,而是呈现一个空白页。这可能是什么原因造成的 我发现当空
我发现当空白页被显示时,这是导航到空白的结果。这是通过导航到一个本地文件来确定的,然后显示该文件(由于随后的写入/关闭,应该显示HTML字符串)。因此,对Navigate2的调用有效,而对write和close的调用有时无效
我认为IE内部安全检查是一个可能的原因(跨域检查?),但我的直觉是,这不是这里发生的事情 在我看来,这更像是某种同步问题,类似于“IE在下一次调用DisplayHtmlString之前还没有完成渲染”。我的代码最初没有检查浏览器的就绪状态(因为示例没有检查)。我添加了一个带有get_readyState调用的实验性等待循环,并观察到在从方法返回之前,状态从未超出“加载”范围-可能是因为渲染是异步的(?)。我还注意到,当对DisplayHtmlString的连续调用正常工作时,程序的主消息循环已经运行(给Windows一个处理消息的机会),这在对DisplayHtmlString的连续调用失败的情况下并非如此 所以我很确定我需要在这里提供正确的同步,但是如何?我注意到有一个名为onreadystatechange的方法,但由于我在黑暗中摸索时尝试了许多其他方法,所以还没有尝试过。这可能是解决方案吗?如何正确使用?或者,我应该只处理DisplayHtmlString中的消息循环,直到就绪状态变为“完成”吗更新:将消息循环处理添加到DisplayHtmlString。在第一次调用中(有效),就绪状态变为“交互式”,但不再进一步(这似乎不是问题)。在随后的调用中(失败时),就绪状态保持在“加载”状态,即使消息循环已被处理。您应该处理
文档
对象上的readystatechange
事件。在JavaScript中,它将如下所示:
<body>
<body>Hi, this is going to be replaced!</body>
<script>
window.onload = function()
{
document.open("text/html");
document.onreadystatechange = function() {
if (document.readyState == "complete")
alert("Done!");
}
document.write("<b>Hello again!</b>");
document.close();
}
</script>
</body>
使用它:
CComObject<CEventSink>* p = NULL;
hr = CComObject<CEventSink>::CreateInstance(&p);
if ( FAILED(hr) )
return 0;
p->Init(m_hWnd, WM_DOCUMENTREADYSTATECHANGE);
m_eventSink = p; // does AddRef
// ...
m_htmlDocument2->put_onreadystatechange(CComVariant(m_eventSink));
ccombject*p=NULL;
hr=ccombject::CreateInstance(&p);
如果(失败(小时))
返回0;
p->Init(m_hWnd,WM_DOCUMENTREADYSTATECHANGE);
m_eventSink=p;//AddRef吗
// ...
m_htmlDocument2->put_on readystatechange(CComVariant(m_eventSink));
有关更多详细信息,请获取并查看
WebOcHost.cpp
。为简洁起见,错误检查非常基本我使用C++;如果您有一个代码示例,那将非常有帮助。我还不明白关于DISPID_值的部分。同步或异步渲染对我来说都可以。我想通常更推荐异步。谢谢,但是您确定这些链接指向正确的示例吗?是C#,我找不到Web0cHost.cpp。
CComObject<CEventSink>* p = NULL;
hr = CComObject<CEventSink>::CreateInstance(&p);
if ( FAILED(hr) )
return 0;
p->Init(m_hWnd, WM_DOCUMENTREADYSTATECHANGE);
m_eventSink = p; // does AddRef
// ...
m_htmlDocument2->put_onreadystatechange(CComVariant(m_eventSink));