Delphi 如何中断组件在其构造函数中的加载?

Delphi 如何中断组件在其构造函数中的加载?,delphi,constructor,components,delphi-2009,Delphi,Constructor,Components,Delphi 2009,我想在组件无法加载时将条件状态添加到组件中,并通知其用户(开发人员)该组件无法在设计时加载,并且无法在运行时加载目标用户(如果可能,安全地加载) 如何防止组件加载到其构造函数中,以及如何在设计时和运行时安全地显示来自构造函数的消息(异常) constructor TSomeComponent.Create(AOwner: TComponent); begin inherited Create(AOwner); if csDesigning in ComponentState then

我想在组件无法加载时将条件状态添加到组件中,并通知其用户(开发人员)该组件无法在设计时加载,并且无法在运行时加载目标用户(如果可能,安全地加载)

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

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;

谢谢你提出一个例外,例如:

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

提出例外情况,例如:

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

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。为了防止它们不这样做,您可以在对象的某些其他方法的开头放置一些断言,如:

procedure TForm.FormShow
begin
  Assert(fCreatedOK, "Programmer failed to check creation result.")
  ...
end;
在所有情况下,一个挑战是不要终止创建,使对象处于半创建状态,处于不确定状态,这可能使析构函数很难知道要销毁多少。

一种方法:

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。为了防止它们不这样做,您可以在对象的某些其他方法的开头放置一些断言,如:

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

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

您的测试在构造函数中(而不是在加载的方法中),因为在从DFM开始加载属性之前需要消息,正确吗?您的测试在构造函数中(不是,也不是在加载的方法中),因为在开始从DFM加载属性之前需要该消息,对吗?