Home

News
News Archive

Articles
Taming the Lizard

Forums / Groups

Mozilla-Delphi Project

Pascal Newsletter

Software

Links

Search

Vote For Us:
Irongut's Delphi Pages
Pascal Newsletter

Contact Details

Legal Stuff

Download
Taming the Lizard with Delphi
By Dave Murray <irongut at vodafone dot net>

Would you like to display HTML in your applications using an open source solution? The Gecko Runtime Environment by the Mozilla Foundation can be embedded in a Delphi application by using the Mozilla ActiveX Control. This article shows how to use this control and points out some of the differences between it and the IE based TWebBrowser. The accompanying source code was written in Delphi 6 but should work in Delphi 5 and later. If you want to use the Mozilla ActiveX Control with Delphi 4 you also need to read Delphi 4 Lizard Taming.

First some background and terminology. In 1998 Netscape released the source code for Communicator, their Internet suite, to the open source community and created Mozilla.org. After several years development, the project finally released Mozilla 1.0 in 2002. By then Netscape had been bought by AOL, who repackaged Mozilla 1.0 as Netscape 7.0. In 2003, AOL closed its Netscape software division and the Mozilla code is now entirely controlled by the non-profit Mozilla Foundation. During development the Communicator code was completely re-written and new technologies were invented such as XUL, a cross platform UI definition language using XML, CSS and JavaScript. The Mozilla Suite of a Browser, Mail and Newsreader, HTML Composer and an Address Book is now being superseded by Firefox (browser), Thunderbird (email), and Nvu (composer). Behind all these applications is the Gecko Runtime Environment (GRE) - a fast, free and standards compliant HTML display engine.

All the Mozilla code is released under an MPL/GPL/LGPL tri-license so you can choose the license that suits your needs when using it. For C programmers, building applications based on the Mozilla code is easy, they can just download the code and start hacking immediately but there is also an option for the rest of us. There is an ActiveX control, written by Adam Lock, which can be used to embed the GRE in other applications. This Mozilla ActiveX Control is written to emulate the familiar IE based TWebBrowser.

There is little documentation for the Mozilla Control but you can use the MSDN WebBrowser documentation and ask questions in the netscape.public.mozilla.embedding newsgroup.

Installing the Mozilla ActiveX Control

The Mozilla ActiveX Control requires files that do not ship with a standard GRE (or with Mozilla or Firefox) so the author provides a package that installs the GRE and support files and registers the control for you. An additional GRE is installed, even if the same version is already on your PC, in a directory you specify. I don't like this way of doing things because the installer requires user input which prevents us creating a seamless installer for our own applications. I plan to work out which files are required for a future article about installing the control with an application.

Download Mozilla ActiveX Control v1.5
Download Mozilla ActiveX Control v1.6
Download Mozilla ActiveX Control v1.7.1

Importing the Control into Delphi

You can now import the control into Delphi in the normal way: Component | Import ActiveX Control | Mozilla Control 1.0 Type Library | Install. The control will appear on the ActiveX page of the Component Palette as TMozillaControl; it doesn't contain its own image so it will use Delphi's default one. The archive accompanying this article contains a *.dcr file that you can use to replace the generated one for a nicer image.

I've received reports from Chris Bensen at Borland that the control doesn't always show up in the Import ActiveX Control wizard in Delphi 7 and Delphi 2005. If this happens to you, start a command prompt, go to the directory where you installed the control and type regsvr32 mozctlx.dll. The control should now show up in the IDE as expected. Do not register any other DLLs!

Building a Browser Framework

Since the Mozilla Control is designed to directly replace TWebBrowser, I will first describe a browser framework that could be used to demonstrate or test either control. The main form will have a main menu and be composed of a TPanel at the top that contains a TToolBar, a TEdit for entering URLs and a TAnimate for the throbber, another TPanel below for the browser control and at the bottom a TStatusBar with a progress meter (TProgressBar). The status bar needs 2 panels, the first 150 width for the progress meter and the rest for status messages.

TfrmMain
Figure 1 - TfrmMain

The main menu has the following items:

