Allow popups in WPF WebBrowser

血红的双手。 提交于 2019-12-24 04:01:49

问题


Is there a way to allow popups within embedded WPF WebBrowser control? I didn't manage to find someone elses solution, nor COM interface which enables allowing popups.

I wouldn't like to change users registry settings or use similar invasive methods, as application is intended to be distributed through ClickOnce.


回答1:


You can implement custom popups by handling NewWindow2 or NewWindow3 events sourced by the underlying WebBrowser ActiveX control. Below is a very basic example of how to do this. It can be further improved with a re-usable WebBrowser-based control, to support popups from popups.

Updated to address the comment. To disable the built-in pop-up blocker, you need to implement WebBrowser Feature Control for FEATURE_WEBOC_POPUPMANAGEMENT. You do need to access Registry.CurrentUser hive, but that doesn't require admin rights. The code below shows how to do it.

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

According to the docs, the pop-up blocker can also be disabled with CoInternetSetFeatureEnabled and FEATURE_WEBOC_POPUPMANAGEMENT, via p/invoke. I haven't tried that venue myself.



来源:https://stackoverflow.com/questions/21470192/allow-popups-in-wpf-webbrowser

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!