Sign in Join

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

Mailing lists / fpc-pascal / 2009-01

csLoading and Create

5 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

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

Martin Friebe

Hi,

If a component is loaded from a stream, then csLoading is set in ComponentState (or so I thought I understood the concept) So in my component i do "if not(csLoading in componentState)" ...

However I found this does not work in the constructor Create. csLoading is only set *after* the Constructor has been called. (This is unless it is an inline component?).
- TReader does create the object with class.NewInstance (so create is not yet called)
- the for inlined components it does set csInline, scLoading => for others it does not set anything
- then the constructor create is called (but csLoading is not set)
- only then does csLoading get set

Is this supposed to be like this? How else can I inside Create check if the component is loaded from a stream?

Thanks
Martin

Reply by email

Michael Van Canneyt
to Martin Friebe
Martin Friebe wrote 18 lines
Hi, If a component is loaded from a stream, then csLoading is set in ComponentState (or so I thought I understood the concept) So in my component i do "if not(csLoading in componentState)" ... However I found this does not work in the constructor Create. csLoading is only set *after* the Constructor has been called. (This is unless it is an inline component?). - TReader does create the object with class.NewInstance (so create is not yet called) - the for inlined components it does set csInline, scLoading => for others it does not set anything - then the constructor create is called (but csLoading is not set) - only then does csLoading get set Is this supposed to be like this? How else can I inside Create check if the component is loaded from a stream?

It is supposed to be like this. You cannot check this, and you shoud not. A component should always behave the same, no matter whether it is being streamed or not: You cannot a priori know whether a component of a certain class will be streamed or not.

Michael.

Reply by email

Martin Friebe
to Michael Van Canneyt
Michael Van Canneyt wrote 27 lines
On Wed, 14 Jan 2009, Martin Friebe wrote: > Hi, > > If a component is loaded from a stream, then csLoading is set in > ComponentState (or so I thought I understood the concept) > So in my component i do "if not(csLoading in componentState)" ... > > However I found this does not work in the constructor Create. csLoading is > only set *after* the Constructor has been called. > (This is unless it is an inline component?). > - TReader does create the object with class.NewInstance (so create is not yet > called) > - the for inlined components it does set csInline, scLoading => for others it > does not set anything > - then the constructor create is called (but csLoading is not set) > - only then does csLoading get set > > Is this supposed to be like this? How else can I inside Create check if the > component is loaded from a stream? > It is supposed to be like this. You cannot check this, and you shoud not. A component should always behave the same, no matter whether it is being streamed or not: You cannot a priori know whether a component of a certain class will be streamed or not.

So here is my problem.

I have a component, that may or may not have children. If it has children they are correctly streamed, and read back too.

Historically it did not have children (or more accurate, it did, but they did not get streamed, they where constant)

Now I want to make sure that:
- a newly created (not loaded) component behaves as before. It creates it's default children.
- a loaded component however can not do with this default created children => because they would be duplicates.

Simply replacing isn't going to work, since their amount can vary. (0, 1 or more).
In fact in Lazarus I probably going to check the LCLVersion property of the form (or something like that). => This is for loaded components => new componets always will have the default.

In any way, currently this default children are created in the constructor, so it would have been nice to know if it was loaded or not.

Question:
- Is there a better place to create those defaults? One where I can access the necessary information?
- Alternative "ReadState" comes to mind. I can intercept it, and clear out the defaults, since loading is about to happen. (then call inherited)

Any better Idea?

Another question:
The component described are Subcomponents, and they are not visible. I will probably have them parented and owned by the same visible control. ( The only reason to stream them as component is because they vary in number and can be of different classes. I can not do that through a property, nor through a collection:
Property is fixed in number and class
Collection(Item) is fixed in class, only variable in number )

It seems to work with the default setting.
But I was wondering if in such a scenario I should have to thing about csInline, csAncestor or csInherited....? Probably not?

Thanks and Best Regards
Martin

Reply by email

Graeme Geldenhuys
to Martin Friebe: If a component is loaded from a stream, then csLoading is set in ComponentState (or so I…
Martin Friebe wrote
Is this supposed to be like this? How else can I inside Create check if the component is loaded from a stream?

Could you not use the AfterConstruction() method? Or is that still to early (before ComponentState is set)?

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Martin Friebe
to Graeme Geldenhuys
Graeme Geldenhuys wrote 9 lines
On Wed, Jan 14, 2009 at 3:25 PM, Martin Friebe wrote: > Is this supposed to be like this? How else can I inside Create check if the > component is loaded from a stream? > Could you not use the AfterConstruction() method? Or is that still to early (before ComponentState is set)?

Thanks, I'll investigate this. I s this called if the component is created by it's owning class>
The "owner" calls within his own create:

       FSubcomponent := TSubCompnetn.Create(self);  // and this should

create the default setup

Anyway I found another tip which works well; I can check AOwner.ComponetState for csLoading

Reply by email