The toolbar has the following buttons: Back, Forward, Stop, Refresh, Home, Print and Properties. I'm using several TImageList components for the main menu and toolbar button images and for the throbber (page loading animation) I used 'Delphi6\Demos\CoolStuf\Cool.avi'.

Adding TMozillaControl to a Form

Adding a TMozillaControl to a form presents us with some unusual problems. For a start you can't select it by clicking on it so you have to use the Object Inspector or Object Treeview (use this if you need to delete it). And, it is not possible to drag or stretch the control so you have to change its Top, Left, etc properties in the Object Inspector to position it. Also, it doesn't have an Anchors property so I recommend that you place it on a TPanel and set Align := alClient as I have done.

I don't know why the Mozilla Control has these problems (or why it is lime green in the IDE) but they are minor inconveniences rather than major bugs.

Connecting TMozillaControl to the Framework

Now that the Mozilla Control is correctly placed on the form it is time to start connecting it to the rest of the GUI. The methods for the Go menu (and buttons) are identical to using TWebBrowser. We just call the relevant methods of the control, e.g. mzGecko.GoBack.

TMozillaControl provides overloaded Navigate methods which are identical to TWebBrowser:

procedure Navigate(const URL: WideString); overload;

procedure Navigate(const URL:WideString; var Flags:OleVariant);overload;

procedure Navigate(const URL: WideString; var Flags: OleVariant; var TargetFrameName: OleVariant); overload;

procedure Navigate(const URL: WideString; var Flags: OleVariant; var TargetFrameName: OleVariant; var PostData: OleVariant); overload;

procedure Navigate(const URL: WideString; var Flags: OleVariant; var TargetFrameName: OleVariant; var PostData: OleVariant; var Headers: OleVariant); overload;

We use one of these in TfrmMain.edtAddressKeyDown to browse to the given URL when Enter is pressed.

The OnStatusTextChange and OnCommandStateChange events work exactly as with TWebBrowser. The Text parameter of OnStatusTextChange is displayed in the second panel of the status bar. OnCommandStateChange is used to enable and disable the Back and Forward buttons and menu items.

Initially I had some trouble using the OnProgressChange event to control a progress meter. The code I have used before with TWebBrowser didn't work but Sterling Bates suggested an alternative that works perfectly. The new code simply shows the progress as a percentage of the maximum. To complete this feature the progress is set to 0 in OnDownloadComplete.

All browsers have an animation called a throbber which tells the user that a page is loading. We start this animation in the control's OnDownloadBegin event and stop it in the OnDownloadComplete event. We also use the latter event to ensure that edtAddress shows the correct URL.

Open URL Dialog

Open URL Dialog
Figure 2 - Open URL Dialog

Our browser needs a dialog that allows the user to open a URL or file. There is only one complication when using TMozillaControl, when opening a local file any relative images or links with a backslash in their path won't load. This is easy to fix, we just need a function that replaces any backslash with slash before we attempt to use the URL. I used the CharReplace function from the JEDI Code Library (JclStrings.pas) and have copied it into the code for the reader's benefit.

Preferences

Preferences Dialog
Figure 3 - Preferences Dialog

Preferences are also pretty simple. I've stored them in global variables and they are read and written when the dialog is created and closed. I used the CharReplace function again to ensure that the start and home pages will be valid URLs.

Trying to show the start page in TfrmMain.FormCreate gave an unspecified error, probably because the control wasn't properly initialised yet. So, we must do it in TfrmMain.FormShow if the application has just started.

Printing and EOleExceptions

If you've used TWebBrowser before you'll know that printing is an OLE command invoked via the IOleCommandTarget interface by calling the control's ExecWB method. You'll also know that to avoid an EOleException we need to initialise the OLE library before we use it and free it when we've finished. This is best done in initialization and finalization sections. We use this code to Print a page:

mzGecko.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER);

Initially everything went wrong when I tried Page Setup (OLECMDID_PAGESETUP) and Print Preview (OLECMDID_PRINTPREVIEW). Both commands caused an exception - EOleException: Trying to revoke a drop target that has not been registered. In order to find out what was going wrong I talked to Adam Lock who recommended I look at the source code. I don't do C but he gave me a few pointers and I bravely dived into MozillaBrowser.h. :) I immediately noticed that OLECMDID_PRINTPREVIEW is not defined and reported it as bug #214884.

