Click here to Skip to main content
11,641,951 members (62,749 online)
Click here to Skip to main content

.NET MSIE OnBeforeNavigate2 fix

, 29 Oct 2002 179.5K 818 53
Rate this:
Please Sign up or sign in to vote.
Provides a fix to catch otherwise hidden events of MS Internet Explorer
<!-- Download Links -->

The remainder of this article provides a fix to receive otherwise hidden events such as the famous OnBeforeNavigate2 from MS Internet Explorer.

Reusing the code

Namely, if you wish to use the Internet Explorer control in a .NET app, what you usually do is go in the Toolbox Window, Customize, search for the Microsoft Web Browser Control (shdocvw.dll), drop it on a form, and start exploring the object model.

That is simple, but does not work as expected. You never get notified of several events.

If you are not interesting in the programming details, just reuse the source code. Don't be afraid of the size (54kb), it is somewhat big because there are two interop assemblies, but the real addition is just 10 lines of code. The project was obtained by doing the following:

  • dropped the Web Browser control on a form named Form1
  • added the code snippet to fix the Web Browser control (see below)
  • added a text box to manage URL typing
  • added an event handler on the TextBox to catch keyboard returns and ask IE to do a simple Navigate(url) on it.

Explanations

There is a problem when you IE in a .NET environment. Due to a .NET 1.0 limitation, marshaling cannot handle complex variant types, which are at the core of most events triggered by the DWebBrowserEvents2 dispatch interface.

Unfortunately, the OnBeforeNavigate2 event is triggered through this interface. This event is often used by programmers to be notified any time the user clicked on a link or submitted a form, providing them with very valuable information including URL, posted data, headers, and even the ability to cancel the navigation depending on the application logic.

Now we know that we can't use this event, as is.

But, by carefully watching the core Internet Explorer interfaces (by using OLEView on shdocvw.dll, or by looking at the redistributed IDL interface located in Platform SDK\Include\ExDisp.idl) we can see the DWebBrowserEvents interface (older but backward supported) provides events such as OnBeforeNavigate (note the missing 2).

Here is a extract of these interfaces in IDL:

[
  uuid(8856F961-340A-11D0-A96B-00C04FD705A2),
  helpstring("WebBrowser Control"),
  control
]
coclass WebBrowser 
{
    [default] interface IWebBrowser2; // default COM interface
    interface IWebBrowser;

    // default event source
    [default, source] dispinterface DWebBrowserEvents2; 
    [source] dispinterface DWebBrowserEvents;
};


[
  uuid(34A715A0-6587-11D0-924A-0020AFC7AC4D),
  helpstring("Web Browser Control events interface"),
  hidden
]
dispinterface DWebBrowserEvents2 
{
    properties:
    methods:

  // note the VARIANT* everywhere
  // (the VARIANT* is the heart of the issue we have)
  [id(0x000000fa)]
  void BeforeNavigate2(
                        [in] IDispatch* pDisp, 
                        [in] VARIANT* URL, 
                        [in] VARIANT* Flags, 
                        [in] VARIANT* TargetFrameName, 
                        [in] VARIANT* PostData, 
                        [in] VARIANT* Headers, 
                        [in, out] VARIANT_BOOL* Cancel);

   ...
}


[
  uuid(EAB22AC2-30C1-11CF-A7EB-0000C05BAE0B),
  helpstring("Web Browser Control Events (old)"),
  hidden
]
dispinterface DWebBrowserEvents {
    properties:
    methods:

  [id(0x00000064)]
  void BeforeNavigate(
                        [in] BSTR URL, 
                        long Flags, 
                        BSTR TargetFrameName, 
                        VARIANT* PostData, 
                        BSTR Headers, 
                        [in, out] VARIANT_BOOL* Cancel);
  ...
}

The important thing to note is that the IDL defines DWebBrowserEvents2 as the default event source, not DWebBrowserEvents. Because of that, the interop wrapper generator (tlbimp.exe) will provide us with marshaling code reflecting just that, namely AxInterop.SHDocVw.dll (ActiveX layer) and Interop.SHDocVw.dll (shdocvw.dll wrapper). As a result, if you type axWebBrowser1. (notice the dot), then intellisense will show you methods from this interface, not from DWebBrowserEvents. Casting is of no help here : the compiler would be ok, but it would fail at run-time. Looks like we are a bit stuck here.

To go on, we are actually going to ask the interop marshaler to produce at run-time a wrapper for the DWebBrowserEvents interface. Let's show some code now:

/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
    private AxSHDocVw.AxWebBrowser axWebBrowser1;
    private SHDocVw.WebBrowserClass ie_events;
    private System.Windows.Forms.TextBox textBox1;

    public Form1()
    {
        //
        // Required for Windows Form Designer support
        //
        InitializeComponent();

        // -- begin code snippet --

        ie_events = (SHDocVw.WebBrowserClass) 
                    Marshal.CreateWrapperOfType(
                        axWebBrowser1.GetOcx(),
                        typeof(SHDocVw.WebBrowserClass)
                    );

        // -- end code snippet --

        ...
    }
}

