Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2009-01

Saving user created component structure to LFM file

2 messages · 1 person · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Martin Friebe

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

Reply by email

Martin Friebe
to Martin Friebe

Hi,

I may have found a way top solve my problem (saving a list of components from various places, not necesarely all nested in the top level component / See below)

The question now is, how forward-compatible is this ode. How much do I have to expect any of the current code to change in ways that would break my solution?

What I would do:
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. I ReadState, I can also sort out to get rid of the default list of objects/components (since new ones are loaded). This must be in ReadState, not in Loaded, because Loaded is called after, and I would run into trouble making the diff between the default, and reloaded objects)

The generated LFM file definitely looks like any LFM file (it has a component, with properties first then other nested Components)

Any ideas, if this is a bad idea (like in will break soon)?

Thanks Martin

Martin Friebe wrote 82 lines
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 _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email