EOleException
Figure 4 - EOleException

OLECMDID_PAGESETUP is defined in MozillaBrowser.h but gave the same exception so I reported it as bug #225045. Since then, Adam Lock has looked into the problem. He expected OLECMDID_PAGESETUP to show a dialog with the message 'No page setup yet!'. The problem was a bug in the way the control tests the second parameter passed in ExecWB. Prior to v1.7, the answer is to pass OLECMDEXECOPT_DODEFAULT instead of OLECMDEXECOPT_PROMPTUSER. Adam has now corrected this and implemented a Page Setup dialog in v1.7. The dialog has all the expected options and a nice headers and footers page but measurements are in inches although the dialog says millimeters. Also, these settings are not saved so they have to be entered every time an application is run. These problems are fairly minor and I hope to see them fixed soon.

Page Setup
Figure 5 - Page Setup Dialog

Another File menu command gave me the same exception, Save As. The problem when calling OLECMDID_SAVEAS is the second parameter again. This has the same workaround prior to v1.7 and has also been fixed.

The Edit Menu

Several edit menu commands are also invoked via IOleCommandTarget - Copy (OLECMDID_COPY), Select All (OLECMDID_SELECTALL) and Clear Selection (OLECMDID_CLEARSELECTION). The first two commands work as per TWebBrowser but with Clear Selection we get an EOleException again. Looking at the source, OLECMDID_CLEARSELECTION is not defined in MozillaBrowser.h; Bugzilla #214884.

Conclusion

The Mozilla Control can be used to display HTML and provide basic browsing functionality in a Delphi application. It is designed to be a close copy of TWebBrowser to make it easier to use but is missing some functionality and has a few quirks of its own. Although development of the control is slow there is work being done and some of the bugs have been fixed recently. There are three two main problems that prevent us providing some basic features:

The latest version, the Mozila ActiveX Control v1.7.1, is based on the Mozilla v1.7.2 codebase. This includes the recent shell: protocol security patch as well as many other speed and stability improvements. I recommend everyone to use this version in their applications.

In future articles I plan to explain how to automatically install the Mozilla Control with an application and explore more complex features like DOM support. The code accompanying this article is a basic browser framework that can be used to demonstrate or test the Mozilla Control. Feel free to use and abuse it as you wish.

Demo Browser
Figure 6 - Demo Browser

References

Mozilla Foundation
Mozilla Control
Mozilla Control Source Code
Bugzilla
netscape.public.mozilla.embedding (via default Newsreader)
netscape.public.mozilla.embedding (via Google Groups)
MSDN WebBrowser Reference
Project JEDI


The Code

unit MainForm;
{Main Form unit for Gecko Browser, a demo of embedding Gecko in Delphi 5+ apps}
{v1.0 Written by Dave Murray <irongut@vodafone.net>, October - November 2003}
{v1.1 Written by Dave Murray, March 2004}
{v1.2 Written by Dave Murray, April + July 2004}
{Gecko Browser v1.2 was written using Mozilla ActiveX Control v1.7.1}


interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, ToolWin, ExtCtrls, ImgList, Menus, OleCtrls,
  ActiveX, MOZILLACONTROLLib_TLB;

