我正在构建一个使用 WebBrowser 控件的 WPF 应用程序。
我在两点上苦苦挣扎:
如何从控件中获取下载的当前进度。WinForms WebBrowser 控件引发 ProgressChange 事件 - 如何使用 WPF 变体复制此功能?
如何捕获试图在新窗口中打开的链接。Winforms WebBrowser 再次有一个 NewWindow 事件。我可以使用它来停止启动 IE 并在同一窗口中打开链接。是否可以使用 WPF 变体做到这一点?
我正在构建一个使用 WebBrowser 控件的 WPF 应用程序。
我在两点上苦苦挣扎:
如何从控件中获取下载的当前进度。WinForms WebBrowser 控件引发 ProgressChange 事件 - 如何使用 WPF 变体复制此功能?
如何捕获试图在新窗口中打开的链接。Winforms WebBrowser 再次有一个 NewWindow 事件。我可以使用它来停止启动 IE 并在同一窗口中打开链接。是否可以使用 WPF 变体做到这一点?
找到我想要的信息后,我想我会为任何感兴趣的人更新这个问题。
在http://msdn.microsoft.com/en-us/library/system.windows.controls.webbrowser(v=VS.90).aspx的底部有一条题为“Getting to the native IWebBrowser2”的评论。
这显示了如何到达所需的界面,并且似乎运行良好。
编辑:在这里添加链接的内容,因为 MSDN 上的评论不断消失在我身上。
我们的托管包装器尚未公开本机 Web 浏览器控件的许多功能。以下代码片段显示了如何IWebBrowser2
从 WPF WebBrowser 控件获取界面。这允许访问对象上未以其他方式公开公开的控件方法。但是请注意,此代码示例仅适用于完全受信任的代码。
首先,请参阅此处的 IWebBrowser2 文档:http: //msdn.microsoft.com/en-us/library/aa752127.aspx ...
System32\shdocvw.dll
要编译此代码,请添加对或的 COM 引用ieframe.dll
(无论您拥有哪个,具体取决于 IE 的版本)。
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
internal interface IServiceProvider
{
[return: MarshalAs(UnmanagedType.IUnknown)]
object QueryService(ref Guid guidService, ref Guid riid);
}
static readonly Guid SID_SWebBrowserApp =
new Guid("0002DF05-0000-0000-C000-000000000046");
// ...
IServiceProvider serviceProvider = (IServiceProvider)myWebBrowser.Document;
Guid serviceGuid = SID_SWebBrowserApp;
Guid iid = typeof(SHDocVw.IWebBrowser2).GUID;
SHDocVw.IWebBrowser2 myWebBrowser2 =
(SHDocVw.IWebBrowser2) serviceProvider.QueryService(ref serviceGuid, ref iid);
然后 myWebBrowser2 已准备好进行交互。
您还可以通过生成的托管包装器处理本机 Web 浏览器的事件 ( http://msdn.microsoft.com/en-us/library/aa768309(VS.85).aspx ),如下所示:
SHDocVw.DWebBrowserEvents_Event wbEvents = (SHDocVw.DWebBrowserEvents_Event)myWebBrowser2;
wbEvents.NewWindow += new SHDocVw.DWebBrowserEvents_NewWindowEventHandler(OnWebBrowserNewWindow);
void OnWebBrowserNewWindow(string URL, int Flags, string TargetFrameName, ref object PostData, string Headers, ref bool Processed)
{
// Set Processed to cancel opening of the new window.
}
要获取IWebBrowser2
接口,有一个简单的方法:
//The "browser" is a object of WebBrowser class.
SHDocVw.IWebBrowser2 axBrowser = typeof(WebBrowser).GetProperty("AxIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(browser, null) as SHDocVw.IWebBrowser2;
((SHDocVw.DWebBrowserEvents_Event)axBrowser).NewWindow += OnWebBrowserNewWindow;
private void OnWebBrowserNewWindow(string URL, int Flags, string TargetFrameName, ref object PostData, string Headers, ref bool Processed)
{
Processed = true;
browser.Navigate(URL);
}
WebBrowser 类有一个属性AxIWebBrowser2
,它持有底层的 COM 浏览器对象,但它是“内部的”,所以我们可以通过反射得到它。