Solved

Chaning Class Type on the fly, can Delphi do this?

Posted on 1997-09-29
10
247 Views
Last Modified: 2010-04-04
I have a bunch of forms say of type dlgForm1, dlgForm2, dlgForm3. They all have an init function in them that I need to call.  I have a database table that I store the name of the dialog to create (if the user selects a certain option, I search thru the table and find the correct dialog to create).  Anyway, is there a way to pick the type of dialog that I want to create at run time.  The normal way to do this is like:

procedure CreateDialog(sDialogClassName: string; iInitParmam: integer);
var
  dlgForm1: TdlgForm1;
  dlgForm2: TdlgForm2;
  dlgForm3: TdlgForm3;
begin
  if sDialogClassName = 'dlgForm1' then
  with dlgForm1.Create(Application) do
  begin
    Init(iInitParam);
    ShowModal;
    Free;
  end;
  if sDialogClassName = 'dlgForm2' then
  with dlgForm2.Create(Application) do
  begin
    Init(iInitParam);
    ShowModal;
    Free;
  end;
  if sDialogClassName = 'dlgForm3' then
  with dlgForm3.Create(Application) do
  begin
    Init(iInitParam);
    ShowModal;
    Free;
  end;
end;

Now since I have about 30 forms like this it would obviously be nice if I didn't have to write the same code over and over again.  Is there a way  do do something like this the following?

procedure CreateDialog(sDialogClassName: string; iInitParmam: integer);
var
   ClassType: TPersistentClass;
begin
  ClassType:= GetClass(sDialogClassName);
  with Application.CreateForm(ClassType, dlgForm) do
  begin
    Init(iInitParam);
    ShowModal;
    Free;
  end;
end;

The above assumes that every form has a global variable called Form.  The code above does not work.  Why doesn't it and is there a way to do something like this?
If there is a way to do this it would be nice to get rid of the global variable as well (I hate globals).  Any ideas there?

Thanks for any help.
0
Comment
Question by:pswenson
  • 5
  • 4
10 Comments
 
LVL 3

Expert Comment

by:mirek071497
ID: 1346475
I must try this but you have some errors.

1. Application.CreateForm is a procedure not function. You must Use this as

Application.CreateForm(ClassType, dlgForm);
With dlgForm ..... etc.

2.ClassType : TFormClass;
  ClassType := TFormClas( GetClass .... etc )

When I have working example then i post this here.
0
 
LVL 1

Accepted Solution

by:
miv earned 200 total points
ID: 1346476
let all your forms descend from the same TMyForm which has a init procedure.
....
ps. This is not the perfect solution, but it´s somewhat shorter than your own code...


CreateDialog(sDialogClassName: string; iInitParmam: integer);

 var
  AForm: TMyForm;
 begin
   if sDialogClassName = 'dlgForm1' then      AForm:=TMyForm1.Create(Application);
   if sDialogClassName = 'dlgForm2' then           AForm:=TMyForm2.Create(Application);

   AForm.Init(iInitParam);
   AForm.ShowModal;
   AForm.Free;
 end;
0
 

Author Comment

by:pswenson
ID: 1346477
Miv, that's not really what I was looking for.  It is better than the code I posted but I still need an if then for each form.  It may not be possible to do what I want with changing the class on the fly. If it is not possible then your solution is the best (I knew I could do that, someone else wrote the code and I was just looking to clean it up)
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 3

Expert Comment

by:mirek071497
ID: 1346478
Hi this works ! but remember that you must RegisterClasses and In ProjectManager delete forms from AutoCreate.

I write simple example which fork Fine.

I Create Unit1 with form1 and Unit2 with form2 and then :

if Unit2 i write RegisterClass for Form 2 :

initialization
  RegisterClass( TForm2 );
end.

and in Unit1 i create button with this event :

procedure TForm1.BitBtn1Click(Sender: TObject);
var ClassType: TFormClass;
begin
  ClassType:= TFormClass( GetClass( 'TForm2' ) );
  Application.CreateForm( ClassType, Form2 );
  With Form2 do
  begin
    ShowModal;
    Free;
  end;
end;


All works as i write later. Is this What you need ?
0
 

Author Comment

by:pswenson
ID: 1346479
Not completely what I was looking for, but good enough!  It works.  The key was RegisterClass because GetClass only works with registered classes.
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1346480
I think so i give you good answer and you accept miv why ?
How this can be "Not completely what I was looking for" this is strict translation of your question but corrected to working example.

bad boy.
0
 

Author Comment

by:pswenson
ID: 1346481
Gimme a break, mirek.  The key to my question was choosing the class on the fly from a string containing the classname and creating the correct form.  You didn't tell me anything I didn't know.  With your method you still had to have an <if then> for each type of form.  With mirek's you only have 1 case to take care of.   This is real nice when you have 30 forms.

The code ends up like:

procedure CustomCreateForm(sFormType: stirng);
var
  ClassType: TFormClass;
  BaseForm: TBaseFormType;
begin
  ClassType:= TFormClass( GetClass( sFormType ) );
  Application.CreateForm( ClassType, BaseForm );
  With BaseForm do
  begin
    Init;
    ShowModal;
    Free;
  end;
end;

As long as all the form types are registered with RegisterClass you can create any form you want.
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1346482
Hi
Your code is based on my answer - is this true ?
You can't do this later and you can do this after my answer - this is true ?
So who help you ?

p.s. My englisgh is poor so please tell this in easy words (i can't understand) - "Gimme a break, mirek"
0
 

Author Comment

by:pswenson
ID: 1346483
Oops!  I meant to accept Mirek's answer not Miv's.  I guess I got  you guys mixed up by the similarity of the names or something.

Sorry.
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1346484
Thank You. No problem.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

679 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question