C Implementation of Multi tab Browser Control

  • 2021-09-12 01:55:46
  • OfStack

In this paper, we share the design and implementation of C # multi-tab browser control in detail for your reference, the specific contents are as follows

1. Why do we need multi-tab browser controls
In the project, we need to use WinForm application to wrap the browser shell of BS application. There is no configuration attribute of multi-tab browsing in WebBrowser of. NET. We need to implement multi-tab browser control to wrap BS application without popping up IE browser window.

2. What do we need to know
2.1. WebBrowser Control
The WebBrowser control provides a managed wrapper for the WebBrowser ActiveX control. Managed wrappers enable you to display Web pages in Windows Forms client applications. Using the WebBrowser control, you can replicate the Internet Explorer Web browsing functionality in your application, disable the default Internet Explorer functionality, and use the control as a simple HTML document viewer.

How to l: Navigate to URL Using the WebBrowser Control

this.webBrowser1.Navigate("http://www.microsoft.com");

CreateSink method and DetachSink method of l WebBrowser

The CreateSink method associates the underlying ActiveX control with a client that can handle control events.

The DetachSink method causes the event-handling client attached to the CreateSink method to be released from the underlying ActiveX control.

The following code example demonstrates how to use this method in a class derived from WebBrowser, which complements the regular WebBrowser event with the NavigateError event in the OLE DWebBrowserEvents2 interface.


using System;

using System.Windows.Forms;

using System.Runtime.InteropServices;

using System.Security.Permissions;

 

namespace WebBrowserExtensibility

{

  [PermissionSetAttribute(SecurityAction.Demand, Name="FullTrust")]

  public class Form1 : Form

  {

    [STAThread]

    public static void Main()

    {

      Application.Run(new Form1());

    }

    private WebBrowser2 wb = new WebBrowser2();

    public Form1()

    {

      wb.Dock = DockStyle.Fill;

      wb.NavigateError += new

        WebBrowserNavigateErrorEventHandler(wb_NavigateError);

      Controls.Add(wb);

      wb.Navigate("www.widgets.microsoft.com");

    }

    private void wb_NavigateError(

      object sender, WebBrowserNavigateErrorEventArgs e)

    {

      // Display an error message to the user.

      MessageBox.Show("Cannot navigate to " + e.Url);

    }

  }

 

  public class WebBrowser2 : WebBrowser

  {

    AxHost.ConnectionPointCookie cookie;

    WebBrowser2EventHelper helper;

    [PermissionSetAttribute(SecurityAction.LinkDemand, Name="FullTrust")]

    protected override void CreateSink()

    {

      base.CreateSink();

      helper = new WebBrowser2EventHelper(this);

      cookie = new AxHost.ConnectionPointCookie(

        this.ActiveXInstance, helper, typeof(DWebBrowserEvents2));

    }

 

    [PermissionSetAttribute(SecurityAction.LinkDemand, Name="FullTrust")]

    protected override void DetachSink()

    {

      if (cookie != null)

      {

        cookie.Disconnect();

        cookie = null;

      }

      base.DetachSink();

    }

    public event WebBrowserNavigateErrorEventHandler NavigateError;

    protected virtual void OnNavigateError(

      WebBrowserNavigateErrorEventArgs e)

    {

      if (this.NavigateError != null)

      {

        this.NavigateError(this, e);

      }

    }

    private class WebBrowser2EventHelper :

      StandardOleMarshalObject, DWebBrowserEvents2

    {

      private WebBrowser2 parent;

 

      public WebBrowser2EventHelper(WebBrowser2 parent)

      {

        this.parent = parent;

      }

 

      public void NavigateError(object pDisp, ref object url,

        ref object frame, ref object statusCode, ref bool cancel)

      {

        // Raise the NavigateError event.

        this.parent.OnNavigateError(

          new WebBrowserNavigateErrorEventArgs(

          (String)url, (String)frame, (Int32)statusCode, cancel));

      }

    }

  }

