Ok You ased for it:-
I thought you might need a bit more background so
The objects are made part of a TList so we can use the Savetostream methods
The code is based on PCPlus Tutorial on how to save mixed objects.
TObjectList = Class(TList)
procedure AddObject(Index: integer;
ObjectName: TextStr; // a fixed length string
status: Integer;
Moveable: Boolean;
Position: Integer;
Ten: Tenses;
Text: array of TStringList;
XPos,YPos: integer;
Image: TIcon);
procedure SaveObjects(fname : string );
procedure LoadObjects(fname: string);
end;
TThings = class(TObject)
objectico: TIcon;
Index: integer;
ObjectName: TextStr;
Status: integer;
Moveable: Boolean;
Position: integer;
Tense: Tenses;
Text: array[0..5] of TstringList; // we will have to save the length of the strings!!
XPos: integer;
YPos: integer;
procedure WriteToStream( Fs: TFileStream );
procedure ReadFromStream(Fs: TFileStream);
constructor CreateFromStream(Fs : TFileStream );
private
public
constructor make(item: integer; obj: TextStr; place: integer; stat: integer;
m: boolean; ten: tenses;
Txt: array of TstringList;
x,y:integer;
Image: TIcon);
end;
In the implementation these procedures do the TThing Load/save :-
procedure TThings.WriteToStream(Fs : TFileStream );
var A, B, C: integer;
LineofText: TextStr;
begin
// Here we cannont attempt to save the string list array so we must extratct
// the text and store it as a simple strings
Fs.WriteBuffer(Index, Sizeof(Index));
Fs.WriteBuffer(ObjectName, Sizeof(ObjectName));
Fs.WriteBuffer(Status, Sizeof(Status));
Fs.WriteBuffer(Moveable, Sizeof(Moveable));
Fs.WriteBuffer(Position, Sizeof(Position));
Fs.WriteBuffer(Tense, Sizeof(Tense));
C := 0;
for a := 0 to 5 do
begin
C := text[a].count;
Fs.WriteBuffer(C, Sizeof(C)); // store number of strings on each page
for b := 0 to C - 1 do
begin
LineofText := Text[a].strings;
Fs.WriteBuffer(LineofText, sizeof(LineofText));
end;
end;
Fs.WriteBuffer(XPos, Sizeof(Xpos));
Fs.WriteBuffer(YPos, Sizeof(Ypos));
ObjectIco.SaveToStream(Fs);
end;
procedure TThings.ReadFromStream(Fs: TFileStream);
var A,B,C: integer;
LineofText: TextStr;
begin
Fs.ReadBuffer(Index, sizeof(Index));
Fs.ReadBuffer(ObjectName, sizeof(ObjectName));
Fs.ReadBuffer(Status, Sizeof(Status));
Fs.ReadBuffer(Moveable, sizeof(Moveable));
Fs.ReadBuffer(Position, Sizeof(Position));
Fs.ReadBuffer(Tense, Sizeof(Tense));
// As you can see I also had a problem with the TStringlist field and got round it by
// extracting it to Fixed length strings. The sring list is implictly created here I thought // this might be a clue but doing simular diddnt seem to work with the Icon type.
C := 0;
for A := 0 to 5 do
begin
Fs.ReadBuffer(C, Sizeof(C));
Text[a] := Tstringlist.create;
for b := 0 to C - 1 do
begin
Fs.ReadBuffer(LineofText, sizeof(LineofText));
Text[a].Add(LineofText);
end;
end;
Fs.ReadBuffer(XPos, Sizeof(Xpos));
Fs.ReadBuffer(YPos, Sizeof(Ypos));
ObjectIco.LoadFromStream(Fs); // Here lieth the crash.
end;
At the TList level these are the procedures called by the main form Load/save Actions
If it seems over complex? This is because the other modules have 2 Types of object (none with icons or the like) and the writetostream Procedures are virtual so looping through the TList only need to make one call.
I intend to add this module into the main TList (when I can get it to work).
procedure TObjectList.SaveObjects(Fname : string );
var Fs : TFileStream;
I : integer;
begin
// create a File stream object
Fs := TFileStream.Create(Fname, fmCreate);
try
for i := 0 to ObjList.Count - 1 do
// cast The ObjectList object to a TThing
TThings(ObjList).WriteToStream(Fs);
finally;
Fs.Free;
end;
end;
procedure TObjectList.LoadObjects(Fname : string );
var Fs : TFileStream;
begin
Fs := TFileStream.Create(Fname, fmOpenRead);
try
//read in the object data and create each object as we read it.
while Fs.Position < Fs.Size do
begin
ObjList.Add(TThings.CreateFromStream(Fs));
inc(NumberOfObjects);
end;
finally;
Fs.Free;
end;
end;
The constructer works fine and I am able to create the icons in memory no problem with these two lines
ObjectIco := TIcon.Create;
ObjectIco.Assign(Image);
Where image is a Tcon Passed in from a TImage as Image.picture.icon.
Steve..