Click here to Skip to main content
Click here to Skip to main content

Multi Tab WebBrowser

, 23 May 2005
Rate this:
Please Sign up or sign in to vote.
A webbrowser example of how to open new web windows in new tabs.

Sample Image - MultiTabWebBrowser.jpg

Introduction

One web browser feature that is growing in popularity is the ability to open different tabs, or sub-pages, within the same browser window. Using tabs to separate multiple pages keeps the desktop tidy, while browsing multiple sites.

The web browser is also efficient for viewing multiple local files as it supports many files formats.

This code shows how to implement this feature, and also implements the following features: Print, Print Preview, Page properties, Options screen, Find Dialog, View page source, and more.

Implementing the Multi Tab Feature

This feature is mainly implemented by the NewWindow2 event.

The NewWindow2 event occurs when a new window is to be created for displaying a resource. This event occurs before a new window is created from the WebBrowser control. For example, this event occurs in response to a navigation that is targeted to a new window or to a scripted window.open method.

To specify that your browser program is to be used when a new window is opened, set the ppDisp parameter equal to the Application object. In this scenario, if a user chooses to open a web page in a new window, the new window in your program is used to display the new web page.

Additionally, set the RegisterAsBrowser property to true. This setting causes the new WebBrowser control to participate in window-name resolution. For example, if the window name is used elsewhere in the script, this control is used instead of a newly created one because the control examines all the existing window names before opening a new window.

On this event, we dynamically create a new instance of a tab page and a web browser as child by calling the CreateNewWebBrowser() method, where each web browser object has a tag object containing additional data on the corresponding web browser:

private void axWebBrowser1_NewWindow2(object sender, 
                AxSHDocVw.DWebBrowserEvents2_NewWindow2Event e)
{
  AxSHDocVw.AxWebBrowser _axWebBrowser = CreateNewWebBrowser();
  e.ppDisp = _axWebBrowser.Application;
  _axWebBrowser.RegisterAsBrowser = true;
}

private AxSHDocVw.AxWebBrowser CreateNewWebBrowser()
{
  AxSHDocVw.AxWebBrowser _axWebBrowser = new AxSHDocVw.AxWebBrowser();
  _axWebBrowser.Tag = new HE_WebBrowserTag();
  TabPage _TabPage = new TabPage();
  _TabPage.Controls.Add(_axWebBrowser);
  _axWebBrowser.Dock = DockStyle.Fill;
  _axWebBrowser.BeforeNavigate2 += new 
           AxSHDocVw.DWebBrowserEvents2_BeforeNavigate2EventHandler(
           this.axWebBrowser1_BeforeNavigate2);
  _axWebBrowser.DocumentComplete += new 
           AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(
           this.axWebBrowser1_DocumentComplete);
  _axWebBrowser.NavigateComplete2 += new 
           AxSHDocVw.DWebBrowserEvents2_NavigateComplete2EventHandler(
           this.axWebBrowser1_NavigateComplete2);
  _axWebBrowser.NavigateError += new 
           AxSHDocVw.DWebBrowserEvents2_NavigateErrorEventHandler(
           this.axWebBrowser1_NavigateError);
  _axWebBrowser.NewWindow2 += new 
           AxSHDocVw.DWebBrowserEvents2_NewWindow2EventHandler(
           this.axWebBrowser1_NewWindow2);
  _axWebBrowser.ProgressChange += new 
           AxSHDocVw.DWebBrowserEvents2_ProgressChangeEventHandler(
           this.axWebBrowser1_ProgressChange);
  _axWebBrowser.StatusTextChange += new 
           AxSHDocVw.DWebBrowserEvents2_StatusTextChangeEventHandler(
           this.axWebBrowser1_StatusTextChange);
  _axWebBrowser.TitleChange += new 
           AxSHDocVw.DWebBrowserEvents2_TitleChangeEventHandler(
           this.axWebBrowser1_TitleChange);
  _axWebBrowser.CommandStateChange += new 
           AxSHDocVw.DWebBrowserEvents2_CommandStateChangeEventHandler(
           this.axWebBrowser1_CommandStateChange);

  tabControl1.TabPages.Add(_TabPage);
  tabControl1.SelectedTab = _TabPage;
  return _axWebBrowser;
}

Each instance of a web browser will have in its tag an HE_WebBrowserTag object that holds some details on that web browser object:

public class HE_WebBrowserTag
{
  public int _TabIndex = 0;
  public bool _CanBack = false;
  public bool _CanForward = false;
}

Invoke the Find, View Source, and Options Dialog Boxes

Warning: this sample uses an undocumented command-group GUID that is subject to change in the future. Although this sample was tested to work correctly with Internet Explorer 6 and earlier, there is no guarantee that these techniques will continue to work successfully in future versions.