  public delegate void WebBrowserNavigateErrorEventHandler(object sender,

    WebBrowserNavigateErrorEventArgs e);

  public class WebBrowserNavigateErrorEventArgs : EventArgs

  {

    private String urlValue;

    private String frameValue;

    private Int32 statusCodeValue;

    private Boolean cancelValue;

 

    public WebBrowserNavigateErrorEventArgs(

      String url, String frame, Int32 statusCode, Boolean cancel)

    {

      urlValue = url;

      frameValue = frame;

      statusCodeValue = statusCode;

      cancelValue = cancel;

    }

 

    public String Url

    {

      get { return urlValue; }

      set { urlValue = value; }

    }

 

    public String Frame

    {

      get { return frameValue; }

      set { frameValue = value; }

    }

 

    public Int32 StatusCode

    {

      get { return statusCodeValue; }

      set { statusCodeValue = value; }

    }

 

    public Boolean Cancel

    {

      get { return cancelValue; }

      set { cancelValue = value; }

    }

  }

  [ComImport, Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D"),

  InterfaceType(ComInterfaceType.InterfaceIsIDispatch),

  TypeLibType(TypeLibTypeFlags.FHidden)]

  public interface DWebBrowserEvents2

  {

    [DispId(271)]

    void NavigateError(

      [In, MarshalAs(UnmanagedType.IDispatch)] object pDisp,

      [In] ref object URL, [In] ref object frame,

      [In] ref object statusCode, [In, Out] ref bool cancel);

  }

}

l WebBrowser. DocumentCompleted Event

Occurs when the WebBrowser control finishes loading the document.

Handles DocumentCompleted events and receives notifications when new documents finish loading. If the DocumentCompleted event occurs, the new document is fully loaded, meaning that the contents of the document can be accessed through the Document, DocumentText, or DocumentStream properties.

2.2. TabControl Control
The TabControl control is an Windows form multiple-tab control that is similar to a separator card in a notebook and a label in a filing cabinet folder. Tab can contain pictures and other controls. You can use this tab control to generate multi-page dialog boxes, which are found in many places in the Windows operating system, such as in the Display property of the control panel.

l How to: Add Controls to Tab Pages

tabPage1.Controls.Add(new Button());

l How to: Add and Remove Tabs Using the Windows Form TabControl

Add a tab


string title = "TabPage " + (tabControl1.TabCount + 1).ToString();

TabPage myTabPage = new TabPage(title);

tabControl1.TabPages.Add(myTabPage);

Remove tabs

tabControl1.TabPages.Remove(tabControl1.SelectedTab);

l TabControl. DrawItem Event

If the DrawMode property is set to OwnerDrawFixed, TabControl raises an DrawItem event whenever it needs to draw one of its tabs. To customize the appearance of a tab, provide your own drawing code in the handler for the DrawItem event.

The following code example creates an TabControl that contains one TabPage. This example declares an event handler and is used to draw strings and Rectangle on the tabs of tabPage1. The event handler is bound to the DrawItem event.


using System.Drawing;

using System.Windows.Forms;

public class Form1 : Form

{

  private Rectangle tabArea;

  private RectangleF tabTextArea;

  public Form1()

  {

    TabControl tabControl1 = new TabControl();

    TabPage tabPage1 = new TabPage();

    tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;

    tabControl1.SizeMode = TabSizeMode.Fixed;

    tabControl1.Controls.Add(tabPage1);

    tabControl1.ItemSize = new Size(80, 30);

    tabControl1.Location = new Point(25, 25);

    tabControl1.Size = new Size(250, 250);

    tabPage1.TabIndex = 0;

    ClientSize = new Size(300, 300);

    Controls.Add(tabControl1);

    tabArea = tabControl1.GetTabRect(0);

    tabTextArea = (RectangleF)tabControl1.GetTabRect(0);

    tabControl1.DrawItem += new DrawItemEventHandler(DrawOnTab);

  }

