Internet explorer Webbrowser控件-使用“显示文本”;写下;

Internet explorer Webbrowser控件-使用“显示文本”;写下;,internet-explorer,webbrowser-control,ihtmldocument2,Internet Explorer,Webbrowser Control,Ihtmldocument2,我正在使用IWebBrowser2接口从运行时创建的HTML字符串呈现页面。我已经编写了一个方法(我们称之为displaythmlstring),它接受一个HTML字符串并呈现它,如中所示。该方法还首先使用“about:blank”调用Navigate2,以确保文档存在,并在调用write后调用close 第一次调用DisplayHtmlString时,页面始终正确呈现,即浏览器根据我传递的字符串显示HTML。问题是后续调用有时不能正常工作,而是呈现一个空白页。这可能是什么原因造成的 我发现当空

我正在使用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
。为简洁起见,错误检查非常基本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));