Delphi: инициализация приложения - лучшие практики / подход

Я регулярно сталкиваюсь с этим и просто ищу лучшую практику / подход. У меня есть приложение, содержащее базу данных / модуль данных, и я хочу запустить базу данных / наборы данных при запуске, если для параметра "active at runtime" задано значение true во время разработки (расположение базы данных различается). Также запустите веб-процедуру проверки обновлений при запуске приложения.

Учитывая последовательности событий TForm и результаты различных проб и ошибок, в настоящее время я использую этот подход:

Я использую запись "Globals", настроенную в главной форме, для хранения всех глобальных переменных, имею один элемент с именем Globals.AppInitialized (boolean) и задаю для нее значение False в разделе "Инициализация" главной формы.

В событии OnShow главной формы (все формы создаются к тому времени) я тестирую Globals.AppInitialized; если это ложно, я запускаю свои вещи "Initialization", а затем заканчиваю, устанавливая Globals.AppInitialized:= True.

Кажется, это работает довольно хорошо, но это лучший подход? Ищите понимание чужого опыта, идей и мнений. ТИА..

7 ответов

Решение

Обычно я всегда отключаю автоматическое создание всех форм, КРОМЕ для основной формы и, возможно, основного модуля данных.

Один трюк, который я узнал, что вы можете сделать, это добавить ваш модуль данных в ваш проект, позволить ему автоматически создавать и создавать ДО вашей основной формы. Затем, когда ваша основная форма будет создана, onCreate для модуля данных уже будет запущен.

Если в вашем приложении есть какой-то код, который нужно сказать, установите фокус элемента управления (что вы не можете сделать при создании, так как он "еще не виден"), затем создайте пользовательское сообщение и опубликуйте его в форме в своем приложении. Сообщение ДОЛЖНО (без гарантии) обрабатываться, как только обрабатывается цикл обработки сообщений. Например:

const
  wm_AppStarted = wm_User + 101;


type
  Form1 = class(tForm)
    :
    procedure wmAppStarted(var Msg:tMessage); message wm_AppStarted;
  end; 

// in your oncreate event add the following, which should result in your wmAppStarted event firing.
PostMessage(handle,wm_AppStarted,0,0);

Я не могу вспомнить ни разу, что это сообщение никогда не обрабатывалось, но характер вызова заключается в том, что оно добавляется в очередь сообщений, и если очередь заполнена, то она "отбрасывается". Просто знайте, что крайний случай существует.

Возможно, вы захотите напрямую вмешаться в источник проекта (файл.dpr) после вызова создания формы и перед Application.Run. (Или даже раньше в случае.)

Вот как я обычно обрабатываю такие вещи инициализации:

...
Application.CreateForm(TMainForm, MainForm);    
...
MainForm.ApplicationLoaded; // loads options, etc..
Application.Run;
...

Я не знаю, полезно ли это, но некоторые из моих приложений не имеют автоматически созданной формы, то есть у них нет mainform в IDE.

Первая форма, созданная с объектом Application в качестве его владельца, автоматически станет основной. Таким образом, я только автоматически создаю один модуль данных как загрузчик и позволяю этому решить, какие модули данных создавать, когда и какие формы создавать в каком порядке. Этот модуль данных имеет методы StartUp и ShutDown, которые называются "скобками" вокруг Application.Run в dpr. Метод ShutDown дает немного больше контроля над процессом выключения.

Это может быть полезно, когда вы спроектировали разные "основные формы" для разных вариантов использования вашего приложения или вы можете использовать некоторые файлы конфигурации для выбора разных основных форм.

На самом деле в Delphi нет такого понятия, как "глобальная переменная". Все переменные ограничены единицей, в которой они находятся, и другими единицами, которые используют эту единицу.

Просто сделайте AppInitialized и Initialization как часть вашего модуля данных. В основном, есть один класс (или модуль данных) для управления всеми вашими вещами, не относящимися к пользовательскому интерфейсу (вроде как One-Ring, кроме не всех злых и подобных).

В качестве альтернативы вы можете:

  • Звоните с вашего заставки.
  • Сделайте это во время входа
  • Запустите "проверку обновлений" в фоновом потоке - не заставляйте их обновляться прямо сейчас. Делайте это как Firefox.

Я использую основной модуль данных, чтобы проверить, в порядке ли соединение с БД, а если нет, показать форму настраиваемого компонента для настройки соединения с БД, а затем загрузить основную форму:

Application.CreateForm(TDmMain, DmMain);

  if DmMain.isDBConnected then
    begin
      Application.CreateForm(TDmVisualUtils, DmVisualUtils);
      Application.CreateForm(TfrmMain, frmMain);
    end;

  Application.Run;

Я не уверен, что понимаю, зачем вам глобальные переменные? В настоящее время я пишу ВСЕ свои приложения Delphi без единой глобальной переменной. Даже когда я их использовал, у меня никогда не было больше пары на одно приложение.

Поэтому, может быть, вам нужно сначала подумать, зачем они вам нужны.

Один из приемов, которые я использую, - это поместить TTimer в основную форму, установить время около 300 мс и выполнить любую инициализацию (вход в БД, сетевые копии файлов и т. Д.). Запуск приложения немедленно вызывает основную форму и позволяет выполнять любые "инициализации". Пользователи не запускают несколько экземпляров, думая: "О, я не щелкнул... Я сделаю это снова..."

Другие вопросы по тегам