[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