Как я стараюсь не называть Приложение. CreateForm дважды?

Я споткнулся на этой странице, Почему я не должен называть Приложение. CreateForm. Теперь у меня есть некоторый код как это:

SplashForm := TSplashForm.Create(Application);
SplashForm.Show;
SplashForm.Update; // force update
Application.Initialize;
Application.CreateForm(TClientData, ClientData);
SplashForm.Update; // force update
Application.CreateForm(TClientMainForm, ClientMainForm);
Application.ShowHint := True;

Application.Run;
ClientMainForm.ServerConnected := false;
FreeAndNil(ClientMainForm);
FreeAndNil(ClientData);

Сначала splashform создается, затем datamodule, и продержитесь основную форму. Страница говорит то Приложение. CreateForm нельзя назвать дважды. Должен код выше быть измененным?

5
задан Cœur 9 December 2018 в 13:29
поделиться

4 ответа

Нет ничего плохого в использовании Application.CreateForm многократно. Но при этом вводятся глобальные переменные для каждой формы, которые могут быть запахом кода. К сожалению, IDE создает по одной для каждой формы. Хотя их можно удалять при желании.

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

Основной модуль данных может быть создан основной формой. Но он может быть и глобальным, просто на вкус.

Таким образом, чтобы ответить на вопрос, Вы можете избежать Application.CreateForm, создавая и выпуская формы локально.

В статье упоминается побочный эффект Application.CreateForm (первая заполненная форма - это основная форма). Таким образом, могут быть неожиданные побочные эффекты, если основная форма создает другие формы с помощью Application.CreateForm.

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

5
ответ дан 14 December 2019 в 08:50
поделиться

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

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

SplashForm := TSplashForm.Create(Application);
SplashForm.Show;
SplashForm.Update; // force update
Application.Initialize;

// Change to this.
ClientData := TClientData.Create(Application);

SplashForm.Update; // force update
Application.CreateForm(TClientMainForm, ClientMainForm);
Application.ShowHint := True;

Application.Run;
ClientMainForm.ServerConnected := false;

// Remove these.
FreeAndNil(ClientMainForm);
FreeAndNil(ClientData);

Вы действительно не должны освободить объекты, которые вы создали здесь, потому что у вас их нет. Они принадлежат глобальному объекту приложений, поэтому позвольте позаботиться о том, чтобы освободить их: удалить две звонки в Фрейднил.

1
ответ дан 14 December 2019 в 08:50
поделиться

Если TClientData - это модуль данных, а TClientMainForm - это форма, тогда нет (за исключением, возможно, двух вызовов FreeAndNil в конце, которые на самом деле не нужны). Но будьте осторожны. Поскольку, как говорит Роб Кеннеди в своем сообщении, Application.CreateForm выполняет другие функции (он устанавливает переменную MainForm ), поэтому я бы посоветовал настроить файл вашего проекта в соответствии со следующими правилами:

  1. Создайте все формы, которые вы хотите создать при запуске, используя единственный вызов Application.CreateForm - обычно это делается в среде IDE.

  2. Удалите из файла проекта формы, которые вы хотите создавать динамически (по запросу) в вашей программе. (В Project | Параметры | Формы ...) - переместите их из «Автоматически создавать формы» в «Доступные формы»

  3. Создайте свои формы в коде , используя TmyForm.Create (Owner ) (и т. Д.) И не с Application.CreateForm (...) . Кстати, если вы уверены, что освободите форму, то лучше (чтобы ускорить процесс) вызвать TmyForm.Create ( nil ) - iow без хозяина.

  4. Если вы хотите выполнить какую-то инициализацию при запуске, вы можете привязать процедуру / метод в файле проекта к уже созданному модулю формы / данных и запускать его перед запуском приложения.

Например:

begin 
  Application.Initialize; 
  Application.MainFormOnTaskbar := True; 
  Application.CreateForm(TdmoMain, dmoMain); //<--this is a data module
  Application.CreateForm(TfrmMain, frmMain); //<--this will became the main form
  Application.CreateForm(TfrmAbout, frmAbout);
  //... other forms created here...
  frmMain.InitEngine; //<--initialization code. You can put somewhere else, according with your app architecture
  Application.Run;
end.

Таким образом вы очистите файл проекта и будете точно знать, что есть что.

HTH

1
ответ дан 14 December 2019 в 08:50
поделиться

Ниже показано, установлена или нет платформа .net framework 3.5. и, если не установлен, установит его. Просто запустите это в командной строке.

if exist "%WINDIR%\Microsoft.Net\Framework\v3.5" goto end start /wait .\Framework\dotnetfx.exe /q /norestart" :end 

Если вы хотите обнаружить другие версии, замените v3.5 на v2.0 или v1.0. Кроме того, если .net не обнаружен, установка .net framework будет выполняться в автоматическом режиме, т.е. без взаимодействия с пользователем.

-121--1391370-

Я подозреваю, что предложение Крейга Стунца может сработать, но если это не так, то, безусловно, должно сработать следующее:

 var xxxx =_connectedClientRepository
        .GetConnectedClients(new[] { "LogEntry", "LogEntry.GameFile" })
        .AsExpandable()
        .Where(predicate)
        .ToList() // execute query
        .Select(cp => cp.LogEntry); // use linq-to-objects to project the result
-121--3023085-

Статья, на которую вы ссылаетесь, неверна. Существует ряд веских причин, по которым требуется несколько вызовов для Application.CreateForm

1) Datamodules: Возможно, они всегда будут доступны. Лучший способ сделать это - Application.CreateForm. Я знаю приложения с несколькими тематическими Датамодулями, например Клиент, Счет, Адрес для обработки различных областей базы данных и аккуратно инкапсулировать функциональные возможности. Все они созданы в .dpr

2) Большая, медленная загрузка материала (что является плохой идеей в & само по себе, но эти вещи происходят и часто наследуются программистами поддержки...). Переместите время загрузки в запуск приложения точно так же, как и код примера, вместе с обновлением заставки. Пользователи ожидают, что приложения будут работать некоторое время благодаря усилиям наших коллег, работающих над Microsoft Office, чтобы снизить планку ожиданий для остальных из нас:)

Таким образом, не волнуйтесь, ваш код в порядке - но вы можете потерять "FreeAndNil" вещи. Однако небольшое быстрое попадание Тип диалога лучше всего вызвать:

with TMyform.Create(nil) do
try
  //Setup
  case ShowModal of
    // Whatever return values you care about (if any)
  end;
finally
  Free;
end;

Короткий, сладкий, в точку и минимизирует использование памяти...

0
ответ дан 14 December 2019 в 08:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: