前面所讲的实现没有多大问题,但这种处理最合适的是放在 OnIdle 事件中:
也不需要 TTimer ,
The following code demonstrates background processing using the OnIdle event, and using the HandleMessage method to permit messages or background processing to get through.
Note: You must add MyIdleHandler to the Form1 methods.
var
{ global variables to show the order of events. }
XPos, YPos, Delta: integer;
{ This is a utility procedure to display messages }
{ add this at the beginning of the implementation section }
procedure StatusMsg(MyForm : TForm; Canvas : TCanvas; Message : string; Bkg : Boolean);
begin
if not bkg then
Canvas.Font.Style := [fsBold]; {foreground messages are bold }
Canvas.TextOut(XPos, YPos, Message);
if not bkg then
Canvas.Font.Style := [];
{ change Xpos and YPos to prepare for the next message }
Ypos := Ypos + Delta;
if YPos >= MyForm.ClientHeight then
begin
YPos := 10;
Xpos := Xpos + 100;
end;
if (Xpos >= MyForm.ClientWidth - 100) then
begin
if (Canvas.Font.Color = clRed) then
Canvas.Font.Color := clBlack;
else
Canvas.Font.Color := clRed;
Xpos := 10;
end;
end;
{This is the Form抯 OnCreate event handler. }
{ It initializes global variables and sets the the OnIdle event handler }
procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.Caption := 'Do not yield';
Button2.Caption := 'Handle Message';
Application.OnIdle:= MyIdleHandler;
XPos := 10;
YPos := 10;
Delta := Abs(Canvas.Font.Height) + 1;
end;
{ This is the OnIdle event handler. It is set in the Form抯 OnCreate event handler, so you need only add it as a private method of the form. Usually it would perform some background processing for the application. This one simply writes a message to let you know when it抯 there. }
procedure TForm1.MyIdleHandler(Sender: TObject; var Done: Boolean);
begin
StatusMsg(TForm1, Canvas, 'This represents a background process.', True);
end;
{ Set this method as the OnClick event handler of Button1. It performs a calculation without yielding to other messages or idle time. }
procedure TForm1.Button1Click(Sender: TObject);
var
I, J, X, Y: Word;
begin
StatusMsg(TForm1, Canvas, 'The Button1Click handler is starting', False);
I := 0;
J := 0;
while I < 10 do
begin
Randomize;
while J < 10 do
begin
Y := Random(J);
Inc(J);
end;
X := Random(I);
Inc(I);
end;
StatusMsg(TForm1, Canvas, 'The Button1Click handler is done', False);
end;
{ Set this method as the OnClick event handler of Button2. It performs a calculation but calls HandleMessage to allow idle time or asynchronous message processing. }
procedure TForm1.Button2Click(Sender: TObject);
var
I, J, X, Y: Word;
begin
StatusMsg(TForm1, Canvas, 'The Button2Click handler is starting', False);
I := 0;
J := 0;
while I < 10 do
begin
Randomize;
while J < 10 do
begin
Y := Random(J);
Inc(J);
Application.HandleMessage; { yield to OnIdle or other messages }
end;
X := Random(I);
Inc(I);
end;
StatusMsg(TForm1, Canvas, 'The Button2Click handler is done', False);
end;