Где поместить код для выполнения один раз после завершения инициализации моего приложения Delphi? - PullRequest
6 голосов
/ 24 сентября 2010

У меня есть функции, которые я хочу выполнять после завершения инициализации приложения и создания основной формы. У меня действительно был код (назовите его MethodX) в событии OnShow форм, но я только что заметил, что он вызывается дважды, потому что OnShow запускается дважды. Срабатывает, когда основная программа DPR вызывает:

Application.CreateForm(TMainForm, MainForm) ;  

как я и ожидал. Но после этого, когда я читаю материал из INI-файла, который включает в себя положение на экране формы, у меня появляется вызов:

MainForm.position := poScreenCenter ;

Это, похоже, снова запускает событие OnShow.

Куда я могу поместить свой вызов к MethodX, который должен быть вызван только один раз и которому необходимо создать основную форму, прежде чем он сможет выполнить?

Ответы [ 6 ]

9 голосов
/ 24 сентября 2010

Если ваш код должен запускаться только один раз при создании формы (или для приложения, а форма создается только один раз за запуск приложения), поместите код в обработчик OnCreate формы. Это естественное место для этого.

В настоящее время (начиная с D3, я думаю) OnCreate запускается в конце процесса построения в методе AfterConstruction. Только если вы установите для OldCreateOrder значение True (а по умолчанию - False), у вас могут возникнуть проблемы, так как это вызовет OnCreate в конце конструктора Create.

6 голосов
/ 24 сентября 2010

@ Sertac,

В поле FRUNOnce действительно нет необходимости;просто сделайте OnShow = NIL в качестве первой строки вашего метода FormShow.

FYI, Идиома «запустить один раз» - установка поля обработчика события в NIL в первой строке обработчика события - также ужаснополезно для получения некоторого кода, работающего после того, как форма полностью инициализирована.Поместите свой код в метод FormActivate и, в качестве первой строки метода, установите OnActivate = NIL.

6 голосов
/ 24 сентября 2010

Обычный порядок выполнения для формы:

  • AfterConstruction: когда форма и ее компоненты полностью созданы со всеми их свойствами.
  • OnShow: всякий раз, когда форма готова к показу (и, да, любое изменение, вызывающее CM_SHOWINGCHANGED, может вызвать OnShow)
  • Activate: всякий раз, когда форма принимаетФокус

Итак, в зависимости от того, что вам нужно в процедуре X, AfterConstruction может быть достаточно и выполняется только один раз;просто переопределите его и добавьте процедуру X после inherited. Это будет после OnCreate.

Если это не так, вы можете опубликовать собственное сообщение в форме с AfterConstruction, оно будет поставлено в очередь и достигнет вашегопользовательский обработчик после обработки других сообщений.

В обоих случаях вам не понадобится дополнительное логическое поле.

4 голосов
/ 13 сентября 2012

Вы можете добавить процедуру в файл DPR после Application.CreateForm.Поместите весь код, который вам нужно инициализировать в этой процедуре.Лучше всего работает, когда в вашем приложении несколько форм.

Кроме того, если инициализация занимает много времени, она позволяет программе отображать формы на экране, чтобы пользователь знал, что приложение загружается.

Пример:

PROGRAM MyProgram;
begin
    Application.Initialize;
    Application.CreateForm(TMyForm, MyForm);
    MyForm.Show;

    LateInitialize;        <----------- here

    Application.Run;
end. 
3 голосов
/ 24 сентября 2010

Вы можете проверить и установить флаг после первого вызова процедуры. Вот так:

type
  TForm1 = class(TForm)
    procedure FormShow(Sender: TObject);
  private
    FRunOnce: Boolean;
  public
    [...]

[...]

procedure TForm1.FormShow(Sender: TObject);
begin
  if not FRunOnce then begin
    FRunOnce := True;
    ProcedureX;
  end;
end;
0 голосов
/ 27 сентября 2010

@ Sertec

Ваш код также не будет работать, если вы хотите, чтобы он выполнялся для каждого отображаемого события (вы не добавили код для сброса поля frunonce).

Таким образом, ваш метод должен был бы сбросить поле frunonce, а мой - установить OnShow = FormShow. Та же разница, за исключением того, что вам нужно дополнительное поле.

...