Board index » delphi » Saving form contents to Memorystream

Saving form contents to Memorystream

Hi
I have a form with a number of controls on it, whose positions, contents and
even the number & type of controls need to be updated dynamically.
Basically I want to save the contents of the form to a TMemoryStream at any
given time so that in case i need to do a "Session Recall", i can just
select the respective TMemoryStream and the form regenerates all the
controls along with their saved properties within it .... something akin to
the way DFM files are saved.

The only thing is that this has to be a single form.

One option was to manually enter each type of control within a record along
with its properties and save them in the memorystream which is way too
tedious.

Any help as to how this can be done ?

Regards
X

 

Re:Saving form contents to Memorystream


Quote
> Basically I want to save the contents of the form to a TMemoryStream at
any
> given time

yourMemoryStream.WriteComponent(yourForm)
--
With best regards, Mike Shkolnik
E-mail: mshkol...@scalabium.com
WEB: http://www.scalabium.com

Re:Saving form contents to Memorystream


Hi Mike
Thanks ... but i tried the reverse process (retrieving the form contents
from a memoryStream) it doesnt work ... I mean it says cannot find TPanel
etc etc.

Quote
"Mike Shkolnik" <mshkolnik2...@ukr.net> wrote in message

news:448b230c@newsgroups.borland.com...
Quote
> > Basically I want to save the contents of the form to a TMemoryStream at
> any
> > given time
> yourMemoryStream.WriteComponent(yourForm)
> --
> With best regards, Mike Shkolnik
> E-mail: mshkol...@scalabium.com
> WEB: http://www.scalabium.com

Re:Saving form contents to Memorystream


Quote
Mr. X wrote:
> Hi Mike
> Thanks ... but i tried the reverse process (retrieving the form
> contents from a memoryStream) it doesnt work ... I mean it says
> cannot find TPanel etc etc.

If you create control/component types on your form in code that are not
also among those dropped on the form at design-time you need to
register the classes used with the streaming system via RegisterClass.

--
Peter Below (TeamB)  
Don't be a vampire (http://slash7.com/pages/vampires),
use the newsgroup archives :
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be

Re:Saving form contents to Memorystream


No
Actually i tried with the RegisterClass at unit intialization but when im
trying to retrive the saved file, i get those error messages.

"Peter Below (TeamB)" <none> wrote in message
news:xn0encfmp1bqx3001@newsgroups.borland.com...

Quote
> Mr. X wrote:

> > Hi Mike
> > Thanks ... but i tried the reverse process (retrieving the form
> > contents from a memoryStream) it doesnt work ... I mean it says
> > cannot find TPanel etc etc.

> If you create control/component types on your form in code that are not
> also among those dropped on the form at design-time you need to
> register the classes used with the streaming system via RegisterClass.

> --
> Peter Below (TeamB)
> Don't be a vampire (http://slash7.com/pages/vampires),
> use the newsgroup archives :
> http://www.tamaracka.com/search.htm
> http://groups.google.com
> http://www.prolix.be

Re:Saving form contents to Memorystream


Quote
Mr. X wrote:
> No
> Actually i tried with the RegisterClass at unit intialization but
> when im trying to retrive the saved file, i get those error messages.

If the error message are indeed what i think you tried to tell us then
the component classes are not registered, regardless of what you think
you did. The error may be something different, though. Give us the
*exact* error message you get.

--
Peter Below (TeamB)  
Don't be a vampire (http://slash7.com/pages/vampires),
use the newsgroup archives :
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be

Re:Saving form contents to Memorystream


Ok,
Here is the sample code (below)
The TPanel has a button, radioButton, listbox and image parented to it.
Everything is been made at designTime.
Once the form contents are saved, cleared and the form is clicked the
contents reload perfectly.
After the reload from the memorystream, clicking the "ClearButton" raises
this exception :
Project Project2.exe raised exception class EAccessViolation with message
'Access violation at address 00403714 in module 'project2.exe'. Read of
address 00D88000. ........

So my question now is :
1) once the controls are got from the memory stream, what are the ownership
issues like ?
2) Will the controls preserve their links to assigned events etc ?

