I have a component that was developed by my company, and would like to remove one of the published properties that is no longer needed and clashes with the way the component works now.
Is there a way to remove the property and not cause property not found errors at runtime or design time when forms that use the component are loaded? i.e. Is there a way to make Delphi silently drop a component property?
Yes. Just remove the property, then override DefineProperties and process it there. That will satisfy the streaming system by loading the value which you can just throw away. Be sure to do nothing when writing the stream.
Depending on the property, the easiest would be to leave the property, but mark it as deprecated and just have the Read/Write bits point to a field that's never used.
Alternatively, you can override DefineProperties
and call Filer.DefineProperty('PropertyName', ReadProc);
where PropertyName is the property you've removed, and ReadProc is a function that calls various TReader Read* functions. This has the advantage that the properties aren't in your interface anymore.
For example, say you've removed this property:
property Center: TPoint read FPoint write SetPoint;
Here's what you would add to your component:
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;
Skipping a simple type like Boolean or Integer is easier, since you can just call ReadBoolean
or ReadInteger
without bothering with the ReadList functions.
In our case we had a lot of similar properties across a bunch of classes (for CLX compatibility) so we had global "dummy" functions like this:
procedure DummyReadBool(Self: Pointer; Reader: TReader);
begin
Reader.ReadBoolean;
end;
const
SkipReadBool: TMethod = (Code: @DummyReadBool; Data: nil);
and then the DefineProperty call looks like this:
Filer.DefineProperty('PropName', TReaderProc(SkipReadBool), nil, False);
That way each class doesn't have to have duplicate Skip* functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With