How to save components to a file or stream (Views: 30)
Problem/Question/Abstract: I have a component TZzz (descends from TComponent) and I want to implement some saving/ restoring capabilities for it. Here's my point. I want to place a TZzz component in a form and export this object to a file. Later, I want import that file to another TZzz object in another form (only for copying the properties from one object to another). Any ideas? Answer: Here is a component I wrote which I use often. Simply derive from TPersistentComponent and you can then stream it in and out either directly to a stream or to a file as well. You will have to implement the FindMethod method yourself. unit Unit1; interface uses Classes, Sysutils; const cFileDoesNotExist = 'File Does Not Exist %0s'; cDefaultBufSize = 4096; type TPersistComponent = class(TComponent) private FStreamLoad: Boolean; protected property StreamLoad: Boolean read FSTreamLoad; procedure FindMethod(Reader: TReader; const MethodName: string; var Address: Pointer; var Error: Boolean); virtual; public procedure LoadFromFile(const FileName: string; const Init: Boolean = False); virtual; procedure SaveToFile(const FileName: string); virtual; procedure LoadFromStream(Stream: TStream); virtual; procedure SaveToStream(Stream: TStream); virtual; end; implementation procedure TPersistComponent.FindMethod(Reader: TReader; const MethodName: string; var Address: Pointer; var Error: Boolean); begin Error := False; end; procedure TPersistComponent.LoadFromFile(const FileName: string; const Init: Boolean = False); var FS: TFileStream; begin if FileExists(Filename) then begin FS := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); try LoadFromStream(FS); finally FS.Free; end; end else raise Exception.CreateFmt(cFileDoesNotExist, [FileName]); end; procedure TPersistComponent.LoadFromStream(Stream: TStream); var Reader: TReader; begin Reader := TReader.Create(Stream, cDefaultBufSize); try {Reader.OnFindMethod := FindMethod;} FStreamLoad := True; Reader.OnFindMethod := FindMethod; Reader.BeginReferences; Reader.Root := Owner; Reader.ReadComponent(Self); Reader.EndReferences; Loaded; finally FStreamLoad := False; Reader.Free; end; end; procedure TPersistComponent.SaveToFile(const FileName: string); var FS: TFileStream; begin FS := TFileStream.Create(FileName, fmCreate); try SaveToStream(FS); finally FS.Free; end; end; procedure TPersistComponent.SaveToStream(Stream: TStream); var Writer: TWriter; begin Writer := TWriter.Create(Stream, cDefaultBufSize); try Writer.Root := Owner; Writer.WriteComponent(Self); finally Writer.Free; end; end; end. |