DelphiRulez
asked on
Streaming Objects to File ?
I am using Delphi 2010. I am creating a small application to create a Quiz. I have created my own unit (UntCommon) which includes the following classes (Objects)
TQuiz
TQuestions
TQuestion
Question 1: Why am I getting the error message
"[DCC Error] UntCommon.pas(46): E2188 Published property 'Items' cannot be of type ARRAY"
for the "Items" property of the TQuestions class?
Question 2: How can I save a Quiz to file (possibly stream) it in somekind of binary format. I would like the answer for each question to be encrypted ( I will work on that later), but for now, im not worried about anything being hacked or readable in the file....but it would be nice to be able to stream it as binary.
I have created two procedures in the TQuiz class (commented out).
Procedure SaveToFile(FileName: String);
Procedure LoadFromFile(FileName: String);
Question 3: Do you see anything else wrong with my code? Most of it was pieced together from help i found using google.
Thanks
TQuiz
TQuestions
TQuestion
Question 1: Why am I getting the error message
"[DCC Error] UntCommon.pas(46): E2188 Published property 'Items' cannot be of type ARRAY"
for the "Items" property of the TQuestions class?
Question 2: How can I save a Quiz to file (possibly stream) it in somekind of binary format. I would like the answer for each question to be encrypted ( I will work on that later), but for now, im not worried about anything being hacked or readable in the file....but it would be nice to be able to stream it as binary.
I have created two procedures in the TQuiz class (commented out).
Procedure SaveToFile(FileName: String);
Procedure LoadFromFile(FileName: String);
Question 3: Do you see anything else wrong with my code? Most of it was pieced together from help i found using google.
Thanks
unit UntCommon;
interface
uses Classes, Contnrs, Graphics;
type
TQuizType = (qtTrueFalse, qtMultipleChoice, qtFillBlanks, qtAll);
TQuestion = class(TObject)
private
fQuestion: String;
fAnswer: String;
fAnswers: TStringList;
fImage: TPicture;
procedure SetQuestion(Value: String);
procedure SetAnswer(Value: String);
procedure SetAnswers(Value: TStrings);
procedure SetImage(Value: TPicture);
function GetQuestion: String;
function GetAnswer: String;
function GetAnswers: TStrings;
function GetImage: TPicture;
public
constructor Create;
destructor Destroy;override;
published
property Question: String read GetQuestion write SetQuestion;
property Answer: String read GetAnswer write SetAnswer;
property Answers: TStrings read GetAnswers write SetAnswers;
property Image: TPicture read GetImage write SetImage;
end;
TQuestions = class(TObjectList)
private
function GetItems(Index: Integer): TQuestion;
procedure SetItems(Index: Integer; value: TQuestion);
public
constructor Create;
function Add(value: TQuestion): Integer;
function IndexOf(value: TQuestion): Integer;
procedure Insert(Index: Integer; value: TQuestion);
function Remove(value: TQuestion): Integer;
published
property Items[Index: Integer]: TQuestion read GetItems write SetItems; default;
end;
TQuiz = class(TObject)
private
fTitle: String;
fType: TQuizType;
fAuthor: String;
fQuestions: TQuestions;
procedure SetTitle(Value: String);
procedure SetType(Value: TQuizType);
procedure SetAuthor(Value: String);
procedure SetQuestions(Value: TQuestions);
function GetTitle: String;
function GetType: TQuizType;
function GetAuthor: String;
function GetQuestions: TQuestions;
public
constructor Create;
destructor Destroy;override;
//procedure SaveToFile(FileName: String);
//procedure LoadToFile(FileName: String);
published
property Title: String read GetTitle write SetTitle;
property QuizType: TQuizType read GetType write SetType;
property Author: String read GetAuthor write SetAuthor;
property Questions: TQuestions read GetQuestions write SetQuestions;
end;
implementation
{********** TQuestion **********}
procedure TQuestion.SetQuestion(Value: String);
begin
if fQuestion <> Value then
fQuestion:= Value;
end;
procedure TQuestion.SetAnswer(Value: String);
begin
if fAnswer <> Value then
fAnswer:= Value;
end;
procedure TQuestion.SetAnswers(Value: TStrings);
begin
fAnswers.Assign(Value);
end;
procedure TQuestion.SetImage(Value: TPicture);
begin
fImage.Assign(Value);
end;
function TQuestion.GetQuestion: String;
begin
result:= fQuestion;
end;
function TQuestion.GetAnswer: String;
begin
result:= fAnswer;
end;
function TQuestion.GetAnswers: TStrings;
begin
result.Assign(fAnswers);
end;
function TQuestion.GetImage: TPicture;
begin
result.Assign(fImage);
end;
constructor TQuestion.Create;
begin
inherited Create;
fAnswers:= TSTringList.Create;
fImage:= TPicture.Create;
fImage:= nil;
end;
destructor TQuestion.Destroy;
begin
fImage.Free;
fAnswers.Free;
inherited Destroy;
end;
{********** TQUESTIONS **********}
constructor TQuestions.Create;
begin
inherited Create(true);
end;
function TQuestions.Add(value: TQuestion): Integer;
begin
Result := inherited Add(value);
end;
function TQuestions.GetItems(Index: Integer): TQuestion;
begin
Result := TQuestion(inherited Items[Index]);
end;
function TQuestions.IndexOf(value: TQuestion): Integer;
begin
Result := inherited IndexOf(value);
end;
procedure TQuestions.Insert(Index: Integer; value: TQuestion);
begin
inherited Insert(Index, value);
end;
function TQuestions.Remove(value: TQuestion): Integer;
begin
Result := inherited Remove(value);
end;
procedure TQuestions.SetItems(Index: Integer; value: TQuestion);
begin
inherited Items[Index] := value;
end;
{********** TQUIZ **********}
procedure TQuiz.SetTitle(Value: String);
begin
if fTitle <> Value then
fTitle:= Value;
end;
function TQuiz.GetTitle: String;
begin
result:= fTitle;
end;
procedure TQuiz.SetType(Value: TQuizType);
begin
if fType <> Value then
fType:= Value;
end;
function TQuiz.GetType: TQuizType;
begin
result:= fType;
end;
procedure TQuiz.SetAuthor(Value: String);
begin
if fAuthor <> Value then
fAuthor:= Value;
end;
function TQuiz.GetAuthor: String;
begin
result:= fAuthor;
end;
procedure TQuiz.SetQuestions(Value: TQuestions);
begin
fQuestions.Assign(Value);
end;
function TQuiz.GetQuestions: TQuestions;
begin
result.assign(fQuestions);
end;
constructor TQuiz.Create;
begin
inherited Create;
fQuestions:= TQuestions.Create;
fQuestions.OwnsObjects:= True;
end;
destructor TQuiz.Destroy;
begin
fQuestions.Free;
inherited Destroy;
end;
end.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Not sure if I should use Memory Stream or file streams. Which is the best?
procedure TQuiz.SaveToFile(FileName: String);
var
AStr: TFileStream;
begin
AStr:= TFileStream.Create(FileNam e, fmOpenWrite);
//
AStr.Free;
end;
procedure TQuiz.LoadToFile(FileName: String);
var
AStr: TFileStream;
begin
AStr:= TFileStream.Create(FileNam e, fmOpenRead);
//
AStr.Free;
end;
procedure TQuiz.SaveToFile(FileName:
var
AStr: TFileStream;
begin
AStr:= TFileStream.Create(FileNam
//
AStr.Free;
end;
procedure TQuiz.LoadToFile(FileName:
var
AStr: TFileStream;
begin
AStr:= TFileStream.Create(FileNam
//
AStr.Free;
end;
I would use FileStream, or a plan TextFile that you can read and write as well to.
ASKER
well, im still waiting on the SaveToFIle and LoadFrom File procedures
I may have them written before i get a answer from you experts (just from info im gathering from google and EE Search)
procedure TQuiz.SaveToFile(FileName: String);
var
AStr: TFileStream;
I: Integer;
begin
AStr:= TFileStream.Create(FileNam e, fmOpenWrite);
WriteStreamInt(AStr, Questions.Count);
for I:= 0 to Questions.Count-1 do
begin
WriteStreamStr(AStr, TQuestion(Questions[I]).fQ uestion);
//write rest of question data here
end;
AStr.Free;
end;
procedure TQuiz.LoadFromFile(FileNam e: String);
var
AStr: TFileStream;
QCount, I: Integer;
AQuestion: TQuestion;
begin
AStr:= TFileStream.Create(FileNam e, fmOpenRead);
QCount:= ReadStreamInt(AStr);
for I:= 0 to QCount-1 do
begin
AQuestion:= TQuestion.Create;
AQuestion.fQuestion:= ReadStreamStr(AStr);
//read rest of question data here
Questions.Add(AQuestion);
end;
AStr.Free;
end;
procedure WriteStreamStr(Stream : TStream; Str : string);
var
StrLen : integer;
begin
StrLen := Length(Str);
WriteStreamInt(Stream, StrLen);
Stream.Write(Str[1], StrLen);
end;
function ReadStreamStr(Stream : TStream) : string;
var
StrLen : integer;
begin
StrLen := ReadStreamInt(Stream);
if StrLen > -1 then begin
SetLength(Result, StrLen);
Stream.Read(Result[1], StrLen);
end
else
Result := '';
end;
procedure WriteStreamInt(Stream : TStream; Num : integer);
begin
Stream.Write(Num, SizeOf(Integer));
end;
function ReadStreamInt(Stream : TStream) : integer;
begin
if Stream.Read(Result, SizeOf(Integer)) < SizeOf(Integer) then
Result := -1;
end;
I may have them written before i get a answer from you experts (just from info im gathering from google and EE Search)
procedure TQuiz.SaveToFile(FileName:
var
AStr: TFileStream;
I: Integer;
begin
AStr:= TFileStream.Create(FileNam
WriteStreamInt(AStr, Questions.Count);
for I:= 0 to Questions.Count-1 do
begin
WriteStreamStr(AStr, TQuestion(Questions[I]).fQ
//write rest of question data here
end;
AStr.Free;
end;
procedure TQuiz.LoadFromFile(FileNam
var
AStr: TFileStream;
QCount, I: Integer;
AQuestion: TQuestion;
begin
AStr:= TFileStream.Create(FileNam
QCount:= ReadStreamInt(AStr);
for I:= 0 to QCount-1 do
begin
AQuestion:= TQuestion.Create;
AQuestion.fQuestion:= ReadStreamStr(AStr);
//read rest of question data here
Questions.Add(AQuestion);
end;
AStr.Free;
end;
procedure WriteStreamStr(Stream : TStream; Str : string);
var
StrLen : integer;
begin
StrLen := Length(Str);
WriteStreamInt(Stream, StrLen);
Stream.Write(Str[1], StrLen);
end;
function ReadStreamStr(Stream : TStream) : string;
var
StrLen : integer;
begin
StrLen := ReadStreamInt(Stream);
if StrLen > -1 then begin
SetLength(Result, StrLen);
Stream.Read(Result[1], StrLen);
end
else
Result := '';
end;
procedure WriteStreamInt(Stream : TStream; Num : integer);
begin
Stream.Write(Num, SizeOf(Integer));
end;
function ReadStreamInt(Stream : TStream) : integer;
begin
if Stream.Read(Result, SizeOf(Integer)) < SizeOf(Integer) then
Result := -1;
end;
ASKER
ok, all i have left to write is the Streaming of the TPicture (Not sure if this is do-able or not) .
of course, none of this is tested. Its just compiling so far. Anyone see any other mistakes or problems i have not foreseen????????? Can anyone write the code to stream a TPicture?
I need to be able to handle all registered image classes within Delphi (bmp, jpg, gif, png, ect).
Do i need to store an extension, size, ect in the stream????????
procedure TQuiz.SaveToFile(FileName: String);
var
AStr: TFileStream;
I, J: Integer;
begin
AStr:= TFileStream.Create(FileNam e, fmOpenWrite);
WriteStreamStr(AStr, Title);
WriteStreamInt(AStr, Integer(QuizType));
WriteStreamStr(AStr, Author);
WriteStreamInt(AStr, Questions.Count);
for I:= 0 to Questions.Count-1 do
begin
WriteStreamStr(AStr, TQuestion(Questions[I]).fQ uestion);
WriteStreamStr(AStr, TQuestion(Questions[I]).fA nswer);
WriteStreamInt(AStr, TQuestion(Questions[I]).fA nswers.Cou nt);
for J:= 0 to TQuestion(Questions[I]).fA nswers.Cou nt - 1 do
begin
WriteStreamStr(AStr, TQuestion(Questions[I]).fA nswers[J]) ;
end;
//write the TPicture to Stream
end;
AStr.Free;
end;
procedure TQuiz.LoadFromFile(FileNam e: String);
var
AStr: TFileStream;
QCount, ACOunt, I: Integer;
AQuestion: TQuestion;
J: Integer;
begin
AStr:= TFileStream.Create(FileNam e, fmOpenRead);
Title:= ReadStreamStr(AStr);
QuizType:= TQuizType(ReadStreamInt(AS tr));
Author:= ReadStreamStr(AStr);
QCount:= ReadStreamInt(AStr);
for I:= 0 to QCount-1 do
begin
AQuestion:= TQuestion.Create;
AQuestion.fQuestion:= ReadStreamStr(AStr);
AQuestion.fAnswer:= ReadStreamStr(AStr);
ACount:= ReadStreamInt(AStr);
for J := 0 to ACount - 1 do
begin
AQuestion.fAnswers.Add(Rea dStreamStr (AStr));
end;
//read the TPicture from Stream
Questions.Add(AQuestion);
end;
AStr.Free;
end;
function Encrypt(const S: String; Key: Word): String;
var
I: byte;
begin
SetLength(Result, Length(S));
for I := 1 to Length(S) do
begin
Result[I] := char(byte(S[I]) xor (Key shr 8));
Key := (byte(Result[I]) + Key) * C1 + C2;
end;
end;
function Decrypt(const S: String; Key: Word): String;
var
I: byte;
begin
SetLength(Result, Length(S));
for I := 1 to Length(S) do
begin
Result[I] := char(byte(S[I]) xor (Key shr 8));
Key := (byte(S[I]) + Key) * C1 + C2;
end;
end;
procedure WriteStreamStr(Stream : TStream; Str : string);
var
StrLen : integer;
begin
StrLen := Length(Str);
WriteStreamInt(Stream, StrLen);
Stream.Write(Str[1], StrLen);
end;
function ReadStreamStr(Stream : TStream) : string;
var
StrLen : integer;
begin
StrLen := ReadStreamInt(Stream);
if StrLen > -1 then begin
SetLength(Result, StrLen);
Stream.Read(Result[1], StrLen);
end
else
Result := '';
end;
procedure WriteStreamInt(Stream : TStream; Num : integer);
begin
Stream.Write(Num, SizeOf(Integer));
end;
function ReadStreamInt(Stream : TStream) : integer;
begin
if Stream.Read(Result, SizeOf(Integer)) < SizeOf(Integer) then
Result := -1;
end;
of course, none of this is tested. Its just compiling so far. Anyone see any other mistakes or problems i have not foreseen????????? Can anyone write the code to stream a TPicture?
I need to be able to handle all registered image classes within Delphi (bmp, jpg, gif, png, ect).
Do i need to store an extension, size, ect in the stream????????
procedure TQuiz.SaveToFile(FileName:
var
AStr: TFileStream;
I, J: Integer;
begin
AStr:= TFileStream.Create(FileNam
WriteStreamStr(AStr, Title);
WriteStreamInt(AStr, Integer(QuizType));
WriteStreamStr(AStr, Author);
WriteStreamInt(AStr, Questions.Count);
for I:= 0 to Questions.Count-1 do
begin
WriteStreamStr(AStr, TQuestion(Questions[I]).fQ
WriteStreamStr(AStr, TQuestion(Questions[I]).fA
WriteStreamInt(AStr, TQuestion(Questions[I]).fA
for J:= 0 to TQuestion(Questions[I]).fA
begin
WriteStreamStr(AStr, TQuestion(Questions[I]).fA
end;
//write the TPicture to Stream
end;
AStr.Free;
end;
procedure TQuiz.LoadFromFile(FileNam
var
AStr: TFileStream;
QCount, ACOunt, I: Integer;
AQuestion: TQuestion;
J: Integer;
begin
AStr:= TFileStream.Create(FileNam
Title:= ReadStreamStr(AStr);
QuizType:= TQuizType(ReadStreamInt(AS
Author:= ReadStreamStr(AStr);
QCount:= ReadStreamInt(AStr);
for I:= 0 to QCount-1 do
begin
AQuestion:= TQuestion.Create;
AQuestion.fQuestion:= ReadStreamStr(AStr);
AQuestion.fAnswer:= ReadStreamStr(AStr);
ACount:= ReadStreamInt(AStr);
for J := 0 to ACount - 1 do
begin
AQuestion.fAnswers.Add(Rea
end;
//read the TPicture from Stream
Questions.Add(AQuestion);
end;
AStr.Free;
end;
function Encrypt(const S: String; Key: Word): String;
var
I: byte;
begin
SetLength(Result, Length(S));
for I := 1 to Length(S) do
begin
Result[I] := char(byte(S[I]) xor (Key shr 8));
Key := (byte(Result[I]) + Key) * C1 + C2;
end;
end;
function Decrypt(const S: String; Key: Word): String;
var
I: byte;
begin
SetLength(Result, Length(S));
for I := 1 to Length(S) do
begin
Result[I] := char(byte(S[I]) xor (Key shr 8));
Key := (byte(S[I]) + Key) * C1 + C2;
end;
end;
procedure WriteStreamStr(Stream : TStream; Str : string);
var
StrLen : integer;
begin
StrLen := Length(Str);
WriteStreamInt(Stream, StrLen);
Stream.Write(Str[1], StrLen);
end;
function ReadStreamStr(Stream : TStream) : string;
var
StrLen : integer;
begin
StrLen := ReadStreamInt(Stream);
if StrLen > -1 then begin
SetLength(Result, StrLen);
Stream.Read(Result[1], StrLen);
end
else
Result := '';
end;
procedure WriteStreamInt(Stream : TStream; Num : integer);
begin
Stream.Write(Num, SizeOf(Integer));
end;
function ReadStreamInt(Stream : TStream) : integer;
begin
if Stream.Read(Result, SizeOf(Integer)) < SizeOf(Integer) then
Result := -1;
end;
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
property Items[Index: Integer]
should be
property Items(Index: Integer)