Http Client Protocol Issues

If you use any of these solutions, Please let me know so I can track if any of this is useful to you! Thanks! This is an area to share observations I have made working with Http Client Protocols and the associated technologies. I currently work for the Microsoft team that supports the WinInet, WinHTTP and System.Net API's and classes associated with these technologies. This is not a replacement for Microsoft Support, but an area to discuss these technologies. These postings are provided "AS IS" with no warranties, and confer no rights. Use of included code samples are subject to the terms specified at Microsoft - Information on Terms of Use

How To: Close the Form hosting the WebBrowser control when scripting calls window.close in the .Net Framework version 2.0

By design the WebBrowser Control does not close the parent Form when WebBrowser Control is closed.  Here is one way you can accomplish this.

The WebBrowser will send a WM_NOTIFYPARENT notification that can be captured and an event raised that a host can respond to.

Here is the documentation on the WM_NOTIFYPARENT notification:  http://msdn2.microsoft.com/en-us/library/ms632638.aspx

In this case we care about when the WebBrowser is closed, so we will respond to the wParam WM_DESTROY only.  Since I am going to override the WebBrowser control for other purposes, I will simply add an event to this control that any Form can act on.

First define a new VB Windows Project.  Drag and drop the WebBrowser Control onto your form from the Common Controls section of the Toolbox.

Next we want to extend the WebBrowser control so we can process the WndProc function.  Create a new Class(Add, Class) and call it MyExtendedBrowserControl.

Public Class MyExtendedBrowserControl
' Based on WebBrowser
Inherits System.Windows.Forms.WebBrowser

' Define constants from winuser.h
Private Const WM_PARENTNOTIFY As Integer = &H210
Private Const WM_DESTROY As Integer = 2

'Define New event to fire
Public Event WBWantsToClose()

Protected Overrides Sub WndProc(ByRef m As Message)
    Select Case m.Msg
        Case WM_PARENTNOTIFY
            If (Not DesignMode) Then
                If (m.WParam = WM_DESTROY) Then
                    ' Tell whoever cares we are closing
                    RaiseEvent WBWantsToClose()
                End If
            End If
            DefWndProc(m)
        Case Else
            MyBase.WndProc(m)
    End Select
End Sub

End Class

Now we have to get into the guts of the Form.  Although we dropped a WebBrowserControl on the form (and VB wired that up nicely for us) we REALLY want to create our new Control that extends the WebBrowser Control.

Choose File, Open from the Visual Studio menu and open the designer vb code (in this case Form1.Designer.vb).

Replace System.Windows.Forms.WebBrowser with the extended control MyExtendedBrowserControl.  There should be Two Places:

Me.WebBrowser1 = New VBCloseBrowser.ExtendedWebBrowser.ExtendWebBrowser

Friend WithEvents WebBrowser1 As VBCloseBrowser.ExtendedWebBrowser.ExtendWebBrowser

Save all the files and Build the project (you will see errors in the designers until you do build).

Now go to the design view of your Form.  Right Click on the Browser control and choose Properties…  Click on the Events Icon (the lightning bolt) and you will see at the bottom your new event WBWantsToClose.  Double click on that name and you will automatically add the handler for that event.  In my case, I simply want to close this form so I added Me.Close() in the handler.

Enjoy!

Published Friday, May 25, 2007 11:01 AM by jpsanders
Filed under:

Comments

 

NeilS said:

Jeff - following on from your NewWindow2 event capture in a managed web browser article - again this was really helpful.

November 6, 2007 2:05 PM
 

disccomp said:

I am using an extendedwebbrowser, Your code almost ties up the last loose end. The only trouble is the closing event fires after windows asks whether to close the window after window.close is called from a script.

---------------------------------

Imports System.Runtime

Imports System.ComponentModel

'Extend the WebBrowser control

Public Class ExtendedWebBrowser

   Inherits WebBrowser

   Private cookie As AxHost.ConnectionPointCookie

   Private events As WebBrowserExtendedEvents

   Private Const WM_PARENTNOTIFY As Integer = &H210

   Private Const WM_DESTROY As Integer = 2

   'Define New event to fire

   Public Event WindowClosing()

   Protected Overrides Sub WndProc(ByRef m As Message)

       Select Case m.Msg

           Case WM_PARENTNOTIFY

               If (Not DesignMode) Then

                   If (m.WParam = WM_DESTROY) Then

                       ' Tell whoever cares we are closing

                       RaiseEvent WindowClosing()

                   End If

               End If

               DefWndProc(m)

           Case Else

               MyBase.WndProc(m)

       End Select

   End Sub

   'This method will be called to give you a chance to create your own event sink

   Protected Overloads Overrides Sub CreateSink()

       'MAKE SURE TO CALL THE BASE or the normal events won't fire

       MyBase.CreateSink()

       events = New WebBrowserExtendedEvents(Me)

       cookie = New AxHost.ConnectionPointCookie(Me.ActiveXInstance, events, GetType(DWebBrowserEvents2))

   End Sub

   Protected Overloads Overrides Sub DetachSink()

       If cookie IsNot Nothing Then

           cookie.Disconnect()

           cookie = Nothing

       End If

       MyBase.DetachSink()

   End Sub

   'This new event will fire when the page is navigating

   Public Event NewWindowWithTaget As EventHandler(Of WebBrowserExtendedNavigatingEventArgs)

   Protected Sub OnNewWindow3(ByVal url As String, ByVal e As WebBrowserExtendedNavigatingEventArgs)

       RaiseEvent NewWindowWithTaget(Me, e)

   End Sub

   'This class will capture events from the WebBrowser

   Private Class WebBrowserExtendedEvents

       Inherits System.Runtime.InteropServices.StandardOleMarshalObject

       Implements DWebBrowserEvents2

       Private _Browser As ExtendedWebBrowser

       Public Sub New(ByVal browser As ExtendedWebBrowser)

           _Browser = browser

       End Sub

       Public Sub NewWindow3(ByVal pDisp As Object, ByRef cancel As Boolean, ByRef flags As Object, ByRef hostURL As Object, ByRef URL As Object) Implements DWebBrowserEvents2.NewWindow3

           Dim args As New WebBrowserExtendedNavigatingEventArgs(URL)

           args.Cancel = cancel

           _Browser.OnNewWindow3(URL, args)

           cancel = args.Cancel

       End Sub

   End Class

   <InteropServices.ComImport(), InteropServices.Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D"), InteropServices.InterfaceTypeAttribute(InteropServices.ComInterfaceType.InterfaceIsIDispatch), InteropServices.TypeLibType(InteropServices.TypeLibTypeFlags.FHidden)> _

   Public Interface DWebBrowserEvents2

       <InteropServices.DispId(273)> _

       Sub NewWindow3(ByVal pDisp As Object, ByRef cancel As Boolean, ByRef flags As Object, ByRef hostURL As Object, ByRef URL As Object)

   End Interface

End Class

Public Class WebBrowserExtendedNavigatingEventArgs

   Inherits CancelEventArgs

   Private _Url As String

   Public Sub New(ByVal url As String)

       _Url = url

   End Sub

   Public ReadOnly Property Url() As String

       Get

           Return _Url

       End Get

   End Property

End Class

February 13, 2008 3:32 PM
Anonymous comments are disabled

© 2008 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker