BUG: The BeforeNavigate2 event of the WebBrowser control does not fire if hosted in a Visual Basic .NET 2002 application (311298)



The information in this article applies to:

  • Microsoft Visual Basic .NET (2002)

This article was previously published under Q311298
For a Microsoft Visual C# .NET version of this article, see 325079.

SYMPTOMS

If you sink the BeforeNavigate2 event of the WebBrowser control in a Visual Basic .NET application, the event does not fire.

RESOLUTION

To work around this problem, hook up event handlers to the non-default source interface, in this case, the DWebBrowserEvents interface. This means you have to implement the DWebBrowserEvents and its methods (of which there are 17).
    Implements SHDocVw.DWebBrowserEvents


    Public Sub BeforeNavigate(ByVal url As String, _
       ByVal flags As Integer, ByVal targetFrameName As String, _
       ByRef postData As Object, ByVal headers As String, ByRef cancel As Boolean) _
       Implements SHDocVw.DWebBrowserEvents.BeforeNavigate

        MessageBox.Show("VB DWebBrowser::BeforeNavigate event fired!", "DWebBrowser Event")

    End Sub


    Public Sub FrameNewWindow(ByVal url As String, _
    ByVal flags As Integer, ByVal targetFrameName As String, _
    ByRef postData As Object, ByVal headers As String, _
    ByRef processed As Boolean) Implements SHDocVw.DWebBrowserEvents.FrameNewWindow
    End Sub


    Public Sub DownloadComplete() Implements SHDocVw.DWebBrowserEvents.DownloadComplete
    End Sub


    Public Sub WindowMove() Implements SHDocVw.DWebBrowserEvents.WindowMove
    End Sub


    Public Sub DownloadBegin() Implements SHDocVw.DWebBrowserEvents.DownloadBegin
    End Sub


    Public Sub WindowResize() Implements SHDocVw.DWebBrowserEvents.WindowResize
    End Sub

    Public Sub CommandStateChange(ByVal command As Integer, _
    ByVal enable As Boolean) Implements SHDocVw.DWebBrowserEvents.CommandStateChange
    End Sub

    Public Sub WindowActivate() Implements SHDocVw.DWebBrowserEvents.WindowActivate
        MessageBox.Show("DWebBrowser::WindowActivate event fired!", "DWebBrowser Event")
    End Sub

    Public Sub ProgressChange(ByVal Progress As Integer, ByVal ProgressMax As Integer) _
    Implements SHDocVw.DWebBrowserEvents.ProgressChange

    End Sub


    Public Sub StatusTextChange(ByVal text As String) _
    Implements SHDocVw.DWebBrowserEvents.StatusTextChange

    End Sub

    Public Sub TitleChange(ByVal text As String) Implements SHDocVw.DWebBrowserEvents.TitleChange
    End Sub

    Public Sub FrameBeforeNavigate(ByVal url As String, _
    ByVal flags As Integer, ByVal targetFrameName As String, _
    ByRef postData As Object, ByVal headers As String, ByRef cancel As Boolean) _
    Implements SHDocVw.DWebBrowserEvents.FrameBeforeNavigate

    End Sub

    Public Sub FrameNavigateComplete(ByVal url As String) _
    Implements SHDocVw.DWebBrowserEvents.FrameNavigateComplete

    End Sub

    Public Sub Quit(ByRef Cancel As Boolean) _
    Implements SHDocVw.DWebBrowserEvents.Quit

    End Sub

    Public Sub PropertyChange(ByVal myProperty As String) _
    Implements SHDocVw.DWebBrowserEvents.PropertyChange

    End Sub

    Public Sub NewWindow(ByVal url As String, _
    ByVal flags As Integer, ByVal targetFrameName As String, _
    ByRef postData As Object, ByVal headers As String, ByRef processed As Boolean) _
     Implements SHDocVw.DWebBrowserEvents.NewWindow

    End Sub

    Public Sub NavigateComplete(ByVal url As String) _
    Implements SHDocVw.DWebBrowserEvents.NavigateComplete

    End Sub
				
COM classes advertise that they support events by implementing an interface named IConnectionPointContainer, and by returning connection point objects by means of this interface. Connection point objects, which implement IConnectionPoint, are provided by the connectable objects, representing a collection of events.

