Отменить / отменить создание новой формы в Delphi / C ++ Builder? - PullRequest
4 голосов
/ 31 августа 2009

Есть ли способ отменить или прервать создание формы из обработчика события OnCreate формы или конструктора C ++ Builder?

По сути, я хотел бы иметь возможность вызывать Close () из OnCreate или из конструктора, чтобы он вообще не отображал форму. У меня есть несколько форм, которые в рамках их инициализации могут определить, что они вообще не должны отображаться. (Я понимаю, что мог бы разделить эту часть инициализации или добавить дополнительные проверки из вызывающей формы или подобного, но если есть способ сделать все это чисто из OnCreate или конструктора, это кажется самым простым.)

Редактировать: В ответ на несколько комментариев часть логики «не показывать на всех» - это логика пользовательского интерфейса, а не бизнес-логика; перед отображением в форме может отображаться подтверждение или может использоваться обычное диалоговое окно для получения ввода для формы, а затем прерывание, если пользователь отменяет это диалоговое окно. (Часть из них является бизнес-логикой и нуждается в рефакторинге, но зачастую трудно найти время для рефакторинга всего, что в этом нуждается.)

Ответы [ 6 ]

8 голосов
/ 31 августа 2009

Вы всегда можете вызвать Release в обработчике OnCreate, но это приведет к тому, что форма быстро появится, а затем закроется. Не очень профессиональная вещь.

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

TheForm := TSomeForm.Create(Self);
TheForm.Show;

у вас будет

TheForm := TSomeForm.Create(Self);
if TheForm.ShouldAppear then
  TheForm.Show
else
  TheForm.Release;

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

7 голосов
/ 31 августа 2009

Я бы подумал, что гораздо лучше даже не создавать форму. Если вы выполняете некоторую логику, которая определяет, что форма даже не нужна, и эта логика содержит состояние, которое важно для формы, затем повторно раскладьте логику в отдельный объект (или даже модуль данных) и передайте объект к форме как собственность. Вот простой пример (с использованием объектного подхода):

UNIT1

type
  TOFormTests = class
    fStateData : string;
  public
    function IsForm1Needed( someparam : string) : boolean;
    property StateData : string read fStateData write fStateData;
  end;

UNIT2

uses
  : 
  UNIT1;

type
  TForm1 = class(tForm)
  :
  procedure SetFormTests(value : tOFormTests);
  property FormTests : TOFormTests read fFormTests write SetFormTests;
end;

procedure SetFormTest(Value:TOFOrmTests);
begin
  fFormTests := Value;
  // perform gui setup logic here.
end;

затем где-нибудь в вашем коде, где вы хотите определить, следует ли вам показывать свой графический интерфейс или не использовать что-то вроде следующего:

var
  Tests : TOFormTests;
begin
  tests := tOFormTests.create;
  try
    if Tests.IsForm1Needed('state data goes here') then
      begin
        Form1 := tForm1.create(nil);
        try
          Form1.FormTests := Tests;
          if Form1.ShowModal = mrOk then
            // handle any save state logic here.
          ;
        finally
          FreeAndNil(Form1);
        end;
      end;
  finally
    freeAndNil(Tests);
  end;
end;

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

6 голосов
/ 31 августа 2009

Использовать Прервать в конструкторе. Это вызывает молчаливое исключение. Если объект имеет исключение в конструкторе, то вызывается деструктор и освобождается память. Преимущество Abort заключается в том, что вам не нужно беспокоиться об отображении диалогового окна исключений, если вы не добавили код обработки исключений.

4 голосов
/ 31 августа 2009

Добавьте функцию класса, которая при необходимости возвращает экземпляр. Затем метод, который определяет, должна ли форма отображаться, все еще находится в этом классе, но он может определить, необходимо ли это до того, как форма действительно будет построена. Назовите его как «CreateIfNeeded», и он будет работать так же, как конструктор, но на самом деле не будет создавать форму, если она не нужна. Минимальные изменения кода и максимальная гибкость.

2 голосов
/ 31 августа 2009

Просто вызовите исключение в OnCreate. Вам также потребуется переопределить поведение метода HandleCreateException (по умолчанию отображается сообщение об ошибке, а не отмена создания).

0 голосов
/ 10 октября 2018

Я бы переопределил ShowModal

function TfHtmlEditor.ShowModal: Integer;
begin
  if TabControl1.Tabs.Count=0 then
    Result := mrAbort
  else
    Result := inherited;
end;
...