【发布时间】:2019-08-13 11:03:58
【问题描述】:
在一个 Delphi VCL 应用程序中,我想创建一个“等待”消息窗口,因为这是一个耗时的过程(本例中是一个大的无用循环)。
在我开始耗时的过程之前,我尝试了以下要执行的事情。
-创建一个包含消息的简单窗口的新形式。
-使用 messagedlg 创建消息。
-甚至更改主窗体上的 TLabel.Caption(执行耗时过程的那个)。
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
popUpMessage;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
dialog : TForm;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var i, j, k :LongInt;
begin
{1}
popUpMessage.Form2 := TForm2.Create(nil); //also tried with Create(self)
Form2.show;
{2}
dialog := CreateMessageDialog ('Wait',TMsgDlgType.mtWarning, mbYesNoCancel);
dialog.Show;
{3}
messagedlg('Wait',mtError, mbOKCancel, 0);
{4}
Label1.Caption := 'Wait';
//Time consuming process
for i := 0 to 200000 do
for j := 0 to 20000do
k := i-j;
end;
end.
在 {1} 和 {2} 的情况下,弹出表单在耗时的过程开始之前出现,但它们的组件仅在此完成后才绘制。
案例 {3} 保持执行直到模式对话框关闭。
如果{4}在耗时的过程完成后字幕发生变化。
如何异步创建消息,使其完全绘制而不等待其父进程?
【问题讨论】:
-
你必须把你的耗时过程放到一个单独的线程上。
-
@nolaspeaker ,这不就是把弹窗放到单独的线程里吗?
-
由于您可能很快也会被
ProcessMessages的黑暗恶魔诱惑,这里有一些额外的相关阅读:I do not understand what Application.ProcessMessages in Delphi is doing -
@Mikemik 您不能将弹出窗口放在单独的线程上。在 Delphi 中,UI(用户界面)线程是您的“显示”所在的位置。这就是为什么您必须为其他所有内容创建一个单独的线程。而且你永远不应该做任何在线程中“显示”的事情。请参阅下面 J... 的答案。
标签: delphi asynchronous non-modal