Reputation: 590
I have an application that the user can run either interactively or from command line. In the second mode, the program must exit upon completion.
Here is the basic minimal code. It seems that application.terminated is never set;
How do I get this program to close, w/o0 user interaction.
unit Unit4;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls ;
type
TForm4 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
procedure DoSomeStuff;
{ Private declarations }
public
{ Public declarations }
end;
var
Form4: TForm4;
implementation
{$R *.dfm}
procedure TForm4.Button1Click(Sender: TObject);
var
anonThread : TThread;
begin
anonThread := TThread.CreateAnonymousThread(procedure
begin
while not application.terminated do
begin
doSomeStuff;
end;
end);
anonThread.Start;
end;
procedure TForm4.DoSomeStuff;
var
i : integer;
begin
for i := 0 to 10 do
begin
beep;
sleep(100);
end;
application.Terminate;
end;
end.
Upvotes: 0
Views: 57
Reputation: 596703
The Application.Terminated
property doesn't work without the message loop in Application.Run()
(or at least a manual loop that calls Application.ProcessMessages()
) in the main UI thread. This is because Application.Terminate()
simply posts a WM_QUIT
message to the calling thread's message queue. Application.Terminated
is not set until that message is processed. A console app typically does not call Application.Run()
, so Application.Terminated
does not work on a console app.
You should redesign your code to remove the dependency on Application
and your TForm
in console mode, eg:
program MyApp;
uses
MyWorkUnit, Unit4;
begin
if IsRunInCommandLineMode then
begin
DoSomeStuff;
end else
begin
Application.Initialize;
Application.CreateForm(TForm4, Form4)
Application.Run;
end;
end.
unit MyWorkUnit;
interface
procedure DoSomeStuff;
implementation
procedure DoSomeStuff;
var
i : Integer;
begin
for i := 0 to 10 do
begin
Beep;
Sleep(100);
end;
end;
end.
unit Unit4;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm4 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form4: TForm4;
implementation
{$R *.dfm}
uses
MyWorkUnit;
procedure TForm4.Button1Click(Sender: TObject);
begin
TThread.CreateAnonymousThread(
procedure
begin
while not Application.Terminated do
DoSomeStuff;
end
).Start;
end;
end.
Upvotes: 1