Какова последовательность создания форм и других объектов в Lazarus?

У меня есть простая программа с двумя формами, основной формой и формой настроек. Очевидно, что форма настроек позволяет пользователю изменять настройки. У меня есть блок настроек, раздел инициализации которого считывает настройки из файла.

Когда программа впервые установлена ​​и запущена в первый раз, настройки будут пустыми, и если это так, я хочу показать форму настроек. Вопрос в том, куда ставить чек и код вызова.

Мой Application.lpr содержит

begin
  RequireDerivedFormResource := True;
  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm);
  Application.CreateForm(TSettingsForm, SettingsForm);
  Application.Run;
end.                       

Мой блок настроек примерно такой

uses
  Classes, SysUtils, INIFiles;

type
  TSettings = class
    public
      procedure LoadFromFile();
      procedure SaveToFile();
    ...
    end;

var
  Settings: TSettings;

implementation

{ TSettings }

...

initialization
  Settings := TSettings.Create;
  Settings.LoadFromFile();

finalization
  Settings.SaveToFile();
  FreeAndNil(Settings);

end.       

Если я сделаю эту проверку на наличие пустых настроек в MainForm.FormCreate, я не смогу показать форму настроек, потому что она еще не создана.

Я не понимаю, как это сделать в Application.lpr, поскольку там нет явной переменной для ссылки на экземпляр SettingsForm. В любом случае, ставить его здесь неправильно.

  • Могу ли я выполнить эту проверку в SettingsForm.FormCreate, предполагая, что это вызывается только после того, как SettingsForm полностью инициализирован и готов к отображению? Вы можете позвонить Show() в FormCreate()?

  • Я не уверен, когда именно создается экземпляр моего типа настроек.

  • Есть ли какие-либо идеи, рекомендации, шаблоны дизайна или другой материал, который я мог бы использовать, чтобы определить, куда поместить мой чек для пустых настроек?


person RedGrittyBrick    schedule 15.08.2013    source источник


Ответы (2)


Формы создаются в том порядке, в котором они создаются в файле вашей программы. Видимые формы не будут отображаться до Application.Run.

Нет вообще никаких причин, по которым нельзя вбить логику "первого запуска" из файла программы. Например, вы можете написать:

begin
  RequireDerivedFormResource := True;
  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm);
  Application.CreateForm(TSettingsForm, SettingsForm);
  if SettingsForm.FirstTime then
    SettingsForm.ShowModal;
  Application.Run;
end.

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


В сторону. Ваш блок финализации настроек является рискованным. Если создание экземпляра Settings завершится неудачно, ваш блок завершения приведет к AV. Вы должны написать:

finalization
  if Assigned(Settings) then
    Settings.SaveToFile();
  FreeAndNil(Settings);
person David Heffernan    schedule 15.08.2013
comment
Я добавил If Settings.AreIncomplete then SettingsForm.Show;, но он выдает исключение ShowModal for SettingsForm невозможно, потому что он уже виден (подсказка для дизайнерских форм: установите для свойства visible значение false) (примечание: у меня SettingsForm.Visible установлено значение false в IDE). SettingsForm.Show (т.е. немодальный) запускается, но бесполезен, так как мне нужно, чтобы программа дождалась завершения настроек. - person RedGrittyBrick; 15.08.2013
comment
Это не имеет большого смысла для меня. Если Visible имеет значение False, почему среда выполнения сообщает вам, что форма видна. Как я уже сказал в своем ответе, избегая глобальных переменных и предварительно созданных форм, можно просто избежать всех таких проблем. - person David Heffernan; 15.08.2013

Вот довольно простой список последовательности создания формы Delphi.

Теперь, если я не ошибаюсь, ваши формы создаются в той последовательности, в которой они перечислены в вашем файле .dpr (см. проект-> исходный код), и первая указанная там форма будет вашей основной формой.

Редактировать:


ДЕЙСТВИЕ

Создать -> Показать -> Рисовать -> Активировать -> Изменить размер -> Рисовать -> Закрыть запрос -> Закрыть -> Деактивировать -> Скрыть -> Уничтожить


СОБЫТИЕ

OnCreate -> OnShow -> OnPaint -> OnActivate -> OnResize -> OnPaint -> OnCloseQuery -> OnClose -> OnDeactivate -> OnHide -> OnDestroy

(Цитируется по здесь)

person mg30rg    schedule 15.08.2013