Define IOleCommandTarget in Visual C# .NET

To define a .NET interface to obtain a reference to a Component Object Model (COM) interface, follow these steps:

  1. Assign the interface the GUID of the appropriate COM interface.
  2. Include type declarations for all the methods of the interface.
  3. Include references to the Mshtml.dll file and the Shdocvw.dll file.

    To do this in your Visual C# .NET project, follow these steps:

    1. Click Add Reference on the Project menu.
    2. Click the COM tab.
    3. Double-click Microsoft HTML Object Library and Microsoft Internet Controls.
  4. Include the following interface declaration just before your application's namespace declaration to add a reference to the Microsoft HTML (MSHTML) IOleCommandTarget interface:
    using System;
    using System.Runtime.InteropServices;
    [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
    public struct OLECMDTEXT
    {
        public uint cmdtextf;
        public uint cwActual;
        public uint cwBuf;
        [MarshalAs(UnmanagedType.ByValTStr,SizeConst=100)]public char rgwz;
    }
    
    [StructLayout(LayoutKind.Sequential)]
    public struct OLECMD
    {
        public uint cmdID;
        public uint cmdf;
    }
    
    // Interop definition for IOleCommandTarget.
    [ComImport,
    Guid("b722bccb-4e68-101b-a2bc-00aa00404770"),
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IOleCommandTarget
    {
        //IMPORTANT: The order of the methods is critical here. You
        //perform early binding in most cases, so the order of the methods
        //here MUST match the order of their vtable layout (which is determined
        //by their layout in IDL). The interop calls key off the vtable ordering,
        //not the symbolic names. Therefore, if you 
        //switched these method declarations
        //and tried to call the Exec method 
        //on an IOleCommandTarget interface from your
        //application, it would translate 
        //into a call to the QueryStatus method instead.
        void QueryStatus(ref Guid pguidCmdGroup, UInt32 cCmds,
            [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] 
            OLECMD[] prgCmds, ref OLECMDTEXT CmdText);
        void Exec(ref Guid pguidCmdGroup, uint nCmdId, uint nCmdExecOpt, 
                  ref object pvaIn, ref object pvaOut);
    }

Define the Command GUID for CGID_IWebBrowser

You must also define the GUID for CGI_IWebBrowser to inform MSHTML how to process your command IDs. Use the Microsoft .NET Framework class GUID to do this:

private Guid cmdGuid = new Guid("ED016940-BD5B-11CF-BA4E-00C04FD70816");

private enum MiscCommandTarget { Find = 1, ViewSource, Options }

Call Exec()

Finally, encapsulate the calls to the Exec method in three separate method calls. Each call assumes the existence of a hosted instance of the WebBrowser control that is named webBrowser:

private mshtml.HTMLDocument GetDocument()
{
    try
    {
        mshtml.HTMLDocument htm = (mshtml.HTMLDocument)axWebBrowser2.Document;
        return htm;
    }
    catch
    {
        throw (new Exception("Cannot retrieve" + 
               " the document from the WebBrowser control"));
    }
}

public void ViewSource()
{
    IOleCommandTarget cmdt;
    Object o = new object();
    try
    {
        cmdt = (IOleCommandTarget)GetDocument();
        cmdt.Exec(ref cmdGuid, (uint)MiscCommandTarget.ViewSource,
        (uint)SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, ref o, ref o);
    }
    catch(Exception e)
    {
        System.Windows.Forms.MessageBox.Show(e.Message);
    }
}

public void Find()
{
    IOleCommandTarget cmdt;
    Object o = new object();
    try
    {
        cmdt = (IOleCommandTarget)GetDocument();
        cmdt.Exec(ref cmdGuid, (uint)MiscCommandTarget.Find,
        (uint)SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, ref o, ref o);
    }
    catch(Exception e)
    {
        System.Windows.Forms.MessageBox.Show(e.Message);
    }
}

public void InternetOptions()
{
    IOleCommandTarget cmdt;
    Object o = new object();
    try
    {
        cmdt = (IOleCommandTarget)GetDocument();
        cmdt.Exec(ref cmdGuid, (uint)MiscCommandTarget.Options,
        (uint)SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, ref o, ref o);
    }
    catch
    {
        // NOTE: Because of the way that this CMDID is handled in Internet Explorer,
        // this catch block will always fire, even though the dialog box
        // and its operations completed successfully. You can suppress this
        // error without causing any damage to your host.
    }
}

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

Ronit H

Israel Israel
No Biography provided

Comments and Discussions

 
BugGUI freezing on navigating PinmemberEmiliarge24-Aug-14 0:01 
QuestionDocument.All.Item and InvokeMember help Pinmemberzouhair samir13-Sep-13 16:57 
GeneralMy vote of 5 PinmemberLVMONTIEL5-May-11 2:05 
GeneralDrag Out tabs PinmemberFullmetal9901224-Apr-11 4:54 
QuestionGreat Job, Help Please Pinmemberyoung10120-Nov-09 20:59 
GeneralHelp with tabs!!! PinmemberALEX CHIHAI7-Oct-09 3:33 
GeneralYou Rock! PinmemberShannon McCoy19-Aug-09 4:04 
GeneralVB.Net implementation Pinmemberbn2vs23-Feb-09 10:12 
GeneralHere is your 5! Pinmemberfinal_zero30-Nov-08 1:16 
QuestionHide the Find Dialog when swichting to differnet tab? PinmemberTexG29-Feb-08 4:57 
QuestionI cannot call javascript with this browser. Could you give me a sample solution? PinmemberWoo Hyuck Choi29-Dec-07 3:47 
QuestionCan we use web browser from stream? PinmemberAriston Darmayuda19-Jul-07 7:27 
GeneralChanging printer at run time Pinmembertemp->next20-Jun-07 2:25 
GeneralVery good PinmemberCurious Programmer26-Mar-07 7:40 
QuestionPage not loaded if switched to another tab PinmemberBalaVikram6-Feb-07 2:24 
GeneralWindow-name resolution with WebBrowser 2.0 PinmemberBrightSoul22-Jun-06 1:13 
AnswerRe: Window-name resolution with WebBrowser 2.0 PinmemberThe Dogcow Farmer8-Sep-08 12:40 
GeneralGreat work...one question PinmemberRoss1000030-Mar-06 19:15 
GeneralProxy problems Pinmembercdemez6-Mar-06 8:29 
QuestionHow can I close the tab inside page? PinmemberLisana30-Jan-06 12:12 
AnswerRe: How can I close the tab inside page? Pinmemberohmzz10-May-10 7:01 
Questionhow 2 work with combo box using axWebBrowser1 ? Pinmembervedmack9-Jan-06 10:51 
GeneralGreat work, just one question PinmemberDrewes5-Jan-06 3:32 
QuestionSendKeys.Send not working in WebBrowser?. PinmemberArun Appukuttan27-Dec-05 21:11 
Questionhow to disable to download image and sound? Pinmemberchjlcn28-Aug-05 16:18 
GeneralTake up too many memory! Pinmembershanteng25-Aug-05 0:57 
Generalcookie ... problems ... Help plz Pinmemberenjoycrack25-Jul-05 19:43 
GeneralRe: cookie ... problems ... Help plz Pinmemberabakshi25-Jul-05 22:31 
GeneralRe: cookie ... problems ... Help plz Pinmemberenjoycrack25-Jul-05 23:19 
GeneralRe: cookie ... problems ... Help plz Pinmemberabakshi26-Jul-05 8:43 
GeneralRe: cookie ... problems ... Help plz Pinmemberenjoycrack26-Jul-05 18:42 
Generaledit and copy are not working for me PinsussAnonymous21-Jun-05 12:33 
GeneralRemoving TabPages dynamically PinmemberJats7-Jun-05 3:30 
GeneralTechConnect - Tabbed, IE + Gecko, Favorites, Media Player, RSS, more... Pinmemberabakshi23-May-05 10:10 
GeneralNetron's version: docking and favorites. PinmemberNetronProject23-May-05 6:04 
GeneralProgress Bar revised to work Pinmemberbadass19-May-05 19:34 
GeneralRe: Progress Bar revised to work PinmemberRonit H23-May-05 11:19 
GeneralRe: Progress Bar revised to work Pinmemberbadass23-May-05 11:26 
GeneralPopup in new browser window PinmemberNxa10-May-05 11:37 
Generalprint landspace Pinmemberkateerre22-Mar-05 0:51 
GeneralRe: print landspace PinmemberRonit H22-Mar-05 3:06 
GeneralRe: print landspace Pinmemberkateerre22-Mar-05 5:14 
GeneralRe: print landspace PinmemberRonit H23-Mar-05 9:04 
GeneralWow Great work Pinmember^^o000o^^20-Mar-05 9:16 
GeneralRe: Wow Great work Pinmember^^o000o^^20-Mar-05 9:32 
QuestionHave you seen Avant Browser? PinmemberPeter Tewkesbury17-Mar-05 5:21 
AnswerRe: Have you seen Avant Browser? PinsussHarm Salomons25-May-05 3:41 
GeneralRe: Have you seen Avant Browser? PinmemberJRBlack1022-Jun-05 8:46 
AnswerRe: Have you seen Avant Browser? PinmemberJRBlack1022-Jun-05 8:47 
GeneralGreat ! PinmemberLe_MuLoT17-Mar-05 4:20 

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
Web04 | 2.8.150331.1 | Last Updated 23 May 2005
Article Copyright 2005 by Ronit H
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid