2017-02-20 20 views
0

У меня есть приложение, которое пользователь может запускать в интерактивном режиме или из командной строки. Во втором режиме программа должна выйти по завершении.Анонимная тема, не позволяющая программе закрыть

Вот базовый минимальный код. Кажется, что application.terminated никогда не устанавливается;

Как мне закрыть эту программу, w/o0 взаимодействие с пользователем.

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. 

ответ

1

Application.Terminated Свойство не работает без цикла обработки сообщений в Application.Run() (или, по крайней мере, ручной цикл, который вызывает Application.ProcessMessages()) в главном потоке пользовательского интерфейса. Это связано с тем, что Application.Terminate() просто отправляет сообщение WM_QUIT в очередь сообщений вызывающего потока. Application.Terminated не установлен до тех пор, пока это сообщение не будет обработано. Консольное приложение обычно не вызывает Application.Run(), поэтому Application.Terminated не работает в консольном приложении.

Вы должны перестроить свой код, чтобы удалить зависимость от Application и вашей TForm в консольном режиме, например:

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. 

 Смежные вопросы

  • Нет связанных вопросов^_^