In the form's OnCreate event handler post a user message and show the dialog in the handler of the message:
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;
Although I found timer approach even better: just drop a timer component on the form, set Interval to 100 (ms) and implement OnTimer event:
procedure Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False; // stop the timer - should be executed only once
form2 := TForm2.Create(Application);
form2.ShowModal;
end;
The difference between the two approaches is:
When user message is posted either from OnCreate or OnShow handler, the message is dispatched with normal priority which means that other window initialization messages might get posted and handled after it. For essence, WM_PAINT messages would be handled after UM_DLG message. If UM_DLG message is taking long time to process without pumping the message queue (for example, opening db connection), then form would be shown blank without client area painted.
WM_TIMER message is a low-priority message and than means that form initialization messages would be handled first and only then WM_TIMER message would be processed, even if WM_TIMER message is posted before the form creation completes.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…