I'm trying to get at the Close event of the .NET WebBrowser type, which doesn't seem to work out of the box. (EDIT: This event is emitted when the window.close()
call is issued in a script running in the browser.)
One solution I've seen is to extend the WebBrowser
class and override
the WndProc
method.
My extension code is as follows:
type internal ExtendedBrowser () = class
inherit System.Windows.Forms.WebBrowser()
let WM_PARENTNOTIFY : int = 0x0210
let WM_DESTROY : int = 0x0002
let closed : Event<unit> = new Event<unit>()
do ()
[<System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")>]
override this.WndProc (msg : Message byref) =
match msg.Msg with
| wm when wm = WM_PARENTNOTIFY ->
if (not base.DesignMode) && (msg.WParam.ToInt32() = WM_DESTROY)
then closed.Trigger()
base.DefWndProc(ref msg)
| _ ->
base.WndProc(ref msg)
member this.Closed = closed.Publish
end
This ends up causing an exception to be thrown when an instance of the type is accessed:
Unhandled Exception: System.Reflection.TargetInvocationException: Unable to get the window handle for the 'ExtendedBrowser' control. Windowless ActiveX controls are not supported. ---> System.ComponentModel.Win32Exception: Error creating window handle.
at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.WebBrowserBase.DoVerb(Int32 verb)
at System.Windows.Forms.WebBrowserBase.TransitionFromRunningToInPlaceActive()
--- End of inner exception stack trace ---
at System.Windows.Forms.WebBrowserBase.TransitionFromRunningToInPlaceActive()
at System.Windows.Forms.WebBrowserBase.TransitionUpTo(AXState state)
at System.Windows.Forms.WebBrowser.get_AxIWebBrowser2()
at System.Windows.Forms.WebBrowser.PerformNavigate2(Object& URL, Object& flag
s, Object& targetFrameName, Object& postData, Object& headers)
at System.Windows.Forms.WebBrowser.Navigate(String urlString)
at [PRODUCT].Application.WebBrowser..ctor() in C:\[PATH]\WebBrowser.fs:line 107
at Program.Main.main(String[] args) in C:\[PATH]\Program.fs:line 79
Press any key to continue . . .
Currently it's erroring on a call to Navigate("about:blank")
(the first access of the instance after its construction). I can comment out the WndProc
override and things work fine (besides missing the close event).
Someone said you had to put the security attribute on the WndProc
override so I did that and it didn't fix things.
Someone else said you can disable the DEP, but I tried and it didn't let me exempt the EXE.
An instance of the extension is being created in a wrapper for the browser (also called WebBrowser) and an instance of this is being created in my main
, which is runing in an [STAThread] (which also seems to be required).
Does anyone know what could be going wrong?
(What I'm really after is a way to get notification of the close event, so if someone knows an alternate route to that I'd be happy to hear it.)
If you want to be notified when the WebBrowser
control is closed, you might be able to create an instance of the normal WebBrowser
class and add an event handler to the HandleDestroyed
event -- it's fired when the form/control containing your instance of WebBrowser
is closed.
If that doesn't work, you can try casting the Parent
property to Form
and hooking the FormClosing
event; see here for an example of both techniques: HandleDestroyed event in userControl
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With