The System.Runtime.InteropServices namespace defines common COM interfaces, such as IConnectionPointContainer and IConnectionPoint. These definitions can be confusing because each interface has been renamed with the prefix "UCOM" added. The "U" indicates unmanaged; "COM" indicates that the interface is originally defined in COM.

Under InteropServices, the IConnectionPointContainer and IConnectionPoint interfaces are defined as follows:
  • UCOMIConnectPointContainer
  • UCOMIConnectionPoint
Although the names of the interfaces are different, COM recognizes no difference between a "UCOM" interface and its corresponding unmanaged definition.

When developing code, you must do the following:
  • Obtain the IConnectionPointContainer interface.
    Private icp As UCOMIConnectionPoint
    Dim icpc As UCOMIConnectionPointContainer = CType(AxWebBrowser1.GetOcx(), UCOMIConnectionPointContainer)
    					
  • Obtain the IConnectionPoint interface for a specified IID (event interface they want to subscribe to) by using the IConnectionPointContainer::FindConnectinPoint method.
    Dim g As New Guid("EAB22AC2-30C1-11CF-A7EB-0000C05BAE0B")
    icpc.FindConnectionPoint(g, icp)
    					
  • Use the IConnectionPoint::Advise method to establish a connection between the connection point object and the client's sink.
    icp.Advise(Me, cookie)
    					
  • Use the IConnectionPoint::Unadvise method to disconnect a connection between the connection point object and the client's sink.
    icp.Unadvise(cookie);
    					

Visual Basic .NET Sample Code

Paste the following code into a Visual Basic .NET Windows form module:
Imports System.ComponentModel
Imports System.Collections
Imports System.Runtime.InteropServices
Imports System.Drawing

Public Class Form1
    Inherits System.Windows.Forms.Form

    Implements SHDocVw.DWebBrowserEvents

    Private icp As UCOMIConnectionPoint
    Dim cookie As Integer = -1


#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        Dim icpc As UCOMIConnectionPointContainer = _
        CType(AxWebBrowser1.GetOcx(), UCOMIConnectionPointContainer)

        Dim g As New Guid("EAB22AC2-30C1-11CF-A7EB-0000C05BAE0B")
        icpc.FindConnectionPoint(g, icp)
        icp.Advise(Me, cookie)
        AxWebBrowser1.Navigate2("http://www.microsoft.com")

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
                If cookie = -1 Then
                    icp.Unadvise(cookie)
                Else
                    cookie = -1

                End If
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer.
    Private components As System.ComponentModel.IContainer

    'NOTE The following procedure is required by the Windows Form Designer.
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents AxWebBrowser1 As AxSHDocVw.AxWebBrowser
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Dim resources As System.Resources.ResourceManager = _
        New System.Resources.ResourceManager(GetType(Form1))

        Me.AxWebBrowser1 = New AxSHDocVw.AxWebBrowser()
        CType(Me.AxWebBrowser1, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'AxWebBrowser1
        '
        Me.AxWebBrowser1.Enabled = True
        Me.AxWebBrowser1.Location = New System.Drawing.Point(8, 8)
        Me.AxWebBrowser1.OcxState = _
        CType(resources.GetObject("AxWebBrowser1.OcxState"), System.Windows.Forms.AxHost.State)

        Me.AxWebBrowser1.Size = New System.Drawing.Size(392, 248)
        Me.AxWebBrowser1.TabIndex = 0
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(416, 269)
        Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.AxWebBrowser1})
        Me.Name = "Form1"
        Me.Text = "Form1"
        CType(Me.AxWebBrowser1, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)

    End Sub

