使用WebBrowser
control,我目前无法检测是否由于主页面的网址被更改而导致Navigating
event被触发,或者是否加载了IFRAME。
Frame
参数始终为空,无论我将哪个属性添加到IFRAME。
我的问题:
是否有任何机会/技巧可以在Navigating
事件处理程序中确定该事件是否由IFRAME触发?
答案 0 :(得分:3)
找到解决方法:
我必须按照DWebBrowserEvents2
interface中的说明实施其他this Code Project article以获取其他活动。
然后,我会在BeforeNavigate2
event收到更多信息的通知。
我发现pDisp
是IWebBrowser2
interface,并且该界面的Parent
property对于顶部窗口是NULL
而对于(I)是非NULL
帧。
这对我来说已经足够了,所以我可以写下:
public class BrowserExtendedNavigatingEventArgs : CancelEventArgs
{
// ...
public bool IsInsideFrame
{
get
{
var wb = AutomationObject as UnsafeNativeMethods.IWebBrowser2;
return wb != null && wb.Parent != null;
}
}
// ...
}
请注意,您必须确保从创建Web浏览器控件的线程中调用IsInsideFrame
属性,否则您可能会遇到访问冲突异常just as described here:
“...所有IE COM对象,包括webbrowser控件,都是Single 螺纹公寓对象。这意味着,除其他外,你可以 只能从创建它们的线程访问它们。如果你 需要从其他线程使用它们,你需要使用它们来编组它们 GIT或CoMarshallInterThreadInterfaceInStream()和相关的 功能...“
我希望这也可以帮助别人。
替代解决方案
自I got AccessViolationException
s访问wb.Parent
以来,虽然我认为我做的一切正确,但我一直在寻找替代解决方案。
我在this Code Project article找到了它。
基本上,本文使用另一种方法来确定框架。它通过比较对Web浏览器控件的引用来实现。
伪代码:
public void BeforeNavigate2(
object pDisp,
ref object url,
ref object flags,
ref object targetFrameName,
ref object postData,
ref object headers,
ref bool cancel)
{
// ...
var isTopFrame = _browser._axIWebBrowser2.Equals(pDisp);
// ...
}
到目前为止,我的测试成功运行,我真的希望我不再接受这些可怕的访问冲突异常。