WebBrowserコントロールにはWindowClosingイベントがありません。そのため,スクリプトのwindow.close()が検知できず,しかもwindow.close()を実行されると無反応になってしまいます。 NewWindow2イベントの拡張と同様の方法でWindowClosingイベントの実装を試みましたが,実装方法に問題があるのか動作しません。そこでウィンドウメッセージWM_PARENTNOTIFYで子ウィンドウの破棄を検知し,そのタイミングでWindowClosingイベントを発生するようにしました。 この方法でwindow.close()を検知し,アプリケーションを適切に閉じることができるようになります。しかし,この方法はwindow.close()をキャンセルすることができません。イベントを無視しても,WebBrowserコントロールは破棄され,無反応となります。
下のコードをフォームのコードにコピー・貼り付けをすれば動作します。
Option Explicit On
Option Strict On
Imports System.Runtime.InteropServices
Public Class Form1
Dim WithEvents WebBrowser As New ExWebBrowser
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.WebBrowser.Dock = DockStyle.Fill
Me.Text = "WebBrowserWindowClosingEventSample"
Me.Controls.Add(Me.WebBrowser)
Me.WebBrowser.DocumentText = "<!DOCTYPE html>" &
"<html >" &
"<body>" &
"<input type=""button"" value=""ウィンドウを閉じる"" onclick=""window.close();"" />" &
"</body>" &
"</html>"
End Sub
Private Sub WebBrowser_WindowClosing(ByVal sender As Object, ByVal e As EventArgs) Handles WebBrowser.WindowClosing
MessageBox.Show("ウィンドウを閉じます", "WindowClosingイベント発生", MessageBoxButtons.OK, MessageBoxIcon.Information)
Me.Close()
End Sub
End Class
Public Class ExWebBrowser
Inherits WebBrowser
Sub New()
MyBase.New()
End Sub
Enum GETWINDOWCMD
GW_HWNDFIRST = 0
GW_HWNDLAST = 1
GW_HWNDNEXT = 2
GW_HWNDPREV = 3
GW_OWNER = 4
GW_CHILD = 5
GW_ENABLEDPOPUP = 6
End Enum
<DllImport("user32.dll")>
Private Shared Function GetWindow(ByVal hWnd As IntPtr, ByVal uCmd As GETWINDOWCMD) As IntPtr
End Function
Public Event WindowClosing As EventHandler
Protected Overridable Sub OnWindowClosing(ByVal e As EventArgs)
RaiseEvent WindowClosing(Me, e)
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Const WM_PARENTNOTIFY = &H210
Const WM_DESTROY = &H2
If m.Msg = WM_PARENTNOTIFY Then
If m.WParam.ToInt32 = WM_DESTROY Then
If m.LParam = GetWindow(Me.Handle, GETWINDOWCMD.GW_CHILD) Then
Dim e As New EventArgs
OnWindowClosing(e)
Return
End If
End If
End If
MyBase.WndProc(m)
End Sub
End Class
※このTipsは2005年頃にNiftyの@homepageで公開していたもの一部変更して再掲載しました。
http://homepage1.nifty.com/yasunari/VB/VB2005/WebBrowserWindowClosingEvent.htm