我有一个由我公司开发的组件,并希望删除一个不再需要的已发布属性,并且与组件现在的工作方式发生冲突。
有没有办法删除属性,并且在加载使用该组件的表单时,在运行时或设计时不会导致属性未找到错误? 即有没有办法让Delphi以静默方式删除组件属性?
答案 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;
跳过布尔或整数这样的简单类型更容易,因为您只需调用ReadBoolean
或ReadInteger
而无需使用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
文件夹中。