我正在尝试使用 WebBrowser 控件为弹出窗口启动一个新表单,而不是在 IE 中打开。我尝试使用AxWebBrowser来获取与NewWindow3事件一起使用的弹出窗口,并且只是做e.ppDisp = AxWebBrowser.Application
,但是AxWebBrowser有很多限制。因此,我正在尝试扩展普通的WebBrowser以包含NewWindow3事件,例如AxWebBrowser,但遇到了问题。e.ppDisp = AxWebBrowser.Application
我收到错误:"检测到无效变体",然后是"指定的 OLE 变体无效",如果我继续。
注意:这是我第一次扩展类,所以我可以忽略一些简单的东西。如果我尝试在新窗口中导航到新 URL,则会从站点收到 java 脚本错误。
我已经根据注释更新了代码库。删除了扩展WebBrowser类,以获得更小更好的版本。以下是新代码:
从主窗体和非常相似的浏览器弹出窗体 -
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">
你是对的,WindowClosing
不会因为Winforms WebBrowser
Control而被解雇,我确认这一点。这似乎是 .NET WebBrowser
ActiveX 托管代码中的一个长期错误,但从未得到解决。查看这篇文章以获取更多详细信息和可能的解决方法。
另一种可能的解决方法可能是直接通过类托管 Web 浏览器 ActiveX 控件AxHost
在这种情况下,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