取消/中止在Delphi/C++ Builder中创建新表单?

Jos*_*ley 4 forms delphi c++builder

有没有办法从窗体的OnCreate事件处理程序或C++ Builder构造函数中取消或中止表单创建?

基本上,我希望能够从OnCreate或构造函数中调用Close()并让它完全跳过显示表单.我有几种形式,作为初始化的一部分可能会确定它们根本不应该显示.(我意识到我可以拆分初始化的这一部分或者从调用表单或类似的内容中添加额外的检查,但是如果有办法从OnCreate或构造函数中干净地完成所有这些操作,那么这似乎是最简单的.)

编辑: 回应一些评论,一些不显示的逻辑是UI逻辑而不是业务逻辑; 表单可能会在显示之前显示确认,或者它可能使用公共对话框来获取表单的输入,然后在用户取消该对话框时中止.(其中一些是业务逻辑,需要重构,但通常很难找到时间来重构所有需要它的东西.)

mgh*_*hie 8

您可以随时拨打ReleaseOnCreate处理程序,但这会导致形式迅速出现,然后关闭.不是很专业的事情.

所以这是另一个想法.让表单具有公共函数或属性,以返回它们实际上是否显示.然后你通常会有

TheForm := TSomeForm.Create(Self);
TheForm.Show;
Run Code Online (Sandbox Code Playgroud)

你将会拥有

TheForm := TSomeForm.Create(Self);
if TheForm.ShouldAppear then
  TheForm.Show
else
  TheForm.Release;
Run Code Online (Sandbox Code Playgroud)

话虽如此 - 任何其他编码方式(所以你不创建一个会被立即销毁的形式)肯定会更好.特别是如果你想在UI和业务层之间保持清晰的分离,那么让代码决定是否在表单之外显示表单会更好.只有在做出决定后才能创建表单.

  • Abort例外是专门为此而设计的.不得以任何方式滥用. (3认同)

ska*_*adt 7

我认为甚至不必首先创建表单要好得多.如果您正在执行一些确定表单甚至不需要的逻辑,并且该逻辑包含对表单重要的状态,则将逻辑重新分解为单独的对象(甚至是数据模块)并传递对象作为财产的形式.这是一个简单的例子(使用对象方法):

单元1

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

单元2

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;
Run Code Online (Sandbox Code Playgroud)

然后你的代码中的某个地方,你想要确定你是否应该显示你的gui或不使用如下的内容:

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;
Run Code Online (Sandbox Code Playgroud)

这也假设表单不在自动创建列表中,需要以模态显示.

  • +1我完全同意:这是业务逻辑,因此应该在创建表单之前确定. (3认同)

Jim*_*eth 6

在构造函数中使用Abort.它提出了一个无声的例外.如果对象在构造函数中有异常,则调用析构函数并释放内存.如果不添加异常处理代码,则Abort的优点是您不必担心显示异常对话框.