2017-02-20 3 views
0

私は、ユーザーが対話形式でもコマンドラインからでも実行できるアプリケーションを持っています。第2のモードでは、プログラムは完了時に終了しなければならない。匿名スレッドアプリケーションを終了させない

ここに基本的な最小限のコードを示します。 application.terminatedは設定されていないようです。

ユーザーの操作なしでこのプログラムを閉じるにはどうすればよいですか。

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プロパティは、メインUIスレッドで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. 
関連する問題