A Web Browser in C#
This article describes creating a web browser completely in
C#. The application hosts a Microsoft WebBrowser Control and uses the
functions it provides for all control. Here is a screenshot:
A lot of the functions do not work yet; most require some
non-.NET programming to work. I stuck to pure .NET programming for this app,
because it is meant to demonstrate features of the .NET Framework and not some
APIs.
Building the Web Browser
Before you begin, you must generate some assemblies from the
WebBrowser typlibs, so that they can be used in our code. Typlibs must be
imported for:
- The WebBrowser control itself, which is in SHDocVw.dll.
- mshtml.tlb, if you plan to access the DHTML Object Model of the document.
This step is easy. At a command prompt, in a folder you
create for this project, type:
aximp c:\windows\system\shdocvw.dll
tlbimp mshtml.tlb
The aximp command should generate two files: AxSHDocVw.dll
and SHDocVw.dll. The tlbimp command should generate MSHTML.dll, which contains
definitions for the DHTML DOM interfaces, along with about 3000 other types,
so it might take a while to import.
Now you can proceed in several ways: You can do all coding
by hand, or you can use Visual Studio.NET. I have done it the 'SDK way'. Basically,
you have to create a form with:
- The WebBrowser control itself.
- A toolbar. Note that not all buttons on the toolbar work as you
might expect them to.
- A status bar. You can add panels for the status message, a progress bar,
offline and secure icons, and a zone indicator. I've added these controls
as placeholders only, they don't work (yet).
- An address bar. This should be a panel with a label, a combo box, and a Go
button.
- A main menu for the application.
- An image list for the toolbar.
Most of the initialisation code shall be added for you and
little work needs to be done here. You must remember to add event handlers for
the WebBrowser control, the status bar, the menus, the toolbar, the address
combo box, and the Go button. All this code is present in the file
WebBrowser.cs. In addition, extra dialogs are included in About.cs,
ImportExport.cs, and Open.cs.
In the WebBrowser.cs file, you must put in the following
statements in the namespace:
namespace ND.WebBrowser
{
using System;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;
using Microsoft.Win32;
using AxSHDocVw;
using MSHTML;
Microsoft.Win32 is required because the application loads the URL MRU
list from the registry. you can remove the MSHTML reference if you
do not need it.
Notice SHDocVw is not included; this causes conflicts with
the definitions in AxSHDocVw.dll. Most of the code is simple and calls
functions of the WB control.
Menus and Toolbars
The menu and the toolbar are standard Windows Forms stuff. Menu
popup events are handled to update the enabled/disabled and checked state of
menu items. For example:
protected void mnuFile_Popup(object sender, EventArgs e)
{
MenuItem miFile = MenuMain.MenuItems[0];
miFile.MenuItems[14].Checked = AxWebBrowser.Offline;
Int32 EnabledTest = Convert.ToInt32(SHDocVw.OLECMDF.OLECMDF_SUPPORTED)
+ Convert.ToInt32(SHDocVw.OLECMDF.OLECMDF_ENABLED);
miFile.MenuItems[2].Enabled = EnabledTest.Equals(AxWebBrowser.QueryStatusWB
(SHDocVw.OLECMDID.OLECMDID_REFRESH));
miFile.MenuItems[3].Enabled = EnabledTest.Equals(AxWebBrowser.QueryStatusWB
(SHDocVw.OLECMDID.OLECMDID_SAVE));
miFile.MenuItems[4].Enabled = EnabledTest.Equals(AxWebBrowser.QueryStatusWB
(SHDocVw.OLECMDID.OLECMDID_SAVEAS));
miFile.MenuItems[6].Enabled = EnabledTest.Equals(AxWebBrowser.QueryStatusWB
(SHDocVw.OLECMDID.OLECMDID_PAGESETUP));
miFile.MenuItems[7].Enabled = EnabledTest.Equals(AxWebBrowser.QueryStatusWB
(SHDocVw.OLECMDID.OLECMDID_PRINT));
miFile.MenuItems[8].Enabled = EnabledTest.Equals(AxWebBrowser.QueryStatusWB
(SHDocVw.OLECMDID.OLECMDID_PRINTPREVIEW));
miFile.MenuItems[13].Enabled = EnabledTest.Equals(AxWebBrowser.QueryStatusWB
(SHDocVw.OLECMDID.OLECMDID_PROPERTIES));
}
First, the File menu object is obtained. Then the WB control
is used to check the enabled status of commands in the menu. If you are
familiar with COM programming, this should be standard code. Otherwise, read
the WebBrowser control documentation at MSDN: WebBrowser.
Most commands are also executed in the standard COM IOleCommandTarget way, like
this:
protected void mnuFileSave_Click(object sender, EventArgs e)
{
Object o = null;
m_axWebBrowser.ExecWB(SHDocVw.OLECMDID.OLECMDID_SAVE,
SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT,
ref o, ref o);
}
A null object reference is passed for the input and output
arguments of the ExecWB method. Simply because we have no arguments to pass.
Some menu commands use methods of the WebBrowser control itself, like Home and Search.
The other source files have other dialogs, like the Import & Export dialog.
protected void mnuFileOpen_Click(object sender, EventArgs e)
{
OpenForm frmOpen = new OpenForm();
frmOpen.ShowDialog(this);
if(frmOpen.DialogResult == DialogResult.OK)
{
Object o = null;
AxWebBrowser.Navigate(frmOpen.Address, ref o, ref o, ref o, ref o);
}
}
The Import and Export dialog uses the ShellUIHelper object,
documented at MSDN: Shell Helper API.
Editing the Document
Instead of calling an external editor, all editing is done
by the WebBrowser control itself, using an IE 4 feature which allows documents to
make themselves editable. However, our code only invokes the edit mode, and
does nothing beyond that.
protected void mnuFileEdit_Click(object sender, EventArgs e)
{
IHTMLDocument2 doc;
object boxDoc = AxWebBrowser.Document;
doc = (IHTMLDocument2)boxDoc;
doc.designMode = "On";
}
The code first gets a reference to the Document
object and then unboxes it to get
to the IHTMLDocument2
interface. This is necessary because the WebBrowser control
returns the document as an object and not an IHTMLDocument2
pointer.
The Finished Code
That just about sums up most of the code. However, a lot of
things do not work yet. Here is a short list:
- 'Full Screen' and 'View Source' in the application menus.
- Enumeration of the user's Favourites and History.
- 'Send' submenu of 'File' menu.
- Mail button on toolbar.
- Edit works to only to a limited extent.
- Tools Menu.
- Back and Forward drop-downs.
- Some pages, especially those with frames, do not load properly. ( ? )
- There is no handling for new windows.
- Status bar icons (secure, offline, zone) are not displayed.
Most code should be easy to create, and can be done within
the .NET Framework. However, some functions, like those for favourites and
history, shall involve PInvoke.