有没有办法从表单的OnCreate事件处理程序或C ++ Builder构造函数中取消或中止表单创建?
基本上,我希望能够从OnCreate或构造函数中调用Close(),并让它完全跳过显示表单。我有几种形式,作为初始化的一部分可能会确定它们根本不应该显示。 (我意识到我可以拆分初始化的这一部分或者从调用表单或类似的内容中添加额外的检查,但是如果有办法从OnCreate或构造函数中干净地完成所有这些操作,那么这似乎是最简单的。)
编辑:为了回应一些评论,一些不显示的逻辑是UI逻辑而不是业务逻辑;表单可能会在显示之前显示确认,或者它可能使用公共对话框来获取表单的输入,然后在用户取消该对话框时中止。 (其中一些是业务逻辑,需要重构,但通常很难找到时间来重构所有需要它的东西。)
答案 0 :(得分:8)
您始终可以在Release
处理程序中调用OnCreate
,但这会导致表单快速显示然后被关闭。不是很专业。
所以这是另一个想法。让表单具有公共函数或属性,以返回它们实际上是否显示。然后你通常会在哪里
TheForm := TSomeForm.Create(Self);
TheForm.Show;
你会有
TheForm := TSomeForm.Create(Self);
if TheForm.ShouldAppear then
TheForm.Show
else
TheForm.Release;
话虽如此 - 任何其他编码方式(所以你不创建一个会被立即销毁的形式)肯定会更好。特别是如果你想在UI和业务层之间保持清晰的分离,那么让代码决定是否在表单之外显示表单会更好。只有在做出决定后才能创建表单。
答案 1 :(得分:7)
我认为甚至不必首先创建表单要好得多。如果您正在执行一些确定表单甚至不需要的逻辑,并且该逻辑包含对表单重要的状态,则将逻辑重新分解为单独的对象(甚至是数据模块)并传递对象作为财产的形式。这是一个简单的例子(使用对象方法):
<强> 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;
然后在您的代码中的某个位置,您想要确定是否应该显示您的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;
这也假定表单不在自动创建列表中,需要以模态显示。
答案 2 :(得分:6)
在构造函数中使用中止。它提出了一个无声的例外。如果对象在构造函数中有异常,则调用析构函数并释放内存。如果不添加异常处理代码,则Abort的优点是您不必担心显示异常对话框。
答案 3 :(得分:4)
添加一个在需要时返回实例的类函数。然后确定是否应该显示表单的方法仍然在该类中,但是它可以确定在实际构造表单之前是否有必要。将其称为“CreateIfNeeded”,它将像构造函数一样工作,但如果不需要,则不会实际构造表单。最小的代码更改和最大的灵活性。
答案 4 :(得分:2)
只需在OnCreate中引发异常即可。 您还需要重新定义HandleCreateException方法的行为(默认情况下显示错误消息,而不是取消创建)。
答案 5 :(得分:0)
我会覆盖ShowModal
function TfHtmlEditor.ShowModal: Integer;
begin
if TabControl1.Tabs.Count=0 then
Result := mrAbort
else
Result := inherited;
end;