The CreateWrapperOfType call performs the magic of creating an RCW (layer to execute COM interfaces and methods) for us. Instead of passing the SHDocVw.DWebBrowserEvents interface type we want, we pass the SHDocVw.WebBrowserClass instead. Why ? That's a trick again, the marshaler expects a coclass type to build the RCW, instead of a simple interface. WebBrowserClass is the .NET name of coclass WebBrowser declared in the IDL.

The resulting RCW is stored in a member of our Form. Now we have the right interface to play with. By virtue of the IDL COM declaration, if we use intellisense on ie_events, we are going to see both interface's methods and events. And there we have BeforeNavigate.

We are done, let's show how we use this event to get the actual notification. In .NET, we just create a delegate, and attach an event handler to it:

public Form1()
{
    //
    // Required for Windows Form Designer support
    //
    InitializeComponent();

    // -- begin code snippet --

    ie_events = (SHDocVw.WebBrowserClass) Marshal.CreateWrapperOfType(
        axWebBrowser1.GetOcx(),
        typeof(SHDocVw.WebBrowserClass)
    );

    SHDocVw.DWebBrowserEvents_BeforeNavigateEventHandler BeforeNavigateE = 
        new SHDocVw.DWebBrowserEvents_BeforeNavigateEventHandler( 
            OnBeforeNavigate 
        );

    ie_events.BeforeNavigate += BeforeNavigateE;

    // -- end code snippet --

    ...
}

public void OnBeforeNavigate(string url, 
                             int flags, 
                             string targetFrame, 
                             ref object postData, 
                             string headers, 
                             ref bool Cancel)
{
    int c = 0; // PUT A BREAKPOINT HERE
}

A demo app

Just to see something happen on screen, we immediately ask the web browser to show CodeProject (face of relief...):

textBox1.Text = "http://www.codeproject.com";
OnNewUrl(null,null);

// KeyUp handler (used to trap VK_RETURN from the text box)
private void OnNewUrl(object sender, KeyEventArgs e)
{
    object o = null;

    if (e==null || e.KeyCode==Keys.Enter)
        axWebBrowser1.Navigate(textBox1.Text, ref o, ref o, 
            ref o, ref o);
}

Eh voilà.

Stephane Rodriguez - Oct 28 2002.

History

  • October 28, 2002 - Initial Posting

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Addicted to reverse engineering. At work, I am developing business intelligence software in a team of smart people (independent software vendor).

Need a fast Excel generation component? Try xlsgen.


You may also be interested in...

