如何顯示子線程的當(dāng)前狀態(tài)  
       剛剛完成的一個小程序是分析使用豎向排列的24針打印頭打印一個數(shù)據(jù)文件,分析每根針的出針次數(shù)等一些參數(shù),給機械開發(fā)部門做壽命分析等等。
 
       由于數(shù)據(jù)文件可能很大,分析時間會比較長,因此要能夠顯示分析進度,否則讓比人以為程序死掉了那不是人生一大憾事。
 
       因此,分析工作放在子線程中進行,通過產(chǎn)生“狀態(tài)改變事件”和“分析結(jié)束事件”來通知主線程更新狀態(tài)。線程定義如下:
//==================================
//  MyThread.pas
//===================================//
 
TStatusChangedEvent = PRocedure (Percent: Integer) of Object;  //狀態(tài)改變事件 TFinishedEvent = procedure of Object; // 分析結(jié)束事件
 
TMyThread = class(TThread)
Private
  FOnStatusChanged: TStatusChangedEvent; 
  FOnFinished: TFinishedEvent;
protected
  procedure Execute; override;
public
  OnStatusChanged: TStatusChangedEvent read FOnStatusChanged write FOnStatusChanged;
  OnFinished: TFinishedEvent read FOnFinished write FOnFinished;
end;
 
procedure TMyThread.Execute; 
var
  Percent: Integer;
begin
  ...
    if (Percent 發(fā)生了改變) and Assigned(FOnStatusChanged) then
      FOnStatusChanged (Percent);
  ...
  
  // 分析結(jié)束
  if Assigned (FOnFinished) then
    FOnFinished;  // 在分析結(jié)束時通知主線程
end;
 
狀態(tài)顯示由一個窗體實現(xiàn),該窗體有一個進度條,一個狀態(tài)Label,一個取消按鈕,以及一個定時器。定義如下(沒有給出進度條、Label、按鈕的代碼)
//=====================================
//  TFrmStatus.pas
//=====================================//
  
TFrmStatus = class (TForm)   // 顯示進度的窗體
  Timer1: TTimer;
  Procedure FormCreate (Sender: TObject);
Private
  Procedure SetPercent (Value: Integer);
  Procedure SetTerminate (Value: Boolean);  
Public
  Property Percent: Integer read FPercent write SetPercent;
  Property Terminate: Boolean read FTerminate write SetTerminate;
End;
 
Procedure TFrmStatus. FormCreate (Sender: TObject);
begin
  FTerminate := false;
  Timer1.enable := false;  
end;
 
procedure TFrmStatus. SetPercent(Value: Integer);  // 設(shè)置百分比進度
begin
  // 設(shè)置控件狀態(tài)以表示當(dāng)前的百分比進度
end;
 
procedure TFrmStatus.SetTerminate(Value: boolean;)  // 設(shè)置結(jié)束狀態(tài)
begin
  if FTerminate <> Value then
  begin
    FTerminate := Value;
    Timer1.Interval := 2;
    Timer1.Enable := true;
  end;
end;
 
procedure TFrmStatus.Timer1Timer(Sender: TObject); // 響應(yīng)定時器,關(guān)閉窗口,返回mrOk
begin
  Close;
  ModalResult := mrOk;
end;
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
主窗體負責(zé)創(chuàng)建分析線程和狀態(tài)顯示窗體,并響應(yīng)分析線程產(chǎn)生的“狀態(tài)改變事件”和“分析結(jié)束事件”。
// 主窗體
TFrmMain := class(TForm)
private
  FFrmStatus: TFrmStatus;
  procedure DoStatusChange(Percent: Integer); // 響應(yīng)分析進度改變事件
  procedure DoFinished; // 響應(yīng)分析結(jié)束事件
public
  procedure Do;
end;
 
// 運行分析
procedure TFrmMain.Do;
var
  MyThread: TMyThread;
  FrmStatus: TFrmStatus;
begin
  try
    MyThread := TMyThread.Create(true);
    MyThread.OnStatusChange := DoStatusChange;
    MyThread.OnFinished := DoFinished;
    try
      FrmStatus := TFrmStatus.Create(nil);
      FFrmStatus := FrmStatus;
      MyThread.Resume; // 啟動線程
      if FrmStatus.ShowModal = mrOk then
        ShowAnalyseResult; // 顯示分析結(jié)果
    finally
      FFrmStatus := nil;
      FrmStatus.Free;
    end;    
  finally
    MyThread.FreeOnTerminate := true;
    MyThread.Terminate;
  end;
end;
 
// 響應(yīng)狀態(tài)改變事件,顯示進度
procedure TFrmMain.DoStatusChange(Percent: Integer)
begin
  if FFrmStatus <> nil then
    FFrmStatus.Percent := Percent;
end;