Example of how to store a Component and its properties
to a disk file or a Blob field
author :
Theodoros Bebekis
Thessaloniki, Greece
e-mail:
[email protected]
----------------------------------------------------------------------
Lets suppose that we have a complex data type
For example:
TThirdLayer = record
.
.
end;
TSecondLayer = record
.
.
ThirdLayer :TThirdLayer;
end;
TFirstLayer = record
.
.
SecondLayer :TSecondLayer;
end;
Jobs : array [0..9] of TFirstLayer;
And we want to save Jobs in a file for later use.
I tried many approaches to solve this problem.
I finally tried to make it a Component to benefit
from Delphi's Component streaming capabilities
and defore starting struggling with DefineProperty,
DefineBinaryProperty, ReadData, WriteData etc.,
I posted a message to Borland's NewsGroups
and then Rick Rogers from TeamB pointed to me
the right direction.
My question:
=========================================================
I have a component with some properties like records and array of
records. Can I store it to a disk file including its properties
and all the data they hold?
And how can I read it back from disk?
Here is an example of my component:
//====================== unit Jobs ==========================
unit Jobs;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TJobType = (jtNormal, jtSpecial, jtFull, jtEmpty);
TMyEnum = (meOne, meTwo, meThree, meFour, meFive);
TJobLabel = record
JobName,
Job_ID : string;
JobType : TJobType;
end;
TThirdLayer = record
S : string;
I : integer;
B : boolean;
F : double;
end;
TSecondLayer = record
aRect : TRect;
aSet : set of TMyEnum;
ThirdLayer : TThirdLayer;
end;
TJob = record // First Layer
Index : integer;
Name : string;
Full : boolean;
SecondLayer : TSecondLayer;
end;
type
TJobHolder = class(TComponent)
private
//================================================================
FJobLabel : TJobLabel;
FJobArray : array [0..9] of TJob;
function GetJobArray(Index:integer):TJob;
procedure SetJobArray(Index:integer; Value:TJob);
public
//================================================================
published
//===============================================================
property JobLabel:TJobLabel read FJobLabel write FJobLabel;
property JobArray[Index:integer]:TJob read GetJobArray write
SetJobArray;
end;
implementation
{-------------------------GetJobArray------------------------------------}
function TJobHolder.GetJobArray(Index:integer):TJob;
begin
Result:=FJobArray[Index];
end; { GetJobArray }
{----------------------------SetJobArray--------------------------------}
procedure TJobHolder.SetJobArray(Index:integer; Value:TJob);
begin
FJobArray[Index]:=Value;
end; { SetJobArray }
end.
//====================== EOF unit Jobs ==========================
TIA
--
===================================================
Theodoros Bebekis
Thessaloniki, Greece
[email protected]
=====================================================
Rick's reply:
=====================================================
On 18 Jun 1998 14:13:38 GMT, "Theodoros Bebekis"
<
[email protected]> wrote:
> Can I store it to a disk file including its properties
> and all the data they hold?
Two ways. First, use ReadComponentResFile and WriteComponentResFile.
This takes advantage of Delphi's automatic and powerful component
streaming system.
However, to use component streams, you'll need to change your class
structure in a number of ways. That's because only certain published
properties (not including records) are automatically written to the
stream (because RTTI isn't generated for records).
Here are the changes: 1) you'll need to change TJobLabel,
TSecondLayer, and TThirdLayer to descend from TPersistent; 2) you'll
need publish all properties in TJobLabel, TSecondLayer, and
TThirdLayer which you want persistent; and 3) you'll need to change
TJobRecord to descend from TCollectionItem, FJobArray to TCollection,
and publish the JobArray collection property.
Alternatively, you could simply write a LoadFromStream and
SaveToStream method for TJobHolder. Of course, this means you'll need
to implement file i/o (such FileStream.ReadBuffer) logic to read and
write the file format you design.
--
Rick Rogers (TeamB) | Fenestra Technologies
http://www.fenestra.com/
=======================================================
I found a relevant example in VCL - DBGrid.Columns - and finally
I made TJobHolder class to work.
I have also made some routines in case somebody needs to save
a component like this to BlobField, using TBlobStream.
Thats all.
Copy all files in the same directory, compile and run
PS. Sorry for uncommented code but I think its easy
to understand what is going on if you study it
Theodoros