Comments and Discussions

 
QuestionMy vote of 5! Pin
Volynsky Alex4-Nov-14 8:48
professionalVolynsky Alex4-Nov-14 8:48 
Generalusing DocumentComplete Pin
dakkeh20-Jan-08 2:36
memberdakkeh20-Jan-08 2:36 
GeneralPerfect Pin
abensicsu26-Jan-06 10:30
memberabensicsu26-Jan-06 10:30 
GeneralWindowSetLeft and dual monitors Pin
geblack8-Dec-04 5:08
membergeblack8-Dec-04 5:08 
GeneralEvent handlers are lost when opening more than one form with a web browser in it. [modified] Pin
simonclark3-Aug-04 4:20
membersimonclark3-Aug-04 4:20 
GeneralRe: Event handlers are lost when opening more than one form with a web browser in it. Pin
Anonymous21-Nov-04 6:15
sussAnonymous21-Nov-04 6:15 
QuestionHow to get rid of the Beep when pressing enter? Pin
henchook14-Jul-04 5:19
memberhenchook14-Jul-04 5:19 
AnswerRe: How to get rid of the Beep when pressing enter? Pin
jbredeche14-Mar-06 12:53
memberjbredeche14-Mar-06 12:53 
GeneralWindowSetLeft problem Pin
Michael Z...25-Jun-04 11:59
sussMichael Z...25-Jun-04 11:59 
GeneralRe: WindowSetLeft problem Pin
Anonymous10-Aug-04 12:52
sussAnonymous10-Aug-04 12:52 
GeneralRe: WindowSetLeft problem Pin
mikezat10-Aug-04 13:30
membermikezat10-Aug-04 13:30 
GeneralNewWindow2 problem Pin
Michael Cleary8-Jun-04 5:49
memberMichael Cleary8-Jun-04 5:49 
GeneralRe: NewWindow2 problem Pin
NetCoder200518-Apr-05 11:49
memberNetCoder200518-Apr-05 11:49 
GeneralRe: NewWindow2 problem Pin
Carlos Eugênio X. Torres4-Sep-05 23:57
memberCarlos Eugênio X. Torres4-Sep-05 23:57 
GeneralRe: NewWindow2 problem Pin
mvdeveloper20-Sep-07 9:19
membermvdeveloper20-Sep-07 9:19 
GeneralCustom HTTP headers Pin
gerdavax7-May-04 0:37
membergerdavax7-May-04 0:37 
GeneralRe: Custom HTTP headers Pin
Stephane Rodriguez.7-May-04 9:40
memberStephane Rodriguez.7-May-04 9:40 
GeneralRe: Custom HTTP headers Pin
gerdavax9-May-04 21:57
membergerdavax9-May-04 21:57 
GeneralRe: Custom HTTP headers Pin
darXstar11-May-04 23:43
memberdarXstar11-May-04 23:43 
GeneralRe: Custom HTTP headers Pin
gerdavax12-May-04 0:47
membergerdavax12-May-04 0:47 
GeneralRe: Custom HTTP headers Pin
darXstar14-May-04 5:45
memberdarXstar14-May-04 5:45 
GeneralRe: Custom HTTP headers Pin
Anonymous13-Dec-04 2:56
sussAnonymous13-Dec-04 2:56 
GeneralRe: Custom HTTP headers Pin
specter7928-Sep-06 11:34
memberspecter7928-Sep-06 11:34 
GeneralCFileFind Pin
Alicya12-Feb-04 22:17
sussAlicya12-Feb-04 22:17 
GeneralRe: CFileFind Pin
Stephane Rodriguez.12-Feb-04 23:30
memberStephane Rodriguez.12-Feb-04 23:30 
GeneralWBC in MDI Pin
sheeba Gandhi7-Nov-03 23:49
membersheeba Gandhi7-Nov-03 23:49 
GeneralRe: WBC in MDI Pin
Stephane Rodriguez.9-Nov-03 5:48
memberStephane Rodriguez.9-Nov-03 5:48 
GeneralNice! Pin
Jamie Nordmeyer13-Oct-03 6:37
memberJamie Nordmeyer13-Oct-03 6:37 
GeneralWindowClosing problem Pin
Pawel Bublewicz4-Sep-03 6:41
memberPawel Bublewicz4-Sep-03 6:41 
GeneralRe: WindowClosing problem Pin
neocrazydvx17-Dec-03 9:19
memberneocrazydvx17-Dec-03 9:19 
GeneralRe: WindowClosing problem Pin
Randy Charles Morin1-May-04 11:59
memberRandy Charles Morin1-May-04 11:59 
GeneralOnDocumentComplete fix Pin
GarryMoore5-Feb-03 2:12
sussGarryMoore5-Feb-03 2:12 
GeneralRe: OnDocumentComplete fix Pin
Kev Keenoy31-Aug-03 5:39
memberKev Keenoy31-Aug-03 5:39 
GeneralRe: OnDocumentComplete fix Pin
Stephane Rodriguez.31-Aug-03 5:50
memberStephane Rodriguez.31-Aug-03 5:50 
GeneralRe: OnDocumentComplete fix Pin
Kev Keenoy31-Aug-03 22:36
memberKev Keenoy31-Aug-03 22:36 
GeneralRe: OnDocumentComplete fix Pin
Anonymous17-Aug-04 7:39
sussAnonymous17-Aug-04 7:39 
GeneralMore concise code: Pin
John Crim8-Jan-03 18:29
memberJohn Crim8-Jan-03 18:29 
GeneralFrame Information Pin
moxen5-Dec-02 11:01
membermoxen5-Dec-02 11:01 
GeneralRe: Frame Information Pin
.S.Rod.5-Dec-02 21:18
member.S.Rod.5-Dec-02 21:18 
GeneralRe: Frame Information Pin
moxen8-Dec-02 11:37
membermoxen8-Dec-02 11:37 
Generalthanks for this ... Pin
Bill Woodruff4-Nov-02 21:44
sussBill Woodruff4-Nov-02 21:44 
GeneralFYI Pin
James T. Johnson29-Oct-02 19:08
editorJames T. Johnson29-Oct-02 19:08 
GeneralRe: FYI Pin
.S.Rod.29-Oct-02 19:13
member.S.Rod.29-Oct-02 19:13 
GeneralRe: FYI Pin
Sijin8-Nov-02 4:48
memberSijin8-Nov-02 4:48 
GeneralRe: FYI Pin
James T. Johnson8-Nov-02 4:54
editorJames T. Johnson8-Nov-02 4:54 
GeneralMS support for this bug Pin
.S.Rod.28-Oct-02 18:13
member.S.Rod.28-Oct-02 18:13 
GeneralGood explanation Pin
GriffonRL28-Oct-02 10:25
memberGriffonRL28-Oct-02 10:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150731.1 | Last Updated 30 Oct 2002
Article Copyright 2002 by Stephane Rodriguez.
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid