您是否可以从delphi组件中删除已发布的属性,并且不会在使用该组件的表单上导致错误?

时间:2011-04-27 15:54:10

标签: delphi

我有一个由我公司开发的组件,并希望删除一个不再需要的已发布属性,并且与组件现在的工作方式发生冲突。

有没有办法删除属性,并且在加载使用该组件的表单时,在运行时或设计时不会导致属性未找到错误? 即有没有办法让Delphi以静默方式删除组件属性?

3 个答案:

答案 0 :(得分:20)

是。只需删除该属性,然后覆盖DefineProperties并在那里处理它。这将通过加载您可以丢弃的值来满足流式传输系统。写入流时一定不要做任何事情。

答案 1 :(得分:18)

根据属性的不同,最简单的方法是离开属性,但将其标记为已弃用,只需将读/写位指向一个从未使用过的字段。

或者,您可以覆盖DefineProperties并致电Filer.DefineProperty('PropertyName', ReadProc);,其中 PropertyName 是您已删除的媒体资源, ReadProc 是一个功能调用各种TReader Read *函数。这样做的好处是属性不再存在于您的界面中。

例如,假设您已删除此属性:

property Center: TPoint read FPoint write SetPoint;

以下是您要添加到组件的内容:

TMyComponent = class...
private
  procedure SkipReadPoint(Reader: TReader);
protected
  procedure DefineProperties(Filer: TFiler); override;
end;

procedure TMyComponent.DefineProperties(Filer: TFiler);
begin
  inherited;
  Filer.DefineProperty('Center', SkipReadPoint, nil, False);
end;

procedure TMyComponent.SkipReadPoint(Reader: TReader);
begin
  Reader.ReadListBegin;
  Reader.ReadInteger;
  Reader.ReadInteger;
  Reader.ReadListEnd;
end;

跳过布尔或整数这样的简单类型更容易,因为您只需调用ReadBooleanReadInteger而无需使用ReadList函数。

在我们的例子中,我们在一堆类中有很多类似的属性(对于CLX兼容性),所以我们有这样的全局“虚拟”函数:

procedure DummyReadBool(Self: Pointer; Reader: TReader);
begin
  Reader.ReadBoolean;
end;
const
  SkipReadBool: TMethod = (Code: @DummyReadBool; Data: nil);

然后DefineProperty调用如下所示:

Filer.DefineProperty('PropName', TReaderProc(SkipReadBool), nil, False);

这样每个类都不必具有重复的Skip *函数。

答案 2 :(得分:6)

如果它存储在.DFM中或在代码中引用,则无法“静默”删除它。

如果它没有在代码中引用,并且它存储在文本.DFM文件中,JVCL有一个名为DFM Cleaner的实用程序,它将通过.DFM并为您删除属性。然后,您可以打开表单并安全地重新编译应用程序。它是JVCL的一部分,在安装期间放在$(JVCL)\DevTools文件夹中。