type
  TfrmMain = class(TForm)
    mnmnuMain: TMainMenu;
      mFile: TMenuItem;
        mOpen: TMenuItem;
        mSaveAs: TMenuItem;
        N1: TMenuItem;
        mPageSetup: TMenuItem;
        mPrintPreview: TMenuItem;
        mPrint: TMenuItem;
        N2: TMenuItem;
        mExit: TMenuItem;
      mEdit: TMenuItem;
        mCopy: TMenuItem;
        mClearSelection: TMenuItem;
        mSelectAll: TMenuItem;
        N4: TMenuItem;
        mPreferences: TMenuItem;
      mGo: TMenuItem;
        mBack: TMenuItem;
        mForward: TMenuItem;
        mStop: TMenuItem;
        mReload: TMenuItem;
        N3: TMenuItem;
        mHome: TMenuItem;
      mHelp: TMenuItem;
        mAbout: TMenuItem;
    pnlBtnNav: TPanel;
      tlbrButtons: TToolBar;
        tlbtnBack: TToolButton;
        tlbtnForward: TToolButton;
        tlbtnStop: TToolButton;
        tlbtnReload: TToolButton;
        tlbtnHome: TToolButton;
        tlbtnSplit1: TToolButton;
        tlbtnPrint: TToolButton;
        tlbtnSplit2: TToolButton;
        tlbtnProperties: TToolButton;
        tlbtnSplit3: TToolButton;
      edtAddress: TEdit;
      pnlThrobber: TPanel;
        nmtThrobber: TAnimate;
    pnlBrowser: TPanel;
    stsbrStatus: TStatusBar;
    imglstMainMenu: TImageList;
    imglstButtons: TImageList;
    imglstButtonsHot: TImageList;
    imglstButtonsDisabled: TImageList;
    prgrssbrProgress: TProgressBar;
    mzGecko: TMozillaBrowser;
    {### FORM METHODS ###}
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    {### MENUITEM METHODS}
    procedure mOpenClick(Sender: TObject);
    procedure mSaveAsClick(Sender: TObject);
    procedure mPageSetupClick(Sender: TObject);
    procedure mPrintPreviewClick(Sender: TObject);
    procedure mPrintClick(Sender: TObject);
    procedure mExitClick(Sender: TObject);
    procedure mCopyClick(Sender: TObject);
    procedure mClearSelectionClick(Sender: TObject);
    procedure mSelectAllClick(Sender: TObject);
    procedure mPreferencesClick(Sender: TObject);
    procedure mBackClick(Sender: TObject);
    procedure mForwardClick(Sender: TObject);
    procedure mStopClick(Sender: TObject);
    procedure mReloadClick(Sender: TObject);
    procedure mHomeClick(Sender: TObject);
    procedure mAboutClick(Sender: TObject);
    {### MOZILLA CONTROL METHODS ###}
    procedure mzGeckoStatusTextChange(Sender: TObject; const Text: WideString);
    procedure mzGeckoProgressChange(Sender: TObject; Progress, ProgressMax: Integer);
    procedure mzGeckoCommandStateChange(Sender: TObject; Command: Integer; Enable: WordBool);
    procedure mzGeckoDownloadBegin(Sender: TObject);
    procedure mzGeckoDownloadComplete(Sender: TObject);
    {### MISC METHODS ###}
    procedure edtAddressKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  private
    { Private declarations }
    function CharReplace(var S: AnsiString; const Search, Replace: AnsiChar): Integer;
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

uses CommCtrl, Globals, OpenForm, PrefsForm;


var
  ON_START : boolean;


{### FORM METHODS ###}


procedure TfrmMain.FormCreate(Sender: TObject);
{initialise...}
begin
  {setup window}
  Application.Title := PROGRAM_TITLE;
  Self.Caption := PROGRAM_TITLE;
  {move progress bar to status bar's first panel}
  prgrssbrProgress.Parent := stsbrStatus;
  prgrssbrProgress.Top := 2;
  prgrssbrProgress.Left := 2;
  prgrssbrProgress.Height := stsbrStatus.Height - 2;
  prgrssbrProgress.Width := stsbrStatus.Panels[0].Width - 2;
  prgrssbrProgress.Position := 0;
  prgrssbrProgress.Refresh;
  {setup vars}
  ON_START := true;
end; {procedure TfrmMain.FormCreate}

procedure TfrmMain.FormShow(Sender: TObject);
{navigate to start page if first show}
begin
  if ON_START then begin
    ON_START := false;
    {show start page}
    case START_TYPE of
  //    0 : {blank page}
      1 : mzGecko.Navigate(WideString(HOME_ADDRESS)); {home page}
      2 : mzGecko.Navigate(WideString(START_ADDRESS)); {custom start page}
      end; {case START_TYPE..}
    end; {if ON_START..}
end; {procedure TfrmMain.FormShow}


{### MENUITEM METHODS ###}


procedure TfrmMain.mOpenClick(Sender: TObject);
{open web page from URL or file}
var
  Address : string;
  frmOpen: TfrmOpen;
begin
  {show open page dialog - frmOpen}
  frmOpen := TfrmOpen.Create(self);
  try
    if (frmOpen.ShowModal = mrOk) then begin
      {retrieve address}
      Address := frmOpen.edtURL.Text;
      if not(trim(Address) = '') then begin
        {navigate to address}
        CharReplace(Address, '\', '/'); {correct bug with relative links + images}
        mzGecko.Navigate(WideString(Address));
        end; {if not(Address = ''..}
      end; {if mrOk..}
  finally
    {free dialog}
    frmOpen.Free;
    end; {try..finally..}
end; {procedure TfrmMain.mOpenClick}

procedure TfrmMain.mSaveAsClick(Sender: TObject);
{show Save As dialog}
{Control <= v1.6: OLECMDEXECOPT_PROMPTUSER causes EOleException due to bug in flag
 tests, use OLECMDEXECOPT_DODEFAULT instead; Bugzilla 2250454.
 Control v1.7: Flag tests fixed so can use OLECMDEXECOPT_PROMPTUSER; Bugzilla 2250454
var
  PageFilename : OleVariant;
begin
  try
    {ensure not busy}
    if not(mzGecko.Busy) then begin
      PageFilename := mzGecko.LocationName + '.html';
      {show save as dialog}
      mzGecko.ExecWB(OLECMDID_SAVEAS, OLECMDEXECOPT_PROMPTUSER {OLECMDEXECOPT_DODEFAULT}, PageFilename);
      end; {if not Busy..}
  except
    {handle exceptions}
    on E : Exception do
      MessageDlg('ERROR: Unable to show Save As dialog. ' + #13 + E.ClassName
        + ': ' + E.Message + '.', mtError, [mbOk], 0);
    end; {try..except..}
end; {procedure TfrmMain.mSaveAsClick}

procedure TfrmMain.mPageSetupClick(Sender: TObject);
{show Page Setup dialog}
{Control <= v1.6: OLECMDEXECOPT_PROMPTUSER causes EOleException due to bug in flag tests,
 use OLECMDEXECOPT_DODEFAULT instead + get 'not implemented' dialog; Bugzilla 2250454.
 Control v1.7: Flag tests fixed so can use OLECMDEXECOPT_PROMPTUSER and Page Setup
 has been implemented; Bugzilla 2250454 fixed.}
begin
  try
    {ensure not busy or printing before showing dialog}
    if not(mzGecko.Busy) and (mzGecko.QueryStatusWB(OLECMDID_PAGESETUP) > 0)
      {show page setup dialog}
      then mzGecko.ExecWB(OLECMDID_PAGESETUP, OLECMDEXECOPT_PROMPTUSER {OLECMDEXECOPT_DODEFAULT});
  except
    {handle exceptions}
    on E : Exception do
      MessageDlg('ERROR: Unable to show Page Setup dialog. ' + #13 + E.ClassName
        + ': ' + E.Message + '.', mtError, [mbOk], 0);
    end; {try..except..}
end; {procedure TfrmMain.mPageSetupClick}

procedure TfrmMain.mPrintPreviewClick(Sender: TObject);
{show Print Preview window}
{OLECMDID_PRINTPREVIEW not currently supported in Mozilla Control although
 QueryStatusWB returns OLECMDF_SUPPORTED so disable menu item.
 OLECMDID_PRINTPREVIEW not defined in MozillaBrowser.h; Bugzilla 214884.}
begin
  try
    {ensure not busy or printing before showing dialog}
    if not(mzGecko.Busy) and (mzGecko.QueryStatusWB(OLECMDID_PRINTPREVIEW) > 0)
      {show Print Preview window}
      then mzGecko.ExecWB(OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_PROMPTUSER);
  except
    {handle exceptions}
    on E : Exception do
      MessageDlg('ERROR: Unable to show Print Preview dialog. ' + #13 + E.ClassName
        + ': ' + E.Message + '.', mtError, [mbOk], 0);
    end; {try..except..}
end; {procedure TfrmMain.mPrintPreviewClick}

procedure TfrmMain.mPrintClick(Sender: TObject);
{print current page}
begin
  try
    {ensure not busy or printing before showing dialog}
    if not(mzGecko.Busy) and (mzGecko.QueryStatusWB(OLECMDID_PRINT) > 0)
      {show Print dialog}
      then mzGecko.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER);
  except
    {handle exceptions}
    on E : Exception do
      MessageDlg('ERROR: Unable to show Print dialog. ' + #13 + E.ClassName
        + ': ' + E.Message + '.', mtError, [mbOk], 0);
    end; {try..except..}
end; {procedure TfrmMain.mPrintClick}

procedure TfrmMain.mExitClick(Sender: TObject);
{close application}
begin
  {close frmMain - closes app}
  Self.Close;
end; {procedure TfrmMain.mExitClick}

procedure TfrmMain.mCopyClick(Sender: TObject);
{copy selection to clipboard}
begin
  try
    {copy selection}
    mzGecko.ExecWB(OLECMDID_COPY, OLECMDEXECOPT_DODEFAULT);
  except
    {handle exceptions}
    on E : Exception do begin
      MessageDlg('ERROR:'#13'Unable to Copy selected text to clipboard.' + #13 + E.ClassName
        + ': ' + E.Message + '.', mtError, [mbOk], 0);
      end; {on Exception..}
    end; {try..except..}
end; {procedure TfrmMain.mCopyClick}

procedure TfrmMain.mClearSelectionClick(Sender: TObject);
{clear selection}
{OLECMDID_CLEARSELECTION not currently supported in Mozilla Control although
 QueryStatusWB returns OLECMDF_SUPPORTED so disable menu item.
 OLECMDID_CLEARSELECTION not defined in MozillaBrowser.h; Bugzilla 214884.}
begin
  try
    {clear selection}
    mzGecko.ExecWB(OLECMDID_CLEARSELECTION, OLECMDEXECOPT_DODEFAULT);
  except
    {handle exceptions}
    on E : Exception do begin
      MessageDlg('ERROR:'#13'Unable to Clear the current selection.' + #13 + E.ClassName
        + ': ' + E.Message + '.', mtError, [mbOk], 0);
      end; {on Exception..}
    end; {try..except..}
end; {procedure TfrmMain.mClearSelectionClick}

procedure TfrmMain.mSelectAllClick(Sender: TObject);
{select entire page}
begin
  try
    {select all}
    mzGecko.ExecWB(OLECMDID_SELECTALL, OLECMDEXECOPT_DODEFAULT);
  except
    {handle exceptions}
    on E : Exception do begin
      MessageDlg('ERROR:'#13'Unable to Select All text on page.' + #13 + E.ClassName
        + ': ' + E.Message + '.', mtError, [mbOk], 0);
      end; {on Exception..}
    end; {try..except..}
end; {procedure TfrmMain.mSelectAllClick}

procedure TfrmMain.mPreferencesClick(Sender: TObject);
{edit Gecko Browser prefs}
var
  frmPrefs: TfrmPrefs;
begin
  {show Preferences dialog - frmPrefs}
  frmPrefs := TfrmPrefs.Create(self);
  try
    if (frmPrefs.ShowModal = mrOk) then begin
      {correct addresses}
      CharReplace(START_ADDRESS, '\', '/'); {correct bug with relative links + images}
      CharReplace(HOME_ADDRESS, '\', '/'); {correct bug with relative links + images}
      end; {if mrOk..}
  finally
    {free dialog}
    frmPrefs.Free;
    end; {try..finally..}
end; {procedure TfrmMain.mPreferencesClick}

procedure TfrmMain.mBackClick(Sender: TObject);
{go Back a page}
begin
  {back}
  mzGecko.GoBack;
end; {procedure TfrmMain.mBackClick}

procedure TfrmMain.mForwardClick(Sender: TObject);
{go Forward a page}
begin
  {forward}
  mzGecko.GoForward;
end; {procedure TfrmMain.mForwardClick}

procedure TfrmMain.mStopClick(Sender: TObject);
{stop loading page}
begin
  {stop}
  mzGecko.Stop;
end; {procedure TfrmMain.mStopClick}

procedure TfrmMain.mReloadClick(Sender: TObject);
{reload page}
begin
  {refresh}
  mzGecko.Refresh;
end; {procedure TfrmMain.mReloadClick}

procedure TfrmMain.mHomeClick(Sender: TObject);
{go to Home page}
begin
  {navigate to Gecko Browser Home}
  mzGecko.Navigate(WideString(HOME_ADDRESS));
end; {procedure TfrmMain.mHomeClick}

procedure TfrmMain.mAboutClick(Sender: TObject);
{show simple About dialog}
begin
  MessageDlg(PROGRAM_TITLE + #13 + '(c) 2003 - 2004 Conspiracy Software' + #13
    + 'A demo of embedding Gecko (Mozilla) in Delphi applications.' + #13
    + 'Written by Dave Murray <irongut@vodafone.net>' + #13
    + PROGRAM_TITLE + ' was written using ' + MOZILLA_VERSION + '.',
    mtInformation, [mbOk], 0);
end; {procedure TfrmMain.mAboutClick}


{### MOZILLA CONTROL METHODS ###}


procedure TfrmMain.mzGeckoStatusTextChange(Sender: TObject; const Text: WideString);
{show status text in stsbrStatus}
begin
  stsbrStatus.Panels[1].Text := Text;
end; {procedure TfrmMain.mzGeckoStatusTextChange}

procedure TfrmMain.mzGeckoProgressChange(Sender: TObject; Progress, ProgressMax: Integer);
{show download progress}
begin
  {new code suggested by Sterling Bates, see Bugzilla #225041}
  prgrssbrProgress.Position := Round((Progress / ProgressMax) * 100);
  prgrssbrProgress.Max := 100;
end; {procedure TfrmMain.mzGeckoProgressChange}

procedure TfrmMain.mzGeckoCommandStateChange(Sender: TObject; Command: Integer; Enable: WordBool);
{fired when user navigates, use to enable/disable navigation buttons}
const
  {from SHDocVw.pas}
  CSC_NAVIGATEFORWARD = $00000001;
  CSC_NAVIGATEBACK = $00000002;
begin
  if (Command = CSC_NAVIGATEFORWARD) then begin
    {enable / disable Forward button + menu item}
    tlbtnForward.Enabled := Enable;
    mForward.Enabled := Enable;
    end {if Command = CSC_NAVIGATEFORWARD}
  else if (Command = CSC_NAVIGATEBACK) then begin
    {enable / disabel Back button + menu item}
    tlbtnBack.Enabled := Enable;
    mBack.Enabled := Enable;
    end; {else if..}
end; {procedure TfrmMain.mzGeckoCommandStateChange}

procedure TfrmMain.mzGeckoDownloadBegin(Sender: TObject);
{begining navigation, start throbber}
begin
  nmtThrobber.Active := true;
end; {procedure TfrmMain.mzGeckoDownloadBegin}

procedure TfrmMain.mzGeckoDownloadComplete(Sender: TObject);
{ending navigation, stop throbber + ensure edtAddress shows URL}
var
  URL : string;
begin
  URL := mzGecko.LocationURL;
  if not(edtAddress.Text = URL) then edtAddress.Text := URL;
  nmtThrobber.Active := false;
  prgrssbrProgress.Position := 0;
end; {procedure TfrmMain.mzGeckoDownloadComplete}


{### MISC METHODS ###}


procedure TfrmMain.edtAddressKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
{navigate to current address}
begin
  if (Key = VK_RETURN) then mzGecko.Navigate(WideString(edtAddress.Text));
end; {procedure TfrmMain.edtAddressKeyDown}


{### PRIVATE METHODS ###}


function TfrmMain.CharReplace(var S: AnsiString; const Search, Replace: AnsiChar): Integer;
{Reproduced from JEDI Code Library JclStrings.pas for demonstration purposes.}
{http://www.delphi-jedi.org/}
var
  P: PAnsiChar;
begin
  Result := 0;
  if Search <> Replace then
  begin
    UniqueString(S);
    P := PAnsiChar(S);
    while P^ <> #0 do
    begin
      if P^ = Search then
      begin
        P^ := Replace;
        Inc(Result);
      end;
      Inc(P);
    end;
  end;
end; {function TfrmMain.CharReplace}


initialization
OleInitialize(nil);

finalization
OleUninitialize;

end.

Zip Download the source code.

Refer this page to a friend!

Copyright © 2003 - 2010 Conspiracy Software. All Rights Reserved.