Solved

Creating objects from a string?

Posted on 1998-03-01
14
198 Views
Last Modified: 2013-11-23
Can I create an object of a certain type, when the classtype is given to me as a string?

eg:

function CreateObject(Str: String): TObject;
begin
  Result:=ObjectFromStr.Create; // need to get the Class from the string....
end;
0
Comment
Question by:bcrotaz
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 6
  • 2
14 Comments
 
LVL 4

Expert Comment

by:itamar
ID: 1359925
Hi bcrotaz,

I think that would be a problem to the compiler to resolve smth like this in run-time.

If you have a limited universe of possible classes, the only thing I can sugest you is test the possibilities like this:

If Str = 'TLabel' Then
   Result := TLabel.Create(owner);
...

Note that in many cases you have to provide an owner and in others you don't.

Sorry if it's not the answer you were waiting for, but sometimes the right answer is: NO - you can't.

Regards,
Itamar
0
 
LVL 5

Expert Comment

by:JimBob091197
ID: 1359926
Hi

Itamar is only half right.  If the object is inherited from TPersistentClass (i.e. all Delphi components), then you can create it from a string.

As with most things, there are a few complications...

The component has to be registered with Delphi.
Let us consider an example with TListBox.

If you use a TListBox on your form, then it is already registered with Delphi.
If not, you have to register it with "RegisterClass(TListBox)".

To create it, you would then execute the following:

procedure TForm1.MakeAComp(ACompClass: string);
var
  AClass: TComponentClass;
  AComp: TComponent;
begin
  AClass := TComponentClass(GetClass(ACompClass));
  if (Assigned(AClass)) then begin
    AComp := AClass.Create(Self);
    if (AComp is TWinControl) then begin
      TWinControl(AComp).Parent := Self;
      TWinControl(AComp).Left := 100;
      TWinControl(AComp).Width := 200;
      // Etc...
    end;
  end;
end;


To call this procedure, first register all the possible components that will be dynamically created:

RegisterClasses([TListBox, TButton, TLabel, TMyThing]);

Then you can create them as & when you want:
MakeAComp('TListBox');
MakeAComp('TMyThing');

Regards,
JB
0
 
LVL 1

Author Comment

by:bcrotaz
ID: 1359927
Jimbob - can you send an answer, so I can grade you?
That's exactly the answer I wanted.
I've used ReadComponent and WriteComponent which work along similar lines, ie registering the classes first.  I just wasn't sure if you could do this.
What happens if you register the classes more than once in one process?
0
Independent Software Vendors: 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 5

Expert Comment

by:JimBob091197
ID: 1359928
Hi bcrotaz
If you want my answer, you must 1st reject itamar's.  Sorry itamar...  ;-)

It is OK to call RegisterClass more than once for a component.

Cheers,
JB
0
 
LVL 1

Author Comment

by:bcrotaz
ID: 1359929
Sorry - Jimbob was much better!
0
 
LVL 4

Expert Comment

by:itamar
ID: 1359930
Hi all,

No problem, I also learned something else from this question. Feel free to grade JimBob's answer.

Regards,
Itamar
0
 
LVL 5

Accepted Solution

by:
JimBob091197 earned 200 total points
ID: 1359931
Hi bcrotaz

This be the answer then...

Regards,
JB
0
 
LVL 1

Author Comment

by:bcrotaz
ID: 1359932
Thanks
0
 
LVL 1

Author Comment

by:bcrotaz
ID: 1359933
HELLPPPP!!!
It doesn't call the constructor of my object.
The object is descended directly from TPersistent.
I've used:

function TForm1.MakeEventObject(NameOfClass: string): TVisualEvent;
var
  TheClass: TPersistentClass;
begin
  Result:=nil;
  TheClass := GetClass(NameOfClass);
  if Assigned(TheClass) then
    Result := TVisualEvent(TheClass.Create);
end;

When I use:
Event:=TVisualEvent.Create;
it calls the TVisuaEvent constructor.

When I use:
Event:=MakeEventObject('TVisualEvent');
it doesn't call it!

Any ideas?

0
 
LVL 5

Expert Comment

by:JimBob091197
ID: 1359934
Just from looking quickly, your line in MakeEventObject may be the problem:
Result := TVisualEvent(TheClass.Create);

This is associating Create with TheClass.

Try shifting it around, e.g.
Result := TVisualEvent(TheClass).Create;

JB
0
 
LVL 1

Author Comment

by:bcrotaz
ID: 1359935
Nope....Still doesn't do it!
0
 
LVL 1

Author Comment

by:bcrotaz
ID: 1359936
Aha!

type
  TVisualEventClass = class of TVisualEvent;

...

Result:=TVisualEventClass(TheClass).Create;

This is wierd.  The VisualEvent constructor now gets called correctly, but so do descendant objects.  Now why did the constructor not get called before as a descendant of TPersistent?
0
 
LVL 5

Expert Comment

by:JimBob091197
ID: 1359937
Strange...  If you like, you can e-mail me your TVisualEvent code with some sample code of what is going wrong...
JB
0
 
LVL 5

Expert Comment

by:JimBob091197
ID: 1359938
(My last comment was based on your 2nd-last comment.)

I think that the constructor is called based on the VMT (Virtual Method Table) that comes from the class being created.  Why it works for descendants of TVisualEvent and not TPersistent is odd....
0

Featured Post

Want Experts Exchange at your fingertips?

With Experts Exchange’s latest app release, you can now experience our most recent features, updates, and the same community interface while on-the-go. Download our latest app release at the Android or Apple stores today!

Question has a verified solution.

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

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…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In this video, viewers will be given step by step instructions on adjusting mouse, pointer and cursor visibility in Microsoft Windows 10. The video seeks to educate those who are struggling with the new Windows 10 Graphical User Interface. Change Cu…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
Suggested Courses
Course of the Month5 days, 13 hours left to enroll

627 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