用于处理应用程序中的弹出窗口的 Web 浏览器

Posted

技术标签:

【中文标题】用于处理应用程序中的弹出窗口的 Web 浏览器【英文标题】:Web Browser to handle pop ups within the application 【发布时间】:2013-11-06 07:57:39 【问题描述】:

我正在尝试使用 WebBrowser 控件为弹出窗口启动一个新表单,而不是在 IE 中打开它。我尝试使用 AxWebBrowser 来获取与 NewWindow3 事件一起使用的弹出窗口,并且只执行 e.ppDisp = AxWebBrowser.Application,但是 AxWebBrowser 有很多限制。因此,我试图扩展普通的 WebBrowser 以包含像 AxWebBrowser 这样的 NewWindow3 事件,但遇到了问题。使用e.ppDisp = AxWebBrowser.Application,我收到错误消息:“检测到 InvalidVariant”,如果我继续,后跟“指定的 OLE 变体无效”。

注意:这是我第一次扩展一个类,所以我可能会忽略一些简单的东西。如果我尝试在新窗口中导航到新 URL,我会从该站点收到 java 脚本错误。

我已经更新了 cmets 的代码库。已删除 ExtendedWebBrowser 类以获得更小更好的版本。这是新代码:

从主窗体和一个非常相似的 BrowserPopup 窗体 -

Protected Overrides Sub OnLoad(ByVal e As EventArgs)
    MyBase.OnLoad(e)
    nativeBrowser = DirectCast(ExtendedWebBrowser1.ActiveXInstance, SHDocVw.WebBrowser)
    AddHandler nativeBrowser.NewWindow3, AddressOf nativeBrowser_NewWindow3
    AddHandler nativeBrowser.WindowClosing, AddressOf nativeBrowser_WindowClosing
End Sub

Private Sub nativeBrowser_NewWindow3(ByRef ppDisp As Object, ByRef Cancel As Boolean, ByVal dwflags As UInteger, ByVal bStrUrlContext As String, ByVal bstrUrl As String)
    Dim popup = New BrowserPopup()
    popup.Show(Me)
    popup.browserPop.DocumentText = bStrUrlContext
    ppDisp = popup.browserPop.ActiveXInstance
End Sub

Private Sub nativeBrowser_WindowClosing(ByVal IsChildWindow As Boolean, ByRef Cancel As Boolean)
    MsgBox("working?") '<<<Doesn't Trigger>>>
End Sub

Protected Overrides Sub OnFormClosing(ByVal e As FormClosingEventArgs)
    MyBase.OnFormClosing(e)
End Sub

另外,如果有帮助,这里是页面中的脚本,它应该能够关闭弹出表单,但似乎只是停用了 WebBrowser。

<table isListBtn="false" cellpadding="0" enabled="true" class="buttonBorderBlue"
cellspacing="0" border="0" onClick="if (typeof(workpaneMediator_toolbar)!='undefined')
workpaneMediator_toolbar.onSelect('CANCEL_ACTION', this)"
actionType="CLOSE_WINDOW_TYPE" id="workpaneMediator_toolbar_CANCEL_ACTIONWrapper"
nowrap><tr><td class="buttonBlueTD">

【问题讨论】:

已回答here 用于 C#,转换为 VB 应该不成问题。 感谢您的回复!我能够转换代码并将其实现为我自己的。它现在弹出没有错误,并且在大多数情况下都正确运行脚本。但是,当单击 java 脚本按钮提交/取消弹出窗口时,Web 浏览器确实停止运行(应该如此),但弹出表单并没有消失。我正在研究,看看能不能找到任何东西。 对于 javascript 链接,请查看this one。 您为 JavaScripts 提供的链接似乎对我没有多大作用。为了清楚起见,我现在已经删除了 WebBrowserEx 类,拿起你第一次发布的项目。这成功地以新形式打开了弹出窗口,没有错误。但是,当尝试单击新表单上的提交/关闭时,WebBrowser 似乎已停用,就像被告知要关闭一样。但表单本身不会自动关闭。我尝试从 WebBrowser 检查各种事件,但如果有任何事件被调用,似乎找不到任何事件。 WindowClosing 似乎也没有引起注意。将更新我原始帖子中的代码以反映最近的更改。 【参考方案1】:

