2014-01-31 55 views
2

有没有办法允许弹出内嵌WPF WebBrowser控制?我没有设法找到别人的解决方案,也没有COM接口,它允许弹出窗口。允许弹出窗口在WPF WebBrowser

我不想更改用户注册表设置或使用类似的侵入方法,因为应用程序旨在通过ClickOnce分发。

回答

3

您可以通过处理底层WebBrowser ActiveX控件产生的NewWindow2NewWindow3事件来实现自定义弹出窗口。以下是如何做到这一点的一个非常基本的例子。可以通过基于可重复使用的WebBrowser控件进一步改进,以支持弹出窗口的弹出窗口。

更新以解决评论。要禁用内置弹出窗口阻止程序,您需要为FEATURE_WEBOC_POPUPMANAGEMENT实施WebBrowser功能控件。您确实需要访问Registry.CurrentUser配置单元,但这不需要管理员权限。下面的代码显示了如何做到这一点。

using System.Reflection; 
using System.Windows; 
using System.Windows.Controls; 
using System.Runtime.InteropServices; 
using System.Diagnostics; 
using Microsoft.Win32; 


namespace WpfWbApp 
{ 
    public partial class MainWindow : Window 
    { 
     WebBrowser webBrowser; 

     public MainWindow() 
     { 
      SetBrowserFeatureControl(); 

      InitializeComponent(); 

      this.webBrowser = new WebBrowser(); 
      this.Content = this.webBrowser; 

      this.Loaded += MainWindow_Loaded; 
     } 

     void MainWindow_Loaded(object sender, RoutedEventArgs e) 
     { 
      var axWebBrowser = (SHDocVw.WebBrowser)GetActiveXInstance(this.webBrowser); 
      axWebBrowser.NewWindow2 += axWebBrowser_NewWindow2; 

      this.webBrowser.Navigate("http://example.com"); 
     } 

     void axWebBrowser_NewWindow2(ref object ppDisp, ref bool Cancel) 
     { 
      var window = new Window { Width = 400, Height = 300 }; 
      var newWebBrowser = new WebBrowser(); 
      window.Content = newWebBrowser; 
      window.Show(); 
      ppDisp = GetActiveXInstance(newWebBrowser); 
     } 

     /// <summary> 
     /// Get the underlying WebBrowser ActiveX object; 
     /// this code depends on SHDocVw.dll COM interop assembly, 
     /// generate SHDocVw.dll: "tlbimp.exe ieframe.dll", 
     /// and add as a reference to the project 
     /// </summary> 
     static object GetActiveXInstance(WebBrowser browser) 
     { 
      var document = browser.Document; 

      return browser.GetType().InvokeMember("ActiveXInstance", 
       BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic, 
       null, browser, new object[] { }) as SHDocVw.WebBrowser; 
     } 

     /// <summary> 
     /// SetBrowserFeatureControlKey 
     /// </summary> 
     static void SetBrowserFeatureControlKey(string feature, string appName, uint value) 
     { 
      using (var key = Registry.CurrentUser.CreateSubKey(
       string.Concat(@"Software\Microsoft\Internet Explorer\Main\FeatureControl\", feature), 
       RegistryKeyPermissionCheck.ReadWriteSubTree)) 
      { 
       key.SetValue(appName, (uint)value, RegistryValueKind.DWord); 
      } 
     } 

     /// <summary> 
     /// SetBrowserFeatureControl 
     /// </summary> 
     static void SetBrowserFeatureControl() 
     { 
      // http://msdn.microsoft.com/en-us/library/ee330720(v=vs.85).aspx 

      // FeatureControl settings are per-process 
      var fileName = System.IO.Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName); 

      // make the control is not running inside Visual Studio Designer 
      if (string.Compare(fileName, "devenv.exe", true) == 0 || string.Compare(fileName, "XDesProc.exe", true) == 0) 
       return; 

      // Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode. 
      SetBrowserFeatureControlKey("FEATURE_BROWSER_EMULATION", fileName, 10000); 

      // Web Browser Control Popup Management 
      SetBrowserFeatureControlKey("FEATURE_WEBOC_POPUPMANAGEMENT", fileName, 0); 
     } 
    } 
} 

根据该文档,在弹出窗口阻止也可以与CoInternetSetFeatureEnabledFEATURE_WEBOC_POPUPMANAGEMENT禁用,通过P /调用。我没有尝试过这个场地。

+0

这对我来说可能是有用的代码片段,但不幸的是不能解决这个特定的问题。当页面尝试打开弹出窗口时,“NewWindow2”和“NewWindow3”事件都不会启动。在尝试导航到弹出页面之前弹出窗口阻止了踢球,并且从未发生新的窗口事件。如果我在IE中禁用弹出窗口阻止程序,它们会正确启动。为了记录,我使用Windows 8.1和IE11,因此旧版本的行为可能会有所不同。 –

+0

@NikolaRadosavljević,检查更新的答案。 – Noseratio

+0

谢谢。我不能很好地使用它,因为正如我所说的,我不允许混淆最终用户设置(注册表修改),但我会接受这一点,因为它可以帮助那些没有这种限制的人。 –