[Lazarus] Saving user created component structure to LFM file

Martin Friebe lazarus at mfriebe.de
Mon Jan 12 11:57:20 CET 2009


Thierry Coq wrote:
> Dear Martin,
> In Delphi, I frequently used the mecanism you described, but I had to 
> use the root "WriteComponentRes" procedure, not the WriteComponent one, 
> which is only available for subcomponents.
> I did not use TCollection, which is capable of writing components (too 
> complex for my usage). What I did do, was create container classes with 
> TComponent as Parent. By default, TComponent stores all children. The 
> root component must also give a name to each component, or the storage 
> will not work.
>
> The end result is the capability to store a hierarchy of objects in a 
> consistent manner.
>
> You should look for WriteComponentResFile in classes.inc and see how 
> this work, with a few tries.
>
> Hope this helps,
> Thierry
>   
Thanks, I think I found a better way.

The outer container has no nested components of it's own. It seems I can 
hook into (override) TComponent.WriteState which is calling 
WriteComponentData (properties, then Children). Since no children are 
there, I can make my own calls to WriteComponent from there, supplying 
all the components, of all the helper objects.

On Read, I can Hook into ReadState. I can let the reader add them 
normally, and sort them out/once they have been read by the reader.

The remaining question is: Does that look like something that will stay 
compatible with future code? The generated LFM file definitely looks 
like any LFM file (it has a component, with properties first then other 
nested Components)

Thanks Martin


> Martin Friebe wrote:
>   
>> Hi, I have a problem saving a certain component struicture to an LFM 
>> (lazarus) file and read it back.
>>
>> since a good amount of code is in FPC, I am not sure which list to go to?
>>
>> There is classes/writer.inc with has TBinaryObjectWriter. This is where 
>> things go first.
>> Then, later this gets translated into text. This translation seems to be 
>> stricter in terms of  what can be nested.
>>
>>
>> Anyway the problem is, that if I want to save a component (that can be 
>> of different class/classes) then I can use WriteComponent. But only if I 
>> am in a Component that is itself written with WriteComponent.
>>
>> In the final LFM it seems a Component can only be nested in an other 
>> component. It does not seem to be possible to put it in:
>> - Not in a subcomponent (because a subcomponent does not write it's 
>> class, but just the properties that are visible for the class given by 
>> the property
>>      property Foo: TPanel read .. write ...
>>   writes
>>      Foo.Name = 'abc'
>>      Foo.Top = 1
>>      ...
>> - Not in a TCollection, or at least I havent managed. Also again a 
>> TCollection is restricted to one classs for all Items
>> - Not Using DefineProperties
>>   All propwerties with define property are of the kind
>>       Name = Value
>>   I can add a list, but even inside the list I can not write a component
>>
>>
>> What I want to archive is theFollowing. I have
>>
>>  TMainComponent = class (foo)
>>    property Options : TPersitentBar read  x write x;
>>  end
>>
>> If It has to be it can be a TComponent, with SubComponent in 
>> TComponentStyle.
>> Problem 1)   Options is always created in the constructor, it can not be 
>> stored as a nested Component in the LFM. If it was, it would exist twice 
>> (once created in the constructor, and once loaded from the lfm)
>>
>> TPersitentBar should have a list of components, variable number, and 
>> different subclasses (could inherit from TPersistent, only Component if 
>> it makes it easier)
>>
>> How can I get this list saved into the lfm? Each item has a diff class, 
>> and diff properties, so they must saved via WriteComponent. (Which does 
>> not work for DefineProerties)
>>
>> And of course a default list of items is created in the constructor, so 
>> I need to detect if they are loaded, and remove the defaults.
>>
>> Any Idea?
>>
>> Example of the final structure (if only it was valid)
>>
>>  object MainComp1 : TMainComponent
>>       Options.AllowFoo = 1
>>       Options.AllowABC = 2
>>       object Options.SubOptionsForCars : TCarOptions
>>           MAxCar = 4
>>       end
>>       object Options.SubOptionsForTrains : TTrainOptions
>>           MAxTrain = 1
>>       end
>>  end
>>
>>
>> Best Regards
>> Martin
>>
>>
>>
>>
>> _______________________________________________
>> Lazarus mailing list
>> Lazarus at lazarus.freepascal.org
>> http://www.lazarus.freepascal.org/mailman/listinfo/lazarus
>>
>>
>>   
>>     
>
> _______________________________________________
> Lazarus mailing list
> Lazarus at lazarus.freepascal.org
> http://www.lazarus.freepascal.org/mailman/listinfo/lazarus
>   



More information about the Lazarus mailing list