【发布时间】:2020-05-31 03:59:17
【问题描述】:
我有一个应用程序需要几秒钟才能加载(大量初始化)。 GUI 在启动期间冻结。所以我想创建一个在应用程序加载时淡入淡出的启动画面。 我使用TBackgroundWorker 组件在后台线程中做动画。
但是,当我使用此组件时,会发生一些奇怪的事情:当它发出“工作完成”信号时(请参阅 BackgroundWorkerWorkComplete),我同时打开的消息对话框会自动关闭。
procedure TMainForm.ButtonStartSplashClick(Sender: TObject);
VAR
frmSplash: TfrmSplash;
begin
frmSplash:= TfrmSplash.Create(NIL);
frmSplash.StartAnimation;
//MessageBox(Handle, 'Hi', nil, MB_OK); // This remains on screen
Application.MessageBox(PChar('Hi'), PChar('Box'), MB_ICONINFORMATION); // This is automatically closed when the background thread is done
end;
这是启动画面:
procedure TfrmSplash.StartAnimation;
begin
Show;
BackgroundWorker.Execute;
end;
procedure TfrmSplash.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:= caFree;
end;
procedure TfrmSplash.BackgroundWorkerWork(Worker: TBackgroundWorker);
VAR i: Integer;
begin
for i:= 1 to 255 DO
begin
AlphaBlendValue:= i; // do not access GUI directly from thread
Sleep(30);
end;
end;
procedure TfrmSplash.BackgroundWorkerWorkComplete(Worker: TBackgroundWorker; Cancelled: Boolean);
begin
Close; // At this point, the msg box will be closed also
end;
我觉得奇怪的是 MessageBox 保留在屏幕上,而 Application.MessageBox 没有(自动关闭)。
为什么关闭 TfrmSplash 也会关闭消息框?
【问题讨论】:
-
您阅读文档了吗? “您必须小心不要在 {OnWork} 事件处理程序中操纵任何用户界面对象。”不设置 AlphaBlendValue 时还会出现吗?
-
刚刚测试过。仍然发生。由于 GUI 访问,我希望得到一些随机的 AV。但无论如何,这不是原因,因为它发生在我注释掉 AlphaBlendValue:= i
-
为您的 AlphaBlend 代码使用报告进度事件。
-
@NasreddineGalfout - 好主意。谢谢/+1。但这不会解决消失的 msgbox 奇怪的问题。
-
@NasreddineGalfout 对于那个用例,老实说,我只会使用
TTimer。没有必要为了阻止一个繁忙的循环定期创建简单的事件而启动一个线程。
标签: multithreading delphi backgroundworker splash-screen tform