Перейти к содержанию
Fire Monkey от А до Я
  • 0

Динамическое создание и уничтожение TForm


Равиль Зарипов (ZuBy)

Вопрос

  • Модераторы

Доброго времени суток!

 

Создание

Application.CreateForm(TFormObject, FormObject);
FormObject.Show;

Уничтожение

if Assigned(FormObject) then
begin
  FormObject.Release;
  FormObject.DisposeOf;
  FormObject := nil;
end;

Вопрос, как при закрытии формы сделать уничтожение самой себя?

 

TActionClose.caFree не предлагать, не работает правильно

эта форма будет несколько раз создаваться и уничтожаться за время выполнения приложения (обязательное условие)

Ссылка на комментарий

Рекомендуемые сообщения

  • 0
  • Модераторы

Альтернативный вариант:

Скрываем форму. Перед тем как создать форму, проверяйте её на существование. Если существует, то удаляем и заново создаём.

Например, вот так, с фреймами:

procedure TForm1.Button1Click(Sender: TObject);
begin
  if FFrame <> nil then
  begin
    FFrame.DisposeOf;
    FFrame := nil;
  end;
  FFrame := TFrame2.Create(Self);
  FFrame.Parent := Self;
  FFrame.Name := 'TFrame10';
  FFrame.bCloseFrame.OnClick := FrameFreeAndNil;
end;

procedure TForm1.FrameFreeAndNil(Sender: TObject);
begin
  FFrame.Visible := False;
end;
Изменено пользователем Andrey Efimov
Ссылка на комментарий
  • 0
  • Модераторы

Альтернативный вариант:

Скрываем форму. Перед тем как создать форму, проверяйте её на существование. Если существует, то удаляем и заново создаём.

Например, вот так, с фреймами:

procedure TForm1.Button1Click(Sender: TObject);
begin
  if FFrame <> nil then
  begin
    FFrame.DisposeOf;
    FFrame := nil;
  end;
  FFrame := TFrame2.Create(Self);
  FFrame.Parent := Self;
  FFrame.Name := 'TFrame10';
  FFrame.bCloseFrame.OnClick := FrameFreeAndNil;
end;

procedure TForm1.FrameFreeAndNil(Sender: TObject);
begin
  FFrame.Visible := False;
end;
Так и сделано, но не то что хочу.

Нужно чтобы при закрытия формы, она сама удалилась.

Ситуация: создаём форму, показываем, закрываем. И она весит в памяти, а хотелось бы чтобы она почистили за собой

Ссылка на комментарий
  • 0
  • Модераторы

TActionClose.caFree не предлагать, не работает правильно

В каком смысле "не работает правильно"?
В том что после такого метода форму заного нельзя создать. AV вылетает
Ссылка на комментарий
  • 0

 

Нужно чтобы при закрытия формы, она сама удалилась.

Ситуация: создаём форму, показываем, закрываем. И она весит в памяти, а хотелось бы чтобы она почистили за собой

 

сделайте свой менеджер окон, типа стэка, который следит за окнами и при закрытии уничтожает их!

Ссылка на комментарий
  • 0
  • Модераторы

 

 

Нужно чтобы при закрытия формы, она сама удалилась.

Ситуация: создаём форму, показываем, закрываем. И она весит в памяти, а хотелось бы чтобы она почистили за собой

 

сделайте свой менеджер окон, типа стэка, который следит за окнами и при закрытии уничтожает их!

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

Ссылка на комментарий
  • 0

не знаю, у меня формы с  Action=caFree нормально убиваются

то, что при этом не сразу вызывается деструктор, это описанное поведение 

 

но есть еще form.Release

кроме того пытаюсь привыкнуть к созданию форм

TMyForm.Create(NIL).Show;

либо диалогов

var f:TMyDialog;
begin
  f:=TMyDialog.Create(NIL);
  f.showModal(procedure (AResult:TModalResult) begin
  case AResult of
    mrOK:begin
    end;
  end; 
end);
FreeAndNil(F);
end;
Ссылка на комментарий
  • 0
  • Администраторы

Вообще Release. Он выполняет отложенное удаление формы через н-ое количество милисекунд. Поэтому по идеи:

  1. Вызываем Release,
  2. Очищаем ссылки на форму (обнуляем ваши переменные/поля, держащие форму)

Ядерная комбинация:

 FormObject.Release;
 FormObject.DisposeOf;
 FormObject := nil;

