tags:

views:

421

answers:

2

We use C++ Builder for an application whose forms are kept external to the EXE in a database. Application code is C++

This allows us to modify the forms and form/actions without a re-compile. Here is a snippet of code that gets the job done of loading a form.

 RegisterClass(__classid(TButton));
 RegisterClass(__classid(TEdit));
 RegisterClass(__classid(TRadioGroup));
 RegisterClass(__classid(TGroupBox));
 RegisterClass(__classid(TCheckBox));
 RegisterClass(__classid(TRadioButton));
 RegisterClass(__classid(TTimer));
 RegisterClass(__classid(TListBox));
 RegisterClass(__classid(TComboBox));
 RegisterClass(__classid(TBitBtn));
 RegisterClass(__classid(TSpeedButton));
 RegisterClass(__classid(TMaskEdit));
 RegisterClass(__classid(TProgressBar));

 ms  = new TMemoryStream;
 ms2 = new TMemoryStream;

 // Loading Module into Memory Stream
 ms->Position = 0;
 ms->LoadFromFile(Filename->Text);
 ms->Position = 0;
 pModule = new TForm(this);

 // Reading Module Definition
 if( !Inputisbin->Checked )
 {
  ms2->Position = 0;
  ObjectTextToBinary(ms, ms2);
  ms2->Position = 0;
  ms2->ReadComponent(pModule);
 }
 else
  ms->ReadComponent(pModule);


 Log->Lines->Add("Displaying Module");
 pModule->Show();

I'm curious to know if there are any built-in functions I can call to register all classes referenced. I suppose it's possible to scan the memory stream or file for all objects myself and call RegisterClass for each but was hoping someone knew of function that already did this.

As such, not all forms use all these classes either so it would be nice to only register those that are actually inherited.

A: 

I don't know of any existing functions - it seems quite a rare thing to have to do, to me. The approach of storing form DFMs in a database (they're stored separately to the CPP and H files for the unit?) is also odd. I know you say "This allows us to modify the forms and form/actions without a re-compile" but personally I would store them in a DLL and re-compile - at least then, depending on your build system, it'll be versioned and you'll have your unit stored as a "unit". I admit I don't know your system requirements and you probably have a good reason for doing it your way.

However, given your approach I think scanning the stream, looking for object clauses and registering those components before calling ReadComponent is probably the best approach.

Storing the DFM separately (in order to just change events and action handlers) still leaves the CPP and H files compiled into your main application. From that, wouldn't you already have the components registered and built in, so this is completely unnecessary?

David M
versioning is not a problem - our home grown system handles versioning within the database where the DFM is stored. Thanks for the reply. The event handlers are not important - I wound up writing my own ORM (object relational mapper) to connect the DFM to data and events. Events are written in Perl; we embedded the Perl interpreter in our app. among others and we can always fall back to C/C++ as needed for performance critical areas.We use this "frame work" for a lot of custom software outside of the system we built it for and it has been serving us well.
Eric M
A: 

The approach you have here is exactly right, in my opinion. I took the same approach years ago using Delphi2, although I had to implement my own class factory and ObjectToText/TextToObject functions as ReadComponent() never featured in the VCL.

On your second point of only registering required classes, surely they only need registering once? And the overhead of determining if a class needs to be registered, will outweigh the cost of registering everything. Again, I would leave it as it is.

John W