#End Region

    Public Sub BeforeNavigate(ByVal url As String, _
       ByVal flags As Integer, ByVal targetFrameName As String, _
       ByRef postData As Object, ByVal headers As String, ByRef cancel As Boolean) _
       Implements SHDocVw.DWebBrowserEvents.BeforeNavigate

        MessageBox.Show("VB DWebBrowser::BeforeNavigate event fired!", "DWebBrowser Event")

    End Sub


    Public Sub FrameNewWindow(ByVal url As String, _
    ByVal flags As Integer, ByVal targetFrameName As String, _
    ByRef postData As Object, ByVal headers As String, _
    ByRef processed As Boolean) Implements SHDocVw.DWebBrowserEvents.FrameNewWindow
    End Sub


    Public Sub DownloadComplete() Implements SHDocVw.DWebBrowserEvents.DownloadComplete
    End Sub


    Public Sub WindowMove() Implements SHDocVw.DWebBrowserEvents.WindowMove
    End Sub


    Public Sub DownloadBegin() Implements SHDocVw.DWebBrowserEvents.DownloadBegin
    End Sub


    Public Sub WindowResize() Implements SHDocVw.DWebBrowserEvents.WindowResize
    End Sub

    Public Sub CommandStateChange(ByVal command As Integer, _
    ByVal enable As Boolean) Implements SHDocVw.DWebBrowserEvents.CommandStateChange
    End Sub

    Public Sub WindowActivate() Implements SHDocVw.DWebBrowserEvents.WindowActivate
        MessageBox.Show("DWebBrowser::WindowActivate event fired!", "DWebBrowser Event")
    End Sub

    Public Sub ProgressChange(ByVal Progress As Integer, ByVal ProgressMax As Integer) _
    Implements SHDocVw.DWebBrowserEvents.ProgressChange

    End Sub


    Public Sub StatusTextChange(ByVal text As String) _
    Implements SHDocVw.DWebBrowserEvents.StatusTextChange

    End Sub

    Public Sub TitleChange(ByVal text As String) Implements SHDocVw.DWebBrowserEvents.TitleChange
    End Sub

    Public Sub FrameBeforeNavigate(ByVal url As String, _
    ByVal flags As Integer, ByVal targetFrameName As String, _
    ByRef postData As Object, ByVal headers As String, ByRef cancel As Boolean) _
    Implements SHDocVw.DWebBrowserEvents.FrameBeforeNavigate

    End Sub

    Public Sub FrameNavigateComplete(ByVal url As String) _
    Implements SHDocVw.DWebBrowserEvents.FrameNavigateComplete

    End Sub

    Public Sub Quit(ByRef Cancel As Boolean) _
    Implements SHDocVw.DWebBrowserEvents.Quit

    End Sub

    Public Sub PropertyChange(ByVal myProperty As String) _
    Implements SHDocVw.DWebBrowserEvents.PropertyChange

    End Sub

    Public Sub NewWindow(ByVal url As String, _
    ByVal flags As Integer, ByVal targetFrameName As String, _
    ByRef postData As Object, ByVal headers As String, ByRef processed As Boolean) _
     Implements SHDocVw.DWebBrowserEvents.NewWindow

    End Sub

    Public Sub NavigateComplete(ByVal url As String) _
    Implements SHDocVw.DWebBrowserEvents.NavigateComplete

    End Sub

End Class
				

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

MORE INFORMATION

A supported fix is now available from Microsoft. For additional information about this fix, click the article number below to view the article in the Microsoft Knowledge Base:

327135 BeforeNavigate2 Event of WebBrowser Control Does Not Fire

Steps to Reproduce the Behavior

  1. Start Visual Studio .NET.
  2. Create a new Visual Basic .NET Windows Application project.
  3. Right-click in the Toolbox window, and then click Customize Toolbox.
  4. On the COM Components tab, select the Microsoft Web Browser check box.

    Notice that the WebBrowser control is added to the Controls tab in the toolbox that you chose to customize from.
  5. Drag the WebBrowser control from the toolbox to the Visual Basic form.
  6. Double-click the form, and then add the following code in the Form New event:
    AxWebBrowser1.Navigate2("http://www.msn.com")
    					
  7. In the Code window, notice the drop-down list boxes. In the first list, click AxWebBrowser1. In the second list, click BeforeNavigate2.
  8. Add the following code to the AxWebBrowser1_BeforeNavigate2 event:
    MessageBox.Show("BeforeNavigate2 event fired")
    					
  9. On the Debug menu, click Start to run the code. Alternatively, you can press F5 to run the code.

    Notice that the WebBrowser control opens the Microsoft Web site. However, notice that the BeforeNavigate2 event does not fire before it browses to the Microsoft Web site.

REFERENCES

325079 BUG: The BeforeNavigate2 Event of WebBrowser Control Does Not Fire If Hosted in C# .NET Application

IConnectionPointContainer Interface

IConnectionPoint Interface

UCOMIConnectionPointContainer Interface

UCOMIConnectionPoint Interface

Modification Type:MinorLast Reviewed:9/14/2005
Keywords:kbvs2002sp1sweep kbCtrlCreate kbEvent kbbug kbCOMInterop kbCtrl kbpending kbWebBrowser KB311298