Форму удаляет, но Release в этом случае не нужен. Это код метода Release.

  if not (TFmxFormState.Released in FFormState) then
  begin
    FWinService.ReleaseWindow(Self);
    Screen.RemoveForm(Self);
    FFormState := FFormState + [TFmxFormState.Released];
    if TFmxFormState.Engaged in FormState then
    begin
      if not (csDesigning in ComponentState) then
        FWinService.HideWindow(Self);
    end;
    inherited Release;
    TMessageManager.DefaultManager.SendMessage(Self, TFormReleasedMessage.Create);
  end;

Ссылка на комментарий
  • 0
  • Модераторы

 

Вообще Release. Он выполняет отложенное удаление формы через н-ое количество милисекунд. Поэтому по идеи:

  1. Вызываем Release,
  2. Очищаем ссылки на форму (обнуляем ваши переменные/поля, держащие форму)

Ядерная комбинация:

 FormObject.Release;
 FormObject.DisposeOf;
 FormObject := nil;

Форму удаляет, но Release в этом случае не нужен. Это код метода Release.

  if not (TFmxFormState.Released in FFormState) then
  begin
    FWinService.ReleaseWindow(Self);
    Screen.RemoveForm(Self);
    FFormState := FFormState + [TFmxFormState.Released];
    if TFmxFormState.Engaged in FormState then
    begin
      if not (csDesigning in ComponentState) then
        FWinService.HideWindow(Self);
    end;
    inherited Release;
    TMessageManager.DefaultManager.SendMessage(Self, TFormReleasedMessage.Create);
  end;

могу ли я на OnClose формы вызвать Release самой формы?

Ссылка на комментарий
  • 0
  • Администраторы

И еще код самого релиза на уровне TFmxObject:

procedure TFmxObject.Release;
begin
  if not (csDestroying in ComponentState) then
  begin
    if vPurgatory <> nil then
    begin
      Parent := nil;
      vPurgatory.Add(self);
      Include(FObjectState, CallingRelease);
    end
    else
      raise EInvalidOperation.CreateFMT(SNotInstance, ['TPurgatory']);
    if (Application <> nil) and (Action <> nil) then
      Application.UnregisterActionClient(Self);
  end;
end;

vPurgatory - это объект удаляющий объект по истечении определенного интервала времени.

Ссылка на комментарий
  • 0
  • Администраторы

Да, можете вызывать Release. Кстати, caFree, как раз и вызывает Release. Так что я даже не знаю, если вы сказали, что этот вариант вам не подошел.

Ссылка на комментарий
  • 0
  • Модераторы

Да, можете вызывать Release. Кстати, caFree, как раз и вызывает Release. Так что я даже не знаю, если вы сказали, что этот вариант вам не подошел.

на чистом проекте работает отлично caFree, а вот в рабочем AV ловлю. Проверю еще раз код.

Спасибо за разъяснения!

Ссылка на комментарий
  • 0

У меня схожая проблема, потому с вашего позволения спрошу здесь. Создал отдельно форму FormAdd (на ней кнопки OK, Cancel и Edit-ы). Из главного модуля убрал Application.CreateForm(TFormAdd, FormAdd);  

Пытаюсь ее вызвать так: 

    with FormAdd.Create(self) do
    begin
      ShowModal( procedure( AResult: TModalResult)
      begin
        if (AResult = mrOK) then
        begin
          /// действия 
        end;
        free;
      end );

и на первой же строке получаю Access Violation. Это я пока запускаю ее в Windows, а не под Android-ом.

Как быть?

Ссылка на комментарий
  • 0
  • Модераторы

У меня схожая проблема, потому с вашего позволения спрошу здесь. Создал отдельно форму FormAdd (на ней кнопки OK, Cancel и Edit-ы). Из главного модуля убрал Application.CreateForm(TFormAdd, FormAdd);

Пытаюсь ее вызвать так:

with FormAdd.Create(self) do    begin      ShowModal( procedure( AResult: TModalResult)      begin        if (AResult = mrOK) then        begin          /// действия         end;        free;      end );
и на первой же строке получаю Access Violation. Это я пока запускаю ее в Windows, а не под Android-ом.

Как быть?

TFormAdd.Create Изменено пользователем ZuBy
Ссылка на комментарий

Присоединяйтесь к обсуждению

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

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...