你说得对,WindowClosing 不会因为 Winforms WebBrowser 控制而被解雇,我确认这一点。这似乎是 .NET WebBrowser ActiveX 托管代码中的一个长期错误,从未得到解决。查看this post 了解更多详细信息和可能的解决方法。

另一种可能的解决方法是直接通过AxHost 类托管WebBrowser ActiveX 控件,在这种情况下WindowClosing 会正确触发。示例:

C#:

using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WebBrowserApp

    // MainForm

    public partial class MainForm : Form 
    
        WebBrowser webBrowser;

        public MainForm()
        
            InitializeComponent();
            InitBrowser();

            if (this.webBrowser.Document == null && this.webBrowser.ActiveXInstance == null)
                throw new ApplicationException ("Unable to initialize WebBrowser ActiveX control.");

            var ax = (SHDocVw.WebBrowser)this.webBrowser.ActiveXInstance;
            ax.NewWindow2 += (ref object ppDisp, ref bool Cancel) =>
            
                var popup = new RawBrowserPopup();
                popup.Visible = true;
                ppDisp = popup.WebBrowser.ActiveXInstance;
            ;

            this.Load += (s, e) =>
            
                this.webBrowser.DocumentText = "<a target=\"_blank\" href=\"javascript:'<button onclick=\\'window.close()\\'>Close</button>'\">Go</a>";
            ;
        

        // create a WebBrowser instance
        void InitBrowser()
        
            this.webBrowser = new WebBrowser();
            this.webBrowser.Dock = DockStyle.Fill;
            this.Controls.Add(this.webBrowser);
            this.webBrowser.Visible = true;
        
    

    // RawWebBrowser

    public class RawWebBrowser : AxHost
    
        public RawWebBrowser()
            : base("8856f961-340a-11d0-a96b-00c04fd705a2")
        
        

        public event EventHandler Initialized;

        protected override void AttachInterfaces()
        
            if (this.Initialized != null)
                this.Initialized(this, new EventArgs());
        

        public object ActiveXInstance
        
            get
            
                return base.GetOcx();
            
        
    

    // RawBrowserPopup

    public class RawBrowserPopup : Form
    
        RawWebBrowser webBrowser;

        public RawWebBrowser WebBrowser
        
            get  return this.webBrowser; 
        

        public RawBrowserPopup()
        
            this.webBrowser = new RawWebBrowser();

            this.webBrowser.Initialized += (s, e) =>
            
                var ax = (SHDocVw.WebBrowser)this.webBrowser.ActiveXInstance;
                ax.NewWindow2 += (ref object ppDisp, ref bool Cancel) =>
                
                    var popup = new RawBrowserPopup();
                    popup.Visible = true;
                    ppDisp = popup.WebBrowser.ActiveXInstance;
                ;

                ax.WindowClosing += (bool IsChildWindow, ref bool Cancel) =>
                
                    Cancel = true;
                    this.Close();
                ;
            ;

            this.webBrowser.Dock = DockStyle.Fill;
            this.Controls.Add(this.webBrowser);
            this.webBrowser.Visible = true;
        
    

VB.NET:

