如何在构造函数中中断组件?

时间:2011-12-22 01:42:51

标签: delphi constructor components delphi-2009

我想在组件无法加载时向条件状态添加条件状态,并通知其用户(开发人员)该组件无法在设计时加载并在运行时以目标用户加载(如果可能的话,以某种方式安全地)。 / p>

如何防止组件在其构造函数中加载以及如何在设计时和运行时安全地显示构造函数中的消息(异常)?

constructor TSomeComponent.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  if csDesigning in ComponentState then
    if SomeIncompatibleCondition then
      begin
        // how to display message (exception) about the wrong 
        // condition and interrupt the loading of the component ?
      end;

  // is it possible to do the same at runtime ?
end;

谢谢

2 个答案:

答案 0 :(得分:6)

提出异常,例如:

constructor TSomeComponent.Create(AOwner: TComponent); 
begin 
  inherited Create(AOwner); 
  if SomeIncompatibleCondition then 
    raise Exception.Create('Incompatible condition detected!');
end; 

答案 1 :(得分:2)

一种方法:

Public 
   Property CreatedOK: boolean read fCreatedOK;

constructor TSomeComponent.Create(AOwner: TComponent);
begin
  ...
  fCreatedOK := ThereIsAnIncompatibleCondition;
end;

然后,程序员通过以下方式创建对象:

MyObject := TSomeComponent.Create(Self);
if (NOT MyObject.CreatedOK) then
  ... deal with it...

我们更喜欢这个,因为它避免了大量的异常代码,这可能很麻烦,而且在调试时也很麻烦。 (那是另一个话题!)

我们使用的另一种方法是,如果构造函数有很多工作,请将工作移动到用户 在构造之后调用的另一个方法。这也有一个好处,就是让我们可以轻松地将许多值传递给对象。

public
  constructor Create...
  function InitAfterCreate:boolean;
end;

来电者:

MyObject := TSomeComponent.Create
if (NOT MyObject.InitAfterCreate) then
   ... deal with it ...

或者,如果您使用InitAfterCreate传递值,则将其定义为

function InitAfterCreate( Value1: Integer, etc.):boolean

然后InitAfterCreate可以检查对象的状态并返回结果。

这些方法的一个缺点是程序员必须记住调用InitAfterCreate或检查MyObject.CreatedOk。为了防止他们不这样做,你可以在你的对象的其他一些方法的开头放一些Asserts,如:

procedure TForm.FormShow
begin
  Assert(fCreatedOK, "Programmer failed to check creation result.")
  ...
end;

在所有情况下,一个挑战是不要终止创建离开半创建的对象,处于不确定状态,这可能使您的析构函数难以知道要销毁多少。