How To: Capture the NewWindow2 Event from a Managed WebBrowser Control

The articles referenced in my post Internet Explorer WebBrowser Control loses state... discusses sinking this event by adding an unmanaged version of the WebBrowser control to your Form and using that.  But what if you want to use the Managed version?  The manged version of the WebBrowser control is really a wrapper around the unmanaged version of the control and has some neat features like automatically docking to the form.

High level concept:

All you would need to do to accomplish this is access the contained unmanaged WebBrowser control and sink the Event Interface you want!  In this particular case I want to get the NewWindow2 event from the control so I can pop-up any new windows in my customer WebBrowser Form.  If you know COM this should be a simple enough concept, but the implementation may be same to you.

Step By Step:

Standard disclaimers apply here (see the top of this page) and you MUST test this solution out, add exception handling and use better named variables :-).  This example is for Visual Studio 2005 and Visual Basic .NET.  It assumes you have created a new Visual Basic Project.  You should be able to figure out how to add this to your existing project if you first go through the steps of creatng a simple project following these steps.

Add the unmanaged WebBrowser control to your Form in order to get a reference to the COM Interfaces of this control:

1.  In the design view of the form that was created, Right Click on the Toolbox and from the context menu select 'Choose Items...'
Click on the 'COM Components' Tab, scroll down and select ‘Microsoft Web Browser’ (Note you may already have this in your toolbox under the 'General' section of the toolbox).

2.  Hit OK and get back to the design view of your form.

3.  Expand the General Section of the Toolbox and drag the WebBrowser from there (IMPORTANT: NOT FROM THE COMMON CONTROLS SECTION) onto your form.  This creates a reference to the Unmanaged WebBrowser Type information in your project.

4.  Now remove the control from the form.  Simply delete the control you just dragged onto the form.

Add the Managed version of the WebBrowser control to your form:

5.  Add the .NET WebBrowser Control to your form (IMPORTANT:  This control is located in the ‘Common Controls’ Section of the toolbox NOT THE ONE YOU ADDED TO THE General Section).  Simply drag the control onto the form.  You can tell this is the managed version of the control because it will autosize to the form boundaries unlike the unmanaged version of the control.

Now wire everything up:

6.  ‘View Code’ of your form (F7).

7.  Right under the class definition for your form add the code to implement the interface that will implement the interface that contains the NewWindow2 event sink: 
Implements SHDocVw.DWebBrowserEvents2

8.  Hit the ‘Enter’ key at the end of the line ‘Implements SHDocVw.DWebBrowserEvents2'  and like magic the implementation for all of these events will populate in your Form code.

9.  Add the Variable used for the ConnectionPoint the events will Sink on:
Private icp As System.Runtime.InteropServices.ComTypes.IConnectionPoint

10.  Finally add the Variable to Track the particular Sink you are setting up:
Private cookie As Integer = -1

Now you need to wire up the Form to the Event Interface you are implementing (DWebBrowserEvents2):

11.  In the code window select from the left drop down box the ‘(Form1 Events)’ (or whatever the name of your form is) and select the ‘Shown’ event and add this code inside that event handler (beware of the lines wrapping in this section):
' Connection point container from the Native WebBrowser
Dim icpc As System.Runtime.InteropServices.ComTypes.IConnectionPointContainer = CType(Me.WebBrowser1.ActiveXInstance, System.Runtime.InteropServices.ComTypes.IConnectionPointContainer)

' Get the Browser events Guid
Dim g As Guid = GetType(SHDocVw.DWebBrowserEvents2).GUID

' Find the CP
icpc.FindConnectionPoint(g, icp)

' Start getting events
icp.Advise(Me, cookie)

12.  Make sure you unregister the event sink.  Do this in the Form1_Disposed event.  Create this event the same way you did the 'Shown' Event
Try
    If cookie <> -1 Then
        icp.Unadvise(cookie)
    End If

    cookie = -1

Catch ex As Exception

End Try

13.  Now you can go down to the NewWindow2 event and add this code to pop up a Window that will be able to share cookies from the current browser session:
'Create a new form that has a Managed WebBrowser Control

Dim frmWB As Form1
frmWB = New Form1()

' Show it
frmWB.Visible = True

frmWB.WebBrowser1.ActiveXInstance.RegisterAsBrowser = True

' Set the application so we share cookies with this new instance
ppDisp = frmWB.WebBrowser1.ActiveXInstance.Application