【问题标题】:Allow popups in WPF WebBrowser允许 WPF WebBrowser 中的弹出窗口
【发布时间】:2014-01-31 00:09:33
【问题描述】:

有没有办法在嵌入式 WPF WebBrowser 控件中允许弹出窗口?我没有设法找到其他人的解决方案,也没有找到允许弹出窗口的 COM 接口。

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

【问题讨论】:

    标签: .net wpf webbrowser-control iwebbrowser2


    【解决方案1】:

    您可以通过处理来自底层 WebBrowser ActiveX 控件的 NewWindow2NewWindow3 事件来实现自定义弹出窗口。下面是一个非常基本的示例,说明如何执行此操作。它可以通过可重复使用的基于WebBrowser 的控件进一步改进,以支持弹出窗口中的弹出窗口。

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

    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);
            }
        }
    }
    

    根据文档,弹出窗口阻止程序也可以通过 p/invoke 使用 CoInternetSetFeatureEnabledFEATURE_WEBOC_POPUPMANAGEMENT 禁用。我自己没有尝试过那个场地。

    【讨论】:

    • 这对我来说可能是有用的 sn-p,但不幸的是不能解决这个特定问题。当页面尝试打开弹出窗口时,NewWindow2NewWindow3 事件都不会触发。在尝试导航到弹出页面之前,弹出窗口被阻止启动,并且永远不会发生新窗口事件。如果我在 IE 中禁用弹出窗口阻止程序,它们会正确触发。作为记录,我使用的是 Windows 8.1 和 IE11,因此旧版本的行为可能会有所不同。
    • 谢谢。不幸的是,我将无法使用它,因为正如我所说,我不允许弄乱最终用户设置(注册表修改),但我会接受它,因为它可能会帮助没有这种限制的人。
    • @NikolaRadosavljević,可能还有另一种方式。尝试通过互操作使用CoInternetSetFeatureEnabledFEATURE_WEBOC_POPUPMANAGEMENT
    • 成功了,谢谢!我想知道是否可能会出现一些 COM 权限问题,但目前,如宣传的那样工作。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 2016-07-18
    • 1970-01-01
    • 2013-04-03
    • 2016-05-10
    相关资源
    最近更新 更多