Как создать диалоговое окно непосредственно после того, как видна основная форма моего приложения? - PullRequest
6 голосов
/ 01 июня 2011

Я использовал событие TForm OnActivate, чтобы дать мне возможность показать диалоговое окно, как только мое приложение запустится. Я хочу, чтобы основная форма уже была загружена и видна. Какой хороший способ сделать это?

Я обнаружил, что OnActivate работает нормально, если формы WindowState не являются wsMaximized.

В прошлом я добивался того, чего хочу, разными способами, но я ожидаю, что есть лучший способ.

Вот что сработало для меня:

procedure TForm1.FormCreate(Sender: TObject);  
begin 
  Application.OnIdle:=OnIdle; 
end; 

procedure TForm1.OnIdle(Sender: TObject; var Done: Boolean); 
begin 
  Application.OnIdle:=nil; 
  form2:=TForm2.Create(Application); 
  form2.ShowModal; 
end;

Есть ли лучший способ?

Ответы [ 5 ]

17 голосов
/ 01 июня 2011

В обработчике события 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 будет опубликовано до завершения создания формы.

1 голос
/ 06 ноября 2018

В событии OnShow в MainForm вы можете выполнить одно из следующих действий, чтобы отобразить диалоговое окно после задержки, которое позволяет MainForm полностью завершиться, показывая себя первым:

  • запустить короткий таймер.
  • PostMessage() пользовательское оконное сообщение для себя.
  • используйте TThread.CreateAnonymousThread() или TTask для вызова TThread.Queue().
  • используйте TThread.ForceQueue() (только 10.2 Токио и позже).
1 голос
/ 02 июня 2011

В итоге я использовал событие Application.OnIdle.Это не идеальное решение, но оно подходит для моей ситуации.Спасибо всем за ответы!

0 голосов
/ 01 мая 2013

Ну, я не знаю, является ли это лучшей практикой, но мне так:

В файле 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.

Пожалуйста, кто-нибудь поправит меня, если это не лучшая практика!

Надеюсь быть полезным для вас!

0 голосов
/ 02 июня 2011

Мне давно показали следующий способ сделать это, и он всегда работал для меня.

В основной метод OnCreate формы, после того, как вы сделали что-то, что вы обычно делаете в этом методе, добавьте следующую строку:

Self.Show;

Появится основная форма.

Затем, после этого, введите код для отображения вашего диалогового окна.

При запуске отобразится ваша основная форма, а затем сразу же появится диалоговое окно.

...