В обработчике события 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;
Хотя я нашел подход с таймером еще лучше: просто поместите компонент таймера в форму, установите интервал в 100 (мс) и реализуйте событие 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 будет опубликовано до завершения создания формы.