问题描述
我有一个Delphi项目,该项目由两种形式组成,即 MainForm 和 DialogForm 。当我单击 Button1 时,应出现 DialogForm 并停留在顶部,直到过程完成(该过程需要几秒钟才能完成)。
对话框表单包括一个图像组件。当我单击 Button1 以显示 DialogForm 时,会出现Gif图像,但没有动画。仅当过程开始时才会发生这种情况(动画不执行过程)。这是什么原因,以及如何保持动画直到关闭 DialogForm ?
?procedure TMainForm.Button1Click(Sender: TObject);
var
gif: TGIFImage;
begin
Enabled:=false;
try
DialogForm.Show;
DialogForm.Refresh;
// The process is:
...
ipcAES1.Encrypt;//where ipcAES is part of the IPWorks Encrypt library
RichEdit1.Text:=ipcAES1.OutputMessage;
finally
Enabled:= true;
DialogForm.Close;
end;
end;
//---------------------------------------
procedure TDialogForm.FormShow(Sender: TObject);
var
gif: TGIFImage;
begin
gif := TGIFImage.Create;
gif.LoadFromFile('D:\preview.gif');
gif.Animate := True;
image1.Parent := Self;
image1.Left := 0;
image1.Top := 0;
image1.width := 800;
image1.height := 800;
image1.Picture.Assign(gif);
gif.Animate := True;
gif.Free;
end;
解决方法
正如该线程中的许多人所说,由于处理是在主线程中完成的,因此在此过程中不会更新UI。
要确保在进程运行时更新UI,请让一个单独的线程进行处理:
procedure TForm1.Button1Click(Sender: TObject);
var
aProcessingThread: TThread;
begin
// First read all data needed by the process from UI controls (or other non-threadsafe parts)
<data> := ...;
// Then create a new (anonymous) thread with the code you need to run your process
aProcessingThread := TThread.CreateAnonymousThread(
procedure
begin
// create the objects you need to do the processing
ipcAES1 := Txxx.Create;
try
// Set the data
ipcAES1.<data> := <data>;
// Execute the proces:
// ...
ipcAES1.Encrypt;
finally
// When the process is done,use 'Synchronize' to interact with the UI
// again,so you can add the processed data to the RichtEdit and so on...
TThread.Synchronize(nil,procedure
begin
// Now you can interact again with the UI
RichEdit1.Text := ipcAES1.OutputMessage;
Enabled:= true;
DialogForm.Close;
end);
ipcAES1.Free;
end;
end);
// The thread is now created,but not started/running,so you can now show
// the dialog and then start the thread,at which point the ButtonClick event
// exists,but the progress dialog is shown and the thread is running.
Enabled := False;
DialogForm.Show;
aProcessingThread.Start;
end;
当然,这仅是一个基本示例,说明如何使用(匿名)线程在后台进行一些处理。 请注意,您需要处理线程内的异常(try / except)。
有关TGifImage加载的小技巧:只要在uses子句中包含Picture.LoadfromFile
,您就可以调用Vcl.Imaging.GIFImg
来加载gif。
procedure TForm1.FormShow(Sender: TObject);
begin
image1.Picture.LoadFromFile('D:\preview.gif');
image1.Parent := Self;
image1.Left := 0;
image1.Top := 0;
image1.width := Image1.Picture.Width;
image1.height := Image1.Picture.Height;
(image1.Picture.Graphic as TGIFImage).Animate := True;
end;