Regards
X

----------------------------------------------------------------------------
----------------------------------------
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, jpeg;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    RadioButton1: TRadioButton;
    ListBox1: TListBox;
    SaveButton: TButton;
    ClearButton: TButton;
    LoadButton: TButton;
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure SaveButtonClick(Sender: TObject);
    procedure ClearButtonClick(Sender: TObject);
    procedure FormClick(Sender: TObject);
  private
    FMemStream: TMemoryStream;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FMemStream := TmemoryStream.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FMemStream.Free;
end;

procedure TForm1.SaveButtonClick(Sender: TObject);
begin
  FMemStream.WriteComponent(Form1);
end;

procedure TForm1.ClearButtonClick(Sender: TObject);
begin
  Panel1.Free;
  savebutton.Free;
  loadbutton.Free;
  clearbutton.Free;
end;

procedure TForm1.FormClick(Sender: TObject);
begin
  FMemStream.Position := 0;
  FMemStream.ReadComponent(Form1);
end;

end.

"Peter Below (TeamB)" <none> wrote in message
news:xn0end17zst1z001@newsgroups.borland.com...

Quote
> Mr. X wrote:

> > No
> > Actually i tried with the RegisterClass at unit intialization but
> > when im trying to retrive the saved file, i get those error messages.

> If the error message are indeed what i think you tried to tell us then
> the component classes are not registered, regardless of what you think
> you did. The error may be something different, though. Give us the
> *exact* error message you get.

> --
> Peter Below (TeamB)
> Don't be a vampire (http://slash7.com/pages/vampires),
> use the newsgroup archives :
> http://www.tamaracka.com/search.htm
> http://groups.google.com
> http://www.prolix.be

Re:Saving form contents to Memorystream


Quote
Mr. X wrote:
> Ok,
> Here is the sample code (below)
> The TPanel has a button, radioButton, listbox and image parented to
> it.  Everything is been made at designTime.
> Once the form contents are saved, cleared and the form is clicked the
> contents reload perfectly.
> After the reload from the memorystream, clicking the "ClearButton"
> raises this exception :
> Project Project2.exe raised exception class EAccessViolation with
> message 'Access violation at address 00403714 in module
> 'project2.exe'. Read of address 00D88000. ........

Which is a completely different error from what you told us in the
last message of this thread mentioning an error.

Quote

> So my question now is :
> 1) once the controls are got from the memory stream, what are the
> ownership issues like ?
> 2) Will the controls preserve their links to assigned events etc ?

> Regards
> X

> ----------------------------------------------------------------------
> ------ ----------------------------------------
> unit Unit1;

> interface

> uses
>   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
> Forms,   Dialogs, StdCtrls, ExtCtrls, jpeg;

> type
>   TForm1 = class(TForm)
>     Panel1: TPanel;
>     Button1: TButton;
>     RadioButton1: TRadioButton;
>     ListBox1: TListBox;
>     SaveButton: TButton;
>     ClearButton: TButton;
>     LoadButton: TButton;
>     Image1: TImage;
>     procedure FormCreate(Sender: TObject);
>     procedure FormDestroy(Sender: TObject);
>     procedure SaveButtonClick(Sender: TObject);
>     procedure ClearButtonClick(Sender: TObject);
>     procedure FormClick(Sender: TObject);
>   private
>     FMemStream: TMemoryStream;
>   public
>     { Public declarations }
>   end;

> var
>   Form1: TForm1;

> implementation

> {$R *.dfm}

> procedure TForm1.FormCreate(Sender: TObject);
> begin
>   FMemStream := TmemoryStream.Create;
> end;

> procedure TForm1.FormDestroy(Sender: TObject);
> begin
>   FMemStream.Free;
> end;

> procedure TForm1.SaveButtonClick(Sender: TObject);
> begin
>   FMemStream.WriteComponent(Form1);
> end;

> procedure TForm1.ClearButtonClick(Sender: TObject);
> begin
>   Panel1.Free;
>   savebutton.Free;
>   loadbutton.Free;
>   clearbutton.Free;
> end;

