2014-01-31 4 views
2

Есть ли способ разрешить всплывающие окна внутри встроенного элемента управления WPF WebBrowser? Мне не удалось найти какое-то решение elses, а не COM-интерфейс, который позволяет разрешать всплывающие окна.Разрешить всплывающие окна в WPF WebBrowser

Я бы не хотел менять параметры реестра пользователей или использовать аналогичные инвазивные методы, поскольку приложение предназначено для распространения через ClickOnce.

ответ

3

Вы можете реализовать пользовательские всплывающие окна, обработав NewWindow2 или NewWindow3 событиями, полученными от основного элемента управления ActiveX WebBrowser. Ниже приведен очень простой пример того, как это сделать. Его можно дополнительно улучшить с помощью повторно используемого элемента управления WebBrowser, чтобы поддерживать всплывающие окна из всплывающих окон.

Обновлено, чтобы ответить на комментарий. Чтобы отключить встроенный блокировщик всплывающих окон, вам необходимо реализовать функцию управления функциями WebBrowser для FEATURE_WEBOC_POPUPMANAGEMENT. Вам нужно получить доступ к улью 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); 
     } 
    } 
} 

Согласно документации, то блокировка всплывающих окон также может быть отключен с CoInternetSetFeatureEnabled и FEATURE_WEBOC_POPUPMANAGEMENT, через р/вызова. Я сам не пробовал это место.

+0

Это может быть полезным фрагментом для меня, но, к сожалению, не решает эту проблему. Ни события NewWindow2, ни события NewWindow3 не срабатывают, когда страница пытается открыть всплывающее окно. Всплывающее окно блокирует удары, прежде чем переходить на всплывающую страницу, и новые события окна никогда не происходят. Если я отключу блокировщик всплывающих окон в IE, они нормально срабатывают. Для записи я использую Windows 8.1 и IE11, поэтому поведение может отличаться для более старых версий. –

+0

@ NikolaRadosavljević, проверьте обновленный ответ. – Noseratio

+0

Спасибо. Я не смогу использовать это, к сожалению, потому что, как я уже сказал, мне не разрешено связываться с настройками конечных пользователей (изменения реестра), но я соглашусь с этим, поскольку это может помочь людям, у которых нет такого ограничения. –

Смежные вопросы