Thanks HeavyUser, lucamar and Martin_fr!
All your answers have contributed to my understanding of the mechanics behind loading properties from a stream/*.lfm and a solution is
successfully implemented!
What worked specifically in my case was this:
- new private property LoadedFromLFM as boolean
- new public property CompVersion as integer
- override
Create to set "if (csDesigning in self.ComponenState) then self.LoadedFromLFM:=False;"
- override
DefineProperties(Filer: TFiler)
- new procedure LoadVersionProperty(Reader: TReader)
- new procedure StoreVersionProperty(Writer: TWriter)
- override
Loaded to set "LoadedFromLFM:=True;" and implement version specific methods using CompVersion
- also:
procedure TCustomComp.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineProperty('CompVersion', LoadVersionProperty, StoreVersionProperty, True);
end;
procedure TCustomComp.LoadVersionProperty(Reader: TReader);
begin
CompVersion := Reader.ReadInteger;
end;
procedure TCustomComp.StoreVersionProperty(Writer: TWriter);
begin
if not self.LoadedFromLFM then
CompVersion := UpdatedValue;
Writer.WriteInteger(CompVersion);
end;
The final part with the check for LoadedFromLFM is necessary because CompVersion didn't exist in previous versions. So I had to make sure CompVersion would only be updated if the component is manually dropped on the form. Otherwise, old components loaded from *.lfm would also be updated and I would miss this information.
As mentioned in the answers, the order of the methods is the following:
-
Dropping component on form: Create --> DefineProperties
-
Opening a saved project: Create --> DefineProperties (sometimes?) --> Loaded
-
Compiling and running: DefineProperties --> Create --> Loaded