How to save a form with VCL controls on it

This is the forum for miscellaneous technical/programming questions.

Moderator: 2ffat

Post Reply
maksim_volodin
Posts: 3
Joined: Thu Oct 10, 2019 11:56 pm

How to save a form with VCL controls on it

Post by maksim_volodin »

What are practices for saving and opening a form with VCL controls on it?
I used this code for saving

Code: Select all

 
   TFileStream* FS = new TFileStream(File, fmCreate);
   for(int i=0;i<CompositeBeamMainForm->ComponentCount;++i)
        FS->WriteComponent(CompositeBeamMainForm->Components[i]);
   delete(FS);

and this code for opening

Code: Select all

     TFileStream* FS = new TFileStream(FileDir_Name, fmOpenRead);
     for(int i=0;i<CompositeBeamMainForm->ComponentCount;++i)
      FS->ReadComponent(CompositeBeamMainForm->Components[i]);
    delete(FS);
then I got warnings "Class TToolButton not found" and "Class TTabSheet not found".
After investigating Internet, I made registrations of those classes in VCL stream system as follows:

Code: Select all

     TComponentClass classes[2] = {__classid(TToolButton),__classid(TTabSheet)};
     RegisterClasses(classes, 1);
The warnings mentioned above were gone but the new one appears when I try to open saved files second time. "A component named ToolButton1 already exists".
What is the reason for this message? How to avoid it? Are there better ways to save forms?
Last edited by maksim_volodin on Fri Jan 31, 2020 1:01 am, edited 1 time in total.
rlebeau
BCBJ Author
BCBJ Author
Posts: 1709
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA
Contact:

Re: How ta save a form with VCL controls on it

Post by rlebeau »

Rather than writing/reading the individual components, try writing/reading just the TForm itself instead. And make sure you clear the TForm of any components before you read the stream, as the reading will create new instances of the child controls that are stored in the stream, which is why you are getting "already exists" errors.

Also, you should not have to register the component classes manually, they should already be registered at program startup, or else your TForm would have failed to stream in from its main DFM resource to begin with.
Last edited by rlebeau on Sun Jan 26, 2020 9:39 pm, edited 1 time in total.
Remy Lebeau (TeamB)
Lebeau Software
maksim_volodin
Posts: 3
Joined: Thu Oct 10, 2019 11:56 pm

Re: How ta save a form with VCL controls on it

Post by maksim_volodin »

How would you recommend to clear the TForm of any components?
HsiaLin
BCBJ Master
BCBJ Master
Posts: 331
Joined: Sun Jul 08, 2007 6:29 pm

Re: How ta save a form with VCL controls on it

Post by HsiaLin »

Just save the form it should save it all.
rlebeau
BCBJ Author
BCBJ Author
Posts: 1709
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA
Contact:

Re: How ta save a form with VCL controls on it

Post by rlebeau »

maksim_volodin wrote:How would you recommend to clear the TForm of any components?
Loop through the Form's Components[] list delete'ing them all.
Remy Lebeau (TeamB)
Lebeau Software
Ahmed Sayed
Top Poster
Top Poster
Posts: 35
Joined: Thu Nov 08, 2018 4:12 pm

Re: How ta save a form with VCL controls on it

Post by Ahmed Sayed »

I think this mechanism is buggy in RAD Studio in general because when I try to save a third party Component
in say a file or table field and try to read the component back it always gives error whether the a certain TClass is not registered and I have to Register it with RegisterClass first. But when i do so the compiler complains about it does know what is this class for example TmyButton. So i had to add the header file in the include clauses. Even so still app gives me an access violation when i try to read the stream into component. The only way to make it work is that you have to drop the component you want to create dynamically at least once on the form that will create it. I don't why it has to be done this way maybe C++ builder is different from Delphi as usual.
rlebeau
BCBJ Author
BCBJ Author
Posts: 1709
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA
Contact:

Re: How ta save a form with VCL controls on it

Post by rlebeau »

Ahmed Sayed wrote:I think this mechanism is buggy in RAD Studio in general
It is not buggy. It is just not really intended to be used this way.
Ahmed Sayed wrote:when I try to save a third party Component in say a file or table field and try to read the component back it always gives error whether the a certain TClass is not registered and I have to Register it with RegisterClass first.
All streamable classes need to be registered at runtime before they can be streamed. Components placed on a Form/Frame/DataModule at design-time are registered automatically at runtime before they are streamed in from a DFM resource.
Ahmed Sayed wrote:But when i do so the compiler complains about it does know what is this class for example TmyButton. So i had to add the header file in the include clauses.
Yes, if you register the class manually, then of course you have to tell the compiler what the class is.
Ahmed Sayed wrote:Even so still app gives me an access violation when i try to read the stream into component.
Then you are likely not using the streaming system correctly.
Ahmed Sayed wrote:The only way to make it work is that you have to drop the component you want to create dynamically at least once on the form that will create it. I don't why it has to be done this way maybe C++ builder is different from Delphi as usual.
There is no difference between Delphi and C++Builder in this regard. This is just how the DFM system works.
Remy Lebeau (TeamB)
Lebeau Software
maksim_volodin
Posts: 3
Joined: Thu Oct 10, 2019 11:56 pm

Re: How ta save a form with VCL controls on it

Post by maksim_volodin »

It is not buggy. It is just not really intended to be used this way.
To conclude, to save data entered by a user in a file, it is not recommended to use VCL controls, as "streamable" objects as it was designed primarily for other needs, but to apply "classic" approach, that is to create a structure or a class object with data members containing content of VCL controls and to process it with FILE structure or ofstream objects or with TFileStream object calling WriteBuffer() method.
Remy, what is your preference?
rlebeau
BCBJ Author
BCBJ Author
Posts: 1709
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA
Contact:

Re: How ta save a form with VCL controls on it

Post by rlebeau »

maksim_volodin wrote:Remy, what is your preference?
I have no preference. I have used all of those techniques. I use whatever best suits the situation.
Remy Lebeau (TeamB)
Lebeau Software
Post Reply