Public Class Form1
    Dim webBrowser As WebBrowser = New WebBrowser()

    Sub New()
        MyBase.New()
        Me.InitializeComponent()
        webBrowser.Dock = DockStyle.Fill
        Me.Controls.Add(webBrowser)
        webBrowser.Visible = True
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.webBrowser.DocumentText = "<a target='_blank' href='javascript:""<button onclick=\""window.close()\"">Close</button>""'>Go</a>"

        Dim ActiveX As SHDocVw.WebBrowser = Me.webBrowser.ActiveXInstance
        AddHandler ActiveX.NewWindow2, AddressOf WebBrowser_ActiveX_NewWindow2
    End Sub

    Private Sub WebBrowser_ActiveX_NewWindow2(ByRef ppDisp As Object, ByRef Cancel As Boolean)
        Dim popup As RawBrowserPopup = New RawBrowserPopup()
        popup.Visible = True
        ppDisp = popup.WebBrowser.ActiveXInstance
    End Sub
End Class

Public Class RawWebBrowser
    Inherits System.Windows.Forms.AxHost

    Sub New()
        MyBase.New("8856f961-340a-11d0-a96b-00c04fd705a2")
    End Sub

    Event Initialized(sender As Object, e As EventArgs)

    Protected Overrides Sub AttachInterfaces()
        RaiseEvent Initialized(Me, New EventArgs())
    End Sub

    Public ReadOnly Property ActiveXInstance() As Object
        Get
            Return MyBase.GetOcx()
        End Get
    End Property
End Class

Public Class RawBrowserPopup
    Inherits System.Windows.Forms.Form

    Dim WithEvents rawBrowser As RawWebBrowser = New RawWebBrowser()

    Sub New()
        MyBase.New()
        rawBrowser.Dock = DockStyle.Fill
        Me.Controls.Add(rawBrowser)
        rawBrowser.Visible = True
    End Sub

    Public ReadOnly Property WebBrowser() As Object
        Get
            Return rawBrowser
        End Get
    End Property

    Private Sub rawBrowser_Initialized(sender As Object, e As EventArgs) Handles rawBrowser.Initialized
        Dim activeX As SHDocVw.WebBrowser = rawBrowser.ActiveXInstance
        AddHandler activeX.NewWindow2, AddressOf activeX_NewWindow2
        AddHandler activeX.WindowClosing, AddressOf activeX_WindowClosing
    End Sub

    Private Sub activeX_NewWindow2(ByRef ppDisp As Object, ByRef Cancel As Boolean)
        Dim popup As RawBrowserPopup = New RawBrowserPopup()
        popup.Visible = True
        ppDisp = popup.WebBrowser.ActiveXInstance
    End Sub

    Private Sub activeX_WindowClosing(IsChildWindow As Boolean, ByRef Cancel As Boolean)
        Cancel = True
        Me.Close()
    End Sub

End Class

【讨论】:

为解决方法提供的链接显示了在 WM_LBUTTONDOWN 上发生的 ParentNotify 事件。 WM_DESTROY 似乎没有被调用。我想我可能需要学习 C#,因为我的问题的所有解决方案都可以在 C# 中使用,并且在转换为 VB.Net 时它们似乎永远无法正常工作。我可以确认您的解决方案适用于 C# 没有问题。但我似乎无法将代码正确转换为 VB.Net。 developerfusion.com 之类的网站转换不正确。具体来说,它不喜欢转换 ax.NewWindow2 += (ref object ppDisp, ref bool Cancel) =&gt;... @Congree,我发布了一个有效的 VB.NET 示例。这个问题我能帮到的就这么多了。 非常感谢您的帮助!我已经验证它在 VB.Net 中工作正常,这正是我所需要的。再次感谢!只要我有足够的代表并且网站允​​许我,我就会投票。 很高兴它有帮助。 +1 用于通过WindowClosing 报告问题。

以上是关于用于处理应用程序中的弹出窗口的 Web 浏览器的主要内容,如果未能解决你的问题,请参考以下文章

处理 SFSafariViewController 中的弹出窗口/选项卡

异常未处理的弹出窗口

如何处理Chrome Selenium网络驱动程序中的弹出窗口-Python

如何获取 Flutter Web 应用程序的弹出窗口?

iframe中的弹出窗口如何显示在最外层?

将参数传递给javascript中的弹出窗口[重复]