  private void DrawOnTab(object sender, DrawItemEventArgs e)

  {

    Graphics g = e.Graphics;

    Pen p = new Pen(Color.Blue);

    Font font = new Font("Arial", 10.0f);

    SolidBrush brush = new SolidBrush(Color.Red);

    g.DrawRectangle(p, tabArea);

    g.DrawString("tabPage1", font, brush, tabTextArea);

  }

  static void Main()

  {

    Application.Run(new Form1());

  }

}

3. How do we design a multi-tab browser control
Features to be implemented:

The l implementation opens a link or window for an BS application to jump to a tab instead of a new window.

l realizes the closing and creating of tabs. Note that when there is only one tab, the closing picture button cannot appear on the tabs.

We mainly use TabControl and WebBrowser to achieve multi-tab browser control development.

The main control implementation code is introduced now.

u New Tab page code implementation is as follows:


public void CreateNewTabPage(string url)

{

  ExtendedWebBrowser web = new ExtendedWebBrowser();

  web.Name = "WebBroswer" + _webBrowserLists.Count.ToString();

  web.Dock = DockStyle.Fill;

  web.Margin = new Padding(0, 0, 0, 0);

  web.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);

  web.BeforeNewWindow += new EventHandler(webBrowser1_BeforeNewWindow);

  web.Navigate(url);

  _webBrowserLists.Add(web);

 

  TabPage tbp = new TabPage();

  tbp.Name = "TabPage" + tabControl1.TabCount.ToString();

  tbp.Text = " Blank page ";

  tbp.Padding = new Padding(0, 3, 0, 0);

  tbp.Margin = new Padding(0, 3, 0, 0);

  tbp.ImageIndex = 0;

  tbp.Controls.Add(web);

 

  this.tabControl1.Controls.Add(tbp);

  this.tabControl1.SelectedTab = tbp;

}

 

u  Realize the code in the drawing tab of the webpage title and picture close button as follows: 

private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)

{

 

  try

  {

    Graphics g = e.Graphics;

 

    Rectangle tabRectangle = this.tabControl1.GetTabRect(e.Index);

 

    // Add first TabPage Attribute  

    g.DrawString(this.tabControl1.TabPages[e.Index].Text

    , this.Font, SystemBrushes.ControlText, tabRectangle.X + 3, tabRectangle.Y + 3);

 

    if (tabControl1.TabCount > 1)

    {

      // Draw again 1 Rectangular boxes 

      using (Pen p = new Pen(SystemColors.Control))

      {

        tabRectangle.Offset(tabRectangle.Width - (CLOSE_SIZE + 3), 2);

        tabRectangle.Width = CLOSE_SIZE;

        tabRectangle.Height = CLOSE_SIZE;

        g.DrawRectangle(p, tabRectangle);

      }

 

      g.DrawImage(e.State == DrawItemState.Selected ? imageList1.Images["closeSelected"] : imageList1.Images["close"], new Point(tabRectangle.X, tabRectangle.Y));

 

    }

    g.Dispose();

  }

  catch (Exception ex)

  {

    throw (ex);

  }

}

When the u Webbrowser control completes and when the Webbrowser control creates a new window, the code implementation is as follows:


private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)

{

  ExtendedWebBrowser web = (ExtendedWebBrowser)(sender);

  string title = web.Document.Title.Trim();

  TabPage tb = (TabPage)web.Parent;

  tb.Text = title.Length > 6 ? title.Substring(0, 6) + "..." : title;

  if (tabControl1.SelectedTab == tb)

  {

    this.Text = title;

  }

}

private void webBrowser1_BeforeNewWindow(object sender, System.EventArgs e)

{

  WebBrowserExtendedNavigatingEventArgs eventArgs = e as WebBrowserExtendedNavigatingEventArgs;

  CreateNewTabPage(eventArgs.Url);

  eventArgs.Cancel = true;

}

The above is the whole content of this paper, hoping to help everyone's study.


Related articles: