I am trying to write an application with a main form that, OnCreate, calls another form that display a message while it checks for an internet connection. While this check is being done, I want the main form to continue to be accessible. Unfortunately, I cannot get it to work. I tried multithreading but then form2 displays briefly before disappearing. I know I'm doing something wrong but cannot figure it out.
For ease of figuring this out, I've made some dummy forms for testing. What I want is:
Form1 displays, Form1 opens Form2, Form2 pauses for 10 seconds and then displays a message. While Form2 is paused, I want to be able to still access Form1.
Unit1 (initial view; no multi-threading)
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Buttons;
type
{ TForm1 }
TForm1 = class(TForm)
BitBtn2: TBitBtn;
procedure BitBtn2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
uses Unit2;
{$R *.lfm}
{ TForm1 }
procedure TForm1.BitBtn2Click(Sender: TObject);
begin
ShowMessage('Test 1');
end;
procedure TForm1.FormCreate(Sender: TObject);
var
MyThread : TMyThread;
begin
frm2 := TForm2.Create(Application);
frm2.Show;
end;
end.
Unit2:
unit Unit2;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Buttons,
ExtCtrls;
type
{ TForm2 }
TForm2 = class(TForm)
BitBtn1: TBitBtn;
Timer1: TTimer;
procedure BitBtn1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
procedure TestMessage();
procedure Timer1Timer(Sender: TObject);
public
{ public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.lfm}
{ TForm2 }
procedure TForm2.BitBtn1Click(Sender: TObject);
begin
ShowMessage('Test 2');
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
Timer1.Interval := 4000;
Timer1.Ontimer := @Timer1Timer;
Timer1.Enabled := True;
end;
procedure TForm2.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
TestMessage();
end;
procedure TForm2.TestMessage();
var x:integer;
begin
for x:=1 to 10 do
sleep(1000);
showmessage('hello');
end;
end.
I then tried multi-threading from examples on the Lazarus Wiki:
Unit1 (multithreading):
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Buttons;
type
{ TForm1 }
TForm1 = class(TForm)
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
procedure BitBtn1Click(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
uses Unit3;
{$R *.lfm}
{ TForm1 }
procedure TForm1.BitBtn2Click(Sender: TObject);
begin
ShowMessage('Test 1');
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
var
MyThread : TMyThread;
begin
MyThread := TMyThread.Create(True);
MyThread.Resume;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
MyThread : TMyThread;
begin
MyThread := TMyThread.Create(True);
MyThread.Resume;
end;
end.
Unit2 stays the same as above
Unit3
unit Unit3;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms;
type
TMyThread = class(TThread)
protected
procedure Execute; override;
public
Constructor Create(CreateSuspended : boolean);
end;
implementation
uses Unit2;
constructor TMyThread.Create(CreateSuspended : boolean);
begin
FreeOnTerminate := True;
inherited Create(CreateSuspended);
end;
procedure TMyThread.Execute;
var
frm2 : TForm2;
begin
frm2 := TForm2.Create(Application);
frm2.Show;
end;
end.