所以不幸的是我为Internet Explorer写了一个BHO。它的功能是在用户访问的每个网页中注入一个iframe,在用户处理他或她的业务时显示一些(相对)恒定的信息。我通过一系列相当hacky的mshtml强制转换来管理注入,如下所示,其中Explorer是一个WebBrowserClass对象,foo.html提供了BHO的源代码:
IHTMLDocument2 document = (IHTMLDocument2) Explorer.Document;
IHTMLDocument3 doc3 = (IHTMLDocument3)document;
var iframe = document.createElement("iframe");
iframe.setAttribute("src", "foo.html");
iframe.setAttribute("id", "iFrame");
iframe.setAttribute("style", "position: fixed; left: 0px; top: 0px; border: 0px; width: 100%; height: 45px; background-color: white");
IHTMLElementCollection iec = doc3.getElementsByTagName("body");
IHTMLElement elem = (IHTMLElement)iec.item(0);
IHTMLDOMNode domnode = (IHTMLDOMNode)elem;
domnode.appendChild((IHTMLDOMNode)iframe);
这个有效!我认为。有点。如果我将它粘贴在OnDocumentComplete中,它会导致无限循环,并且它不会以任何方式显示任何iframe。循环的问题是使用Explorer的事件监听器,如OnDocumentComplete,因为只要iFrame中的页面完成加载就调用它们,然后调用注入函数,然后调用OnDocumentComplete,这就好了,你明白了。我尝试过使用OnNavigateComplete,但它仍会在从多个来源加载的网页上多次加载(例如,google的主要搜索页面启用了自动完成功能。)但即使它没有进入无限循环,我仍然没有看到一个可见的iframe。
所以我想这是两个问题: 1)我如何让我的iframe出现?注入代码有效(我用简单的javascript警告尝试过)... 2)如何在每次用户导航到新页面时刷新我的iframe或刷新当前iframe而不会导致BHO进入无限循环?
其他可能相关的功能:
void OnNavigateComplete(object pDisp, ref object URL)
{
if ((_currentDocument != null) && (isValidURL(_currentDocument.url)))
{
injectFrame();
}
}
void OnDocumentComplete(object pDisp, ref object URL)
{
if (Explorer.ReadyState == SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE)
{
_currentDocument = Explorer.Document as mshtml.HTMLDocument;
if (_currentDocument != null)
{
//injectFrame();
}
}
}
答案 0 :(得分:2)
好吧,我想我大部分都是这样想的。 OnDocumentComplete仍然不止一次被调用,但我已经怀疑框架的所有问题......所以当iframe加载多次时,它会被加载到同一个地方。
无限循环的修复是硬编码工具栏的位置,并在OnDocumentComplete中检查该URL:
void OnDocumentComplete(object pDisp, ref object URL)
{
// _currentDocument = Explorer.Document as mshtml.HTMLDocumentClass;
if (Explorer.ReadyState == SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE)
{
_currentDocument = Explorer.Document as mshtml.HTMLDocument;
if (_currentDocument != null)
{
// we have a document - attach our events
// on onload event should go here if the document is now complete...
if (!URL.Equals("http://url.to/foo.html")) injectFrame();
}
else
{
// document is null?
// Debugger.ShowMessage("Tried to attach to document, but was null");
}
}
}
就iframe而言,Style属性显然是它自己的字符串集,而不仅仅是像每个OTHER属性一样的常规字符串。所以不要做像...这样的事情。
setAttribute("style","position: fixed; left: 0px; top: 0px; border: 0px; width: 100%; height: 45px; background-color: white");
我最终不得不做
iframe.style.setAttribute("position", "fixed");
iframe.style.left="0px";
iframe.style.top="0px";
iframe.style.border="0px";
iframe.style.width = "100%";
iframe.style.height="45px";
iframe.style.backgroundColor="white";
这一切都是一个巨大的麻烦,我希望永远不必再次处理它。