主窗体
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,LongWaitTrd; type TForm1 = class(TForm) btnSetTask: TButton; btnExitThd: TButton; btnCreateTrd: TButton; procedure btnSetTaskClick(Sender: TObject); procedure btnCreateTrdClick(Sender: TObject); procedure btnExitThdClick(Sender: TObject); private LongWaitThread:TLongWaitTrd; procedure OnThreadMessage(var Message: TMessage); message WM_USER+2000; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.btnSetTaskClick(Sender: TObject); begin if (LongWaitThread<>nil) then PostThreadMessage(LongWaitThread.ThreadID,WM_USER+1000,0,0); end; procedure TForm1.btnCreateTrdClick(Sender: TObject); begin LongWaitThread:=TLongWaitTrd.Create(true); LongWaitThread.MainWin:=Handle; LongWaitThread.Resume; end; procedure TForm1.OnThreadMessage(var Message: TMessage); begin if Message.Msg= WM_USER+2000 then begin Showmessage(String(message.LParam)); end; end; procedure TForm1.btnExitThdClick(Sender: TObject); begin if (LongWaitThread<>nil) then begin if (not LongWaitThread.ExitLongWaitTrd()) then ShowMessage('The thread exited time out'); end; end; end.
线程单元
unit LongWaitTrd; interface uses Classes,Windows,Messages,SyncObjs,SysUtils; type TLongWaitTrd = class(TThread) private FMainWin:THandle; QuitEvent: TEvent; procedure SendFeedBackToMainWin(); procedure DoTheHardWork(); protected procedure Execute; override; public constructor Create(CreateSuspended: Boolean); destructor Destroy; override; function ExitLongWaitTrd():Boolean; published property MainWin:THandle read FMainWin write FMainWin; end; implementation uses Unit1; constructor TLongWaitTrd.Create(CreateSuspended: Boolean); begin inherited Create(CreateSuspended); end; destructor TLongWaitTrd.Destroy; begin inherited; end; procedure TLongWaitTrd.DoTheHardWork(); begin end; procedure TLongWaitTrd.Execute; var Msg: TMsg; begin FreeOnTerminate:=True; // while GetMessage(Msg, 0, 0, 0) do // begin // if (Msg.message=WM_USER+1000) then //任务来了 // begin // DoTheHardWork(); // SendFeedBackToMainWin; // end; // if (Msg.message=WM_QUIT) then // begin // QuitEvent.SetEvent; // Break; // end; // end; // while(true) do // begin // if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then // begin // if (Msg.message=WM_QUIT) then // begin // QuitEvent.SetEvent; // Break; // end; // end; // DoTheHardWork(); // end; end; function TLongWaitTrd.ExitLongWaitTrd; begin Result:=true; QuitEvent:=TEvent.Create(nil,True,False,'QuitEvent'); PostThreadMessage(ThreadID,WM_QUIT,0,0); if (QuitEvent.WaitFor(3000)=wrTimeOut) then Result:=false; QuitEvent.Free ; end; procedure TLongWaitTrd.SendFeedBackToMainWin(); var Status:String; begin if (MainWin<>0) then begin Status:='The data has been processed by thread.'; PostMessage(MainWin,WM_USER+2000,0,Integer(Status)) end; end; end.