The Mozilla ActiveX Control can be used to display html in Delphi 4 applications but there is a VCL bug and other problems to overcome. This article provides solutions to these problems and a reworked GeckoBrowser framework for Delphi 4. I am assuming that you have already read my article Taming the Lizard with Delphi.

Figure 1 - Import ActiveX Dialog
Installing the Mozilla ActiveX Control is the same for Delphi 4 as for later versions. For this article I've used the Mozilla ActiveX Control v1.6 package from Adam Lock. It installs the GRE and the necessary support files and then registers the control.
The Mozilla ActiveX Control is imported 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.
The GeckoBrowser project from Taming the Lizard with Delphi was written with Delphi 6 and due to changes between versions I can't just open it in Delphi 4. The most obvious problem is that the *.dfm file format is different. It would be time consuming to redo the forms from scratch but I have a cunning plan... I start a new project in Delphi 4 and add two forms to it then right-click on the forms and select View as Text from the menu. I then open my Delphi 6 *.dfm files for GeckoBrowser in a text editor and copy the text to replace that in the forms in Delphi 4. I then save those forms, overwriting the Delphi 6 ones, and 'hey presto!' they've been magically downgraded.
Now, opening the GeckoBrowser project in Delphi 4 causes a few error messages about missing
components and incorrect property values. They are noted and ignored to get the project to load.
The error messages are because TLabeledEdit and the TForm.Position property
that I used did not exist in Delphi 4. The property value errors are easily sorted by changing
TfrmOpen.Position and TfrmPrefs.Position to poDesktopCenter.
There are two TLabeledEdit components on TfrmPrefs, edtCustomStartPage
and edtHomePage. I have replaced them with two TEdit components that are
also named edtCustomStartPage and edtHomePage and a pair of similarly
named TLabels.
There are two other minor changes that need to be made. The Variants unit doesn't
exist in Delphi 4 so it must be removed from the uses clauses of all the *.pas files
in the project. And, the location of the throbber animation is slightly different in each version
of Delphi (Delphi4\Demos\CoolStuf\Cool.avi).

Figure 2 - TfrmMain
Compiling the project at this point produced several 'Not enough actual parameters' errors.
This is because when Delphi 4 produced MOZILLACONTROLLib_TLB.pas from the type library
contained in the Mozilla ActiveX Control it did not provide overloaded methods for optional
parameters but just one method taking all the parameters.
i.e. Delphi 4 produces:
procedure Navigate(const URL: WideString; var Flags: OleVariant;
var TargetFrameName: OleVariant; var PostData: OleVariant; var Headers: OleVariant);
But Delphi 6 produces:
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;
In each method where I call Navigate or ExecWB (which have optional
parameters) I've declared a local variable temp : OleVariant which is assigned to
null. Then where I'm not using a parameter that should be optional I pass that variable.
e.g. :
procedure TfrmMain.edtAddressKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
{navigate to current address}
var
temp : OleVariant;
begin
if (Key = VK_RETURN) then mzGecko.Navigate(WideString(edtAddress.Text), temp, temp, temp, temp);
end; {procedure TfrmMain.edtAddressKeyDown}
Having adapted the GeckoBrowser framework for Delphi 4 I can now move on to a meatier problem. Namely, that Delphi 4 applications cause floating point exceptions in Gecko. To be more precise, using one of the Delphi 4 VCL's common dialogs (TOpenDialog, TSaveDialog, etc) can cause random floating point exceptions in various Gecko dlls. Thankfully, this problem has been solved by Nick Bradbury, creator of TopStyle.

Figure 3 - Floating Point Exception
The problem is that after any common dialog is displayed, Delphi 4 changes the FPU control
word. This is done because some libraries (Microsoft's) want the FPU to be set in 64 bit precision,
whereas Delphi expects 80 bit precision. This call causes Gecko to crash. The offending code is in
the TCommonDialog.TaskModalDialog method in dialogs.pas and has been fixed in Delphi 5
and later. To fix this you need to alter dialogs.pas and recompile it which is more awkward than you'd
expect. Here is the fixed TCommonDialog.TaskModalDialog with the original code commented out:
function TCommonDialog.TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool;
type
TDialogFunc = function(var DialogData): Bool stdcall;
var
ActiveWindow: HWnd;
WindowList: Pointer;
FPUControlWord: Word; // GECKO
begin
ActiveWindow := GetActiveWindow;
WindowList := DisableTaskWindows(0);
try
Application.HookMainWindow(MessageHook);
asm // GECKO
FNSTCW FPUControlWord // GECKO
end; // GECKO
try
CreationControl := Self;
Result := TDialogFunc(DialogFunc)(DialogData);
// ORIGINAL Set8087CW(Default8087CW);
finally
asm // GECKO
FNCLEX // GECKO
FLDCW FPUControlWord // GECKO
end; // GECKO
Application.UnhookMainWindow(MessageHook);
end;
finally
EnableTaskWindows(WindowList);
SetActiveWindow(ActiveWindow);
end;
end;
Here's the process for fixing this bug in your Delphi 4 VCL:
This article shows how to fix a problem in the Delphi 4 VCL that causes floating point exceptions when using the Mozilla ActiveX Control. It also provides a workaround for problems with the inadequate header file Delphi 4 produces from the control's type library. The source code accompanying this article is a basic browser framework that can be used to demonstrate or test the Mozilla ActiveX Control with Delphi 4. Feel free to use and abuse it as you wish.
Mozilla ActiveX Control
Taming the Lizard with Delphi
|
Download this article in eBook format. You can download a free eBook reader for PalmOS, PocketPC, MacOS, Symbian or Windows. |
|
Download the source code. |