7

我有一个自定义控件:

type
   TContosoFrobber = class(TCustomControl)
   private
   end;

在内部,我的组件创建了一个控件

type
   TContosoFrobber = class(TCustomControl)
   private
      FMyDateTimePicker: TDateTimePicker;
   public
      constructor Create(AOwner : TComponent); override;
      property DateTimePicker: TDateTimePicker read FMyDateTimePicker;
   end;

constructor TContosoFrobber.Create(AOwner: TComponent);
begin
   inherted Create(AOwner);

   FMyControl := TMyDateTimePicker.Create(AOwner);
end;

其中TMyDateTimePickerTDateTimePicker的简单后代

TMyDateTimePicker = class(TDateTimePicker)
protected
end;

所以总结一下我所做的:

  • 声明一个私有变量TDateTimePicker
  • 将其公开(即未公开)属性TDateTimePicker
  • 通过多态,控件实际上是TDateTimePicker

这一切都奏效了——直到我最近重新安装了 Delphi XE6(在 Windows 10 上)。

DFM

这就是为什么我不明白为什么我在设计时遇到错误:

找不到类 TMyDateTimePicker

为什么它试图找到那个类?实现细节中的那个类;它不是为流媒体发布的。流媒体系统甚至是如何尝试创建它的!?所以我检查了DFM:

  object cfBeachBall: TContosoFrobber
     Left = 445
     Top = 25
     Width = 101
     Height = 22
     ...snip...
     object TMyDateTimePicker
        Left = 0
        Top = 0
        Width = 101
        Height = 22
        Date = 37306.581535243100000000
        Time = 37306.581535243100000000
        TabOrder = 0
        TabStop = False
     end
  end

为什么TInternalDateTimePicker最终出现在 dfm 中:

  • 财产是公开的,不公开的

如何阻止表单流系统在 dfm 中放置未发布的属性?

更糟糕的是错误的IDE

它不仅有时包含它不应该包含的属性。有时它包括不应该两次的属性:

  object cfPlasticBag: TContosoFrobber
     Left = 445
     Top = 25
     Width = 101
     Height = 22
     ...snip...
     object TMyDateTimePicker
        Left = 0
        Top = 0
        Width = 101
        Height = 22
        Date = 37306.581535243100000000
        Time = 37306.581535243100000000
        TabOrder = 0
        TabStop = False
     end
     object TMyDateTimePicker
        Left = 0
        Top = 0
        Width = 101
        Height = 22
        Date = 37306.581535243100000000
        Time = 37306.581535243100000000
        TabOrder = 0
        TabStop = False
     end
  end
  • 如何阻止 dfm 包含未发布的属性?
  • 我如何阻止 dfm 包含它两次

破解解决方法

我知道可怕的黑客攻击:告诉 DFM 它不应该让任何企业知道的控制:

initialization
    RegisterClass(TMyDateTimePicker);

finalization
    UnRegisterClass(TMyDateTimePicker);

end.

现在 dfm 包含一个它不知道的控件。每当我保存表单时,它都会包含对不应包含的内容的引用。最糟糕的是:我验证了它是错误的信念TMyDateTimePicker

为什么Delphi XE6在重装之前没有这样做?也许我需要安装长期以来不受支持的 Delphi 版本的最新更新?

已知错误?

在此处输入图像描述

4

1 回答 1

12

问题是您将错误分配OwnerTDateTimePicker. 您正在分配您TContosoFrobber的所有者而不是其TContosoFrobber本身:

constructor TContosoFrobber.Create(AOwner: TComponent);
begin
  inherted Create(AOwner);
  FMyControl := TMyDateTimePicker.Create(Self); // <-- not AOwner!
end;

或者:正如 Jerry Doge 所提到的,您可以改用nilOwner。你只需要Free()手动TDataTimePicker

type
  TContosoFrobber = class(TCustomControl)
  private
    FMyDateTimePicker: TDateTimePicker;
  public
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
    ...
  end;

constructor TContosoFrobber.Create(AOwner: TComponent);
begin
  inherted Create(AOwner);
  FMyControl := TMyDateTimePicker.Create(nil);
end;

destructor TContosoFrobber.Destroy;
begin
  FMyControl.Free;
  inherted Destroy;
end;
于 2016-09-14T20:04:12.170 回答