WPF WebBrowser中如何允许弹出窗口?

3
有没有办法在嵌入的WPF WebBrowser控件中允许弹出窗口?我没有找到别人的解决方案,也没有找到可以允许弹出窗口的COM接口。我不想改变用户的注册表设置或使用类似的侵入性方法,因为该应用程序旨在通过ClickOnce进行分发。
1个回答

4
你可以通过处理底层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);
        }
    }
}

根据文档,弹出窗口拦截器也可以通过CoInternetSetFeatureEnabledFEATURE_WEBOC_POPUPMANAGEMENT进行p/invoke禁用。我自己还没有尝试过这种方法。

这段代码对我可能有用,但不幸的是它并没有解决我遇到的具体问题。当网页试图打开一个弹出窗口时,既没有NewWindow2事件也没有NewWindow3事件被触发。在尝试导航到弹出窗口页面之前,就会启动弹出窗口阻止程序,并且新窗口事件永远不会发生。如果我在IE中禁用弹出窗口阻止程序,则可以正常触发这些事件。值得一提的是,我使用的是Windows 8.1和IE11,因此行为可能因较旧的版本而异。 - Nikola Radosavljević
谢谢。不幸的是,我不能使用这个,因为正如我所说,我不被允许干扰最终用户的设置(注册表修改),但我会接受这个,因为它可能会帮助那些没有这种限制的人。 - Nikola Radosavljević
@NikolaRadosavljević,也许还有另一种方法。尝试使用CoInternetSetFeatureEnabledFEATURE_WEBOC_POPUPMANAGEMENT,通过互操作性实现。 - noseratio - open to work
1
可以了,谢谢!我想知道是否可能会出现一些COM权限问题,但目前按照广告运作。再次感谢! - Nikola Radosavljević

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接