Solved

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

Posted on 1997-09-29
10
243 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 3

Expert Comment

by:mirek071497
Comment Utility
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
Comment Utility
Not completely what I was looking for, but good enough!  It works.  The key was RegisterClass because GetClass only works with registered classes.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 3

Expert Comment

by:mirek071497
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Thank You. No problem.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

771 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now