[Lazarus] TDateEdit
Darmawan Sugiarto
darmawan_sugiarto at yahoo.com
Tue Jan 13 05:51:49 CET 2009
Is the subcomponent declared as a "published" property of its owner?.
Maybe that's why the streaming system can't view it.
Leonardo M. Ramé
Griensu S.A. - Medical IT Córdoba
Tel.: 0351 - 4247979
Martin Friebe escribió:
> Leonardo M. Ramé wrote:
>
>> In Delphi you have to explicitly set the subcomponent:
>>
>> Example:
>>
>> constructor TMyComponent.create....
>> begin
>> ...
>> FSubComponent := TSubComponent.Create(Self);
>> ...
>> FSubComponent.SetSubComponent(True);
>> ...
>> end;
>>
>>
>>
> Same here, just yopu can modify the flag directly:
> include(ComponentStyle, csSubComponent);
>
> But that only streams the properties, and does assume a specific class.
> It doesn't work for Anything that can change it;'s class.
>
> In fact in Lazarus you can skip this, IF the property has write access.
> There are 2 conditons that will save the valuse of a Class-property
> 1) property is TPersistend or descendant, and has both read and write
> access (write can end up in assign)
> 2) property is TComponent or descendant, and has csSubComponent (in this
> case it does not need a write access method)
>
>
>> Martin Friebe escribió:
>>
>>
>>> Mattias Gaertner wrote:
>>>
>>>
>>>
>>>>> [...]
>>>>> 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)
>>>>>
>>>>>
>>>>>
>>>>>
>>>> To store a property that is a component and which is not owned by the
>>>> Lookuproot (form, datamodule, frame) you must set the csSubComponent
>>>> flag in ComponentStyle.
>>>>
>>>>
>>>>
>>>>
>>> yes, I found the csSubComponent. But it stores the only the properties
>>> of the SubComponent, not the Component's Class.
>>>
>>> SubComponent does (Within the list of properties of the actual component):
>>> MySubCompProp.Value1 = 120
>>> MySubCompProp.Foo = 'abc'
>>>
>>> And also subcomps, look (correctly) at the definition of the property.
>>> It the Property is defined as TFoo (" property mySubCompProp: TFoo reads
>>> FMyFoo write FMyFoo;" , then all properties known by this class (TFoo)
>>> are stored. In My case the actual Object may be a descend and of TFoo
>>> (that is the objects stored in FMyFoo), and have additional Properties
>>> (This additional Properties would be lost)
>>>
>>>
>>> My Components are in a TList, the have different classes, so I need to
>>> save them the same way like nested components:
>>> object MySubCompFromListClassABC: TSubCompClassABC
>>> Value1 = 120
>>> end;
>>>
>>>
>>> The Real Background is SynEdits Gutter.
>>>
>>> The Gutter, I have managed to get saved. (via csSubComponent).
>>> But then the Gutter has a list of GutterParts (all of them Objects (and
>>> I can/will make them Components)). I need to save all those GutterParts.
>>> [ I know, I will also need a Property Editor for the object inspector,
>>> but that's not the issue ]
>>>
>>> If A Gutter is created, with a new SynEdit, and *not* loaded from LFM;
>>> then it creates a default set.
>>> If it is loaded, it needs to remove the default set (can be done in
>>> ReadState of SynEdit (SynEdit can inform the gutter) / Can depend on The
>>> LCL Version, so loading a 0.9.26 form, will keep the defaults, as no
>>> saved parts can exist)
>>>
>>>
>>>
>>>
>>>> To store a list use TCollection. If you can not use TCollection please
>>>> explain why not.
>>>>
>>>>
>>>>
>>>>
>>> Because All collection Items a of the same class. If I make that
>>> TGutterPartBase, then only properties exposed by TGutterPartBase are
>>> saved. but each GutterPart has additional published properties. (Same
>>> applies, if I make the CollectionItem a wrapper class with a property
>>> "property TheRealGutterPart: TGutterPartBase" => because as
>>> csSubComponen it does not save the class-info)
>>> Also even If I manage to get this subclasses into the collection (which
>>> is hard enough, as it is not supposed to be), If the collection is
>>> loaded, it restores them all to the base class, because it never saved
>>> the class-info
>>>
>>>
>>>
>>>> To store data of arbitrary length/format, use DefineProperties. This
>>>> has a drawback: In case of an error the IDE can not help fixing it.
>>>>
>>>>
>>>>
>>>>
>>> DefineProperties only takes simple values. Because in define properties
>>> I must give it the name. Then In Read/WriteProc I deal with the value.
>>> So define Property will always create an LFM entry like:
>>> MyDefinedPropertyName = xxx
>>> xxx Comes from the writecallback.
>>>
>>> If the write callback attempts to do WriteComponent, then this will fail
>>> later, when the binary format is translated into text-lfm-format
>>> (because " MyDefinedPropertyName = MyObject: TMyClass" is not allowed
>>>
>>> That is even, if the WriteCallback starts a list first, it will still fail.
>>> MyDefinedPropertyName = (
>>> MyObject: TMyClass
>>> ....
>>>
>>> With "DefineProperties" I have 2 (undesirable) possibilities:
>>> 1) use DefineBinarryProperties => and write my own format, no one can
>>> edit it, and why invent the wheel again?
>>> 2) use DefineProperties and define a large set of properties:
>>> - define a classname property for each of my objects
>>> - and define a property for each value that each of my objects needs
>>> to store.
>>> Again there is code (WriteComponent) that does streaming of objects
>>> including class info; why invent the wheel again?
>>>
>>> ---------------
>>>
>>> So as I see it I found 2 possibilities
>>>
>>> 1) The GutterParts are created as components owned by the SynEdit (or
>>> does it have to be the form; if it does have to be the form then there
>>> will be issues if there is more than one synedit.... ). that will be a
>>> lot of easy to break maintenance work. because you need to search
>>> through the component list to find the Objects.
>>> And when loading I still need to remove the Objects created in
>>> Synedit.Create or I get double entries.
>>> - Also I tried it, and SynEdit did not seem to stream them (MyGutterPart
>>> := TcomponentBasedClass.Create(TheSynEditAsOwner);) => nothing in the lfm
>>>
>>> 2) Maintain the objects as they are, but use SynEdit.WriteState to
>>> append them to the lfm
>>> (They can easily be caught, if they get read (by the default reader)
>>> during loading
>>>
>>>
>>> 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
>>
>>
> _______________________________________________
> Lazarus mailing list
> Lazarus at lazarus.freepascal.org
> http://www.lazarus.freepascal.org/mailman/listinfo/lazarus
>
>
More information about the Lazarus
mailing list