Here you are sawing off the branch you are sitting on. The consequences
are, not unexpectedly, rather painful <g>.

You cannot destroy a component from an event handler of that component,
which you are doing here since the method is the handler for the
ClearButtons OnClick event. After the code flow exits the method it
will try to access things in the now dead button, that is the cause of
your access violations.

The typical solution to this problem is to have the event handler post
(via PostMessage) a custom message to the form. The messages handler
can then destroy the component safely.

--
Peter Below (TeamB)  
Don't be a vampire (http://slash7.com/pages/vampires),
use the newsgroup archives :
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be

Re:Saving form contents to Memorystream


Ok
After the custom message implementation ... everything works great now .. :)

"Peter Below (TeamB)" <none> wrote in message
news:xn0ene9u41os9i001@newsgroups.borland.com...

Quote
> Mr. X wrote:

> > Ok,
> > Here is the sample code (below)
> > The TPanel has a button, radioButton, listbox and image parented to
> > it.  Everything is been made at designTime.
> > Once the form contents are saved, cleared and the form is clicked the
> > contents reload perfectly.
> > After the reload from the memorystream, clicking the "ClearButton"
> > raises this exception :
> > Project Project2.exe raised exception class EAccessViolation with
> > message 'Access violation at address 00403714 in module
> > 'project2.exe'. Read of address 00D88000. ........

> Which is a completely different error from what you told us in the
> last message of this thread mentioning an error.

> > So my question now is :
> > 1) once the controls are got from the memory stream, what are the
> > ownership issues like ?
> > 2) Will the controls preserve their links to assigned events etc ?

> > Regards
> > X

> > ----------------------------------------------------------------------
> > ------ ----------------------------------------
> > unit Unit1;

> > interface

> > uses
> >   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
> > Forms,   Dialogs, StdCtrls, ExtCtrls, jpeg;

> > type
> >   TForm1 = class(TForm)
> >     Panel1: TPanel;
> >     Button1: TButton;
> >     RadioButton1: TRadioButton;
> >     ListBox1: TListBox;
> >     SaveButton: TButton;
> >     ClearButton: TButton;
> >     LoadButton: TButton;
> >     Image1: TImage;
> >     procedure FormCreate(Sender: TObject);
> >     procedure FormDestroy(Sender: TObject);
> >     procedure SaveButtonClick(Sender: TObject);
> >     procedure ClearButtonClick(Sender: TObject);
> >     procedure FormClick(Sender: TObject);
> >   private
> >     FMemStream: TMemoryStream;
> >   public
> >     { Public declarations }
> >   end;

> > var
> >   Form1: TForm1;

> > implementation

> > {$R *.dfm}

> > procedure TForm1.FormCreate(Sender: TObject);
> > begin
> >   FMemStream := TmemoryStream.Create;
> > end;

> > procedure TForm1.FormDestroy(Sender: TObject);
> > begin
> >   FMemStream.Free;
> > end;

> > procedure TForm1.SaveButtonClick(Sender: TObject);
> > begin
> >   FMemStream.WriteComponent(Form1);
> > end;

> > procedure TForm1.ClearButtonClick(Sender: TObject);
> > begin
> >   Panel1.Free;
> >   savebutton.Free;
> >   loadbutton.Free;
> >   clearbutton.Free;
> > end;

> Here you are sawing off the branch you are sitting on. The consequences
> are, not unexpectedly, rather painful <g>.

> You cannot destroy a component from an event handler of that component,
> which you are doing here since the method is the handler for the
> ClearButtons OnClick event. After the code flow exits the method it
> will try to access things in the now dead button, that is the cause of
> your access violations.

> The typical solution to this problem is to have the event handler post
> (via PostMessage) a custom message to the form. The messages handler
> can then destroy the component safely.

> --
> Peter Below (TeamB)
> Don't be a vampire (http://slash7.com/pages/vampires),
> use the newsgroup archives :
> http://www.tamaracka.com/search.htm
> http://groups.google.com
> http://www.prolix.be

Other Threads