How to save a form with VCL controls on it

This is the forum for miscellaneous technical/programming questions.

Moderator: 2ffat

How to save a form with VCL controls on it

Postby maksim_volodin » Wed Jan 22, 2020 2:29 am

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.
maksim_volodin
 
Posts: 3
Joined: Thu Oct 10, 2019 11:56 pm

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

Postby rlebeau » Fri Jan 24, 2020 12:17 pm

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
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1665
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

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

Postby maksim_volodin » Sat Jan 25, 2020 2:19 pm

How would you recommend to clear the TForm of any components?
maksim_volodin
 
Posts: 3
Joined: Thu Oct 10, 2019 11:56 pm

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

Postby HsiaLin » Sun Jan 26, 2020 1:29 pm

Just save the form it should save it all.
HsiaLin
BCBJ Master
BCBJ Master
 
Posts: 320
Joined: Sun Jul 08, 2007 6:29 pm

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

Postby rlebeau » Sun Jan 26, 2020 9:40 pm

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
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1665
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

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

Postby Ahmed Sayed » Mon Jan 27, 2020 3:11 am

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.
Ahmed Sayed
Top Poster
Top Poster
 
Posts: 33
Joined: Thu Nov 08, 2018 4:12 pm

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

Postby rlebeau » Tue Jan 28, 2020 2:13 pm

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
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1665
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

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

Postby maksim_volodin » Fri Jan 31, 2020 12:59 am

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?
maksim_volodin
 
Posts: 3
Joined: Thu Oct 10, 2019 11:56 pm

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

Postby rlebeau » Fri Jan 31, 2020 12:43 pm

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
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1665
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA


Return to Technical

Who is online

Users browsing this forum: Majestic-12 [Bot], mark_c and 15 guests