我一直在使用TForm
的{{1}}事件让我有机会在我的应用启动后立即显示一个对话框。我希望主表单已经加载&可见。有什么好办法呢?
我发现OnActivate
工作正常,除非表单OnActivate
是WindowState
。
过去我以各种方式完成了我想要的东西,但我希望有更好的方法。
这对我有用:
wsMaximized
有更好的方法吗?
答案 0 :(得分:17)
在表单的OnCreate事件处理程序中发布用户消息并在消息处理程序中显示对话框:
unit Unit1;
interface
const
UM_DLG = WM_USER + $100;
type
TForm1 = class(TForm)
...
procedure UMDlg(var Msg: TMessage); message UM_DLG;
...
implementation
procedure TForm1.FormCreate(Sender: TObject);
begin
PostMessage(Handle, UM_DLG, 0, 0);
end;
procedure TForm1.UMDlg(var Msg: TMessage);
begin
form2 := TForm2.Create(Application);
form2.ShowModal;
end;
虽然我发现计时器方法更好:只需在表单上删除一个计时器组件,将Interval设置为100(ms)并实现OnTimer事件:
procedure Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False; // stop the timer - should be executed only once
form2 := TForm2.Create(Application);
form2.ShowModal;
end;
两种方法的区别在于:
当从OnCreate或OnShow处理程序发布用户消息时,将使用正常优先级调度消息,这意味着其他窗口初始化消息可能会在其后发布和处理。实质上,WM_PAINT消息将在UM_DLG消息之后处理。如果UM_DLG消息需要很长时间才能处理而不会抽取消息队列(例如,打开数据库连接),那么表单将显示为空白而不绘制客户区域。
WM_TIMER消息是一个低优先级消息,并且意味着首先处理表单初始化消息,然后才会处理WM_TIMER消息,即使在表单创建完成之前发布了WM_TIMER消息。
答案 1 :(得分:1)
我最终做的方式是使用Application.OnIdle事件。这不是一个完美的解决方案,但它确实适用于我的情况。谢谢大家的答案!
答案 2 :(得分:1)
在MainForm的OnShow
事件中,您可以执行以下操作之一以在允许MainForm首先完成完全显示自身的延迟之后显示对话框:
PostMessage()
给自己的自定义窗口消息。TThread.CreateAnonymousThread()
或TTask
呼叫TThread.Queue()
。TThread.ForceQueue()
(仅限10.2东京及以后)。答案 3 :(得分:0)
我很久以前就看到过这样做的方法,它总是对我有用。
在您的主要表单OnCreate方法中,在您完成此方法通常执行的任何操作后,添加以下行:
Self.Show;
这将显示主窗体。
然后,输入代码以显示对话框。
运行时,您的主表单将立即显示在您的对话框中。
答案 4 :(得分:0)
嗯,我不知道这是不是最好的实践,但我确实喜欢这个:
在PROGRAM文件(.dpr - 我使用Delphi 7)中,我添加以下行:
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Form1.Show; // Show Main Form
Form1.Button1.Click; // Call event/function
Application.Run;
end.
如果不是最好的实践,请有人纠正我!
希望对你有所帮助!