Board index » cppbuilder » creating instance by class name does not work

creating instance by class name does not work

Hi!

I want to create an instance of an VCL object whose name is given as a
string at runtime:

TControl *CreateInstanceOf(std::string ClassName);

I searched this newsgroup and found a "working" and a "good" example at

http://home.att.net/~robertdunn/CodeSamples/CodeSnips.html#Bmk011

However, I tried the Delphi version (which is titled "perfect
solution"): it doesn't compile. I messed a little bit with it (I have no
clue about Pascal whatsoever) but I couldn't make it work. I either
encountered an error in the pas file or in "pasall.tmp".

So I tried the C++ example (the "working" one): It compiles but
FindClass doesn't find anything:

TObject* CreateMetaClassObject(TMetaClass* metaClass)
{
  int objSize = TObject::InstanceSize(metaClass);
  TObject* obj = (TObject*) new char[objSize];
  TObject::InitInstance(metaClass, obj);
  return obj;

Quote
}

void __fastcall TForm1::FormClick(TObject *Sender)
{
  TObject *obj(CreateMetaClassObject(FindClass("TEdit")));
  TControl *con(dynamic_cast<TControl*>(obj));

So I added the following in the form constructor:

RegisterClass(__classid(TEdit));

Ok, compiles, but the created object seems invalid. When I try to assign
a Parent:

  if(con)
  {
    con->Parent=this;  //this is Form1

it crashes. However Left,Top,Width and Height don't throw (when I
comment out the parent line). I tried to call AfterConstruction on the
created object, but that doesn't change anything at all.

What's wrong here?

Frank

 

Re:creating instance by class name does not work


Hi!

Quote
Frank Birbacher wrote:
> I searched this newsgroup and found a "working" and a "good" example at

> http://home.att.net/~robertdunn/CodeSamples/CodeSnips.html#Bmk011

> However, I tried the Delphi version (which is titled "perfect
> solution"): it doesn't compile.

Can somebody post me the *complete* pas unit which compiles? I have now:

{**file1.pas**}
unit file1;

interface

uses Classes;

//type TClass = class of TObject;
function CreateDI(ClassRef : TClass) : TObject;

implementation

function CreateDI(ClassRef : TClass) : TObject;
{var
        FC : TComponentClass;

Quote
}

begin
        try     Result := ClassRef.Create;
        except  Result := nil;
        end;
end;
{**EOF**}

What's missing? And how do I set the Owner property?

Frank

Re:creating instance by class name does not work


Quote
"Frank Birbacher" <{*word*76}ymir.c...@gmx.net> wrote in message

news:3CF22765.A78AFBE7@gmx.net...

Quote
> Can somebody post me the *complete* pas unit which compiles?

You should be calling NewInstance() before calling Create().  Try this:

    function CreateDI(ClassRef : TClass, AOwner: TComponent) : TObject;
    var
        Instance: TObject;
    begin
        Instance := ClassRef.NewInstance;
        Result := Instance;
        try
            Instance.Create;
        except
            Result := nil;
        end;
    end;

Quote
> What's missing? And how do I set the Owner property?

The Owner is passed as a parameter to Create().  It's only used for
decendants of TComponent.

    function CreateDI(ClassRef : TComponentClass, AOwner: TComponent) :
TComponent;
    var
        Instance: TComponent;
    begin
        Instance := TComponent(ClassRef.NewInstance);
        TComponent(Result) := Instance;
        try
            Instance.Create(AOwner);
        except
            TComponent(Result) := nil;
        end;
    end;

Gambit

Re:creating instance by class name does not work


Hi!

Quote
"Remy Lebeau [TeamB]" wrote:
> The Owner is passed as a parameter to Create().  It's only used for
> decendants of TComponent.

Thanks for the hints, Remy, but I need to know the *complete*PAS*unit*,
which I just copy&paste and BC++B(!) will compile it right away. I don't
know anything about Delphi, so I cannot do it myself.

Frank

Re:creating instance by class name does not work


Just copy/paste my earlier code on top of the existing function in the
existing unit you already have.

Gambit

Quote
"Frank Birbacher" <{*word*76}ymir.c...@gmx.net> wrote in message

news:3CF35669.F6D3A806@gmx.net...
Quote
> Thanks for the hints, Remy, but I need to know the *complete*
> PAS*unit*, which I just copy&paste and BC++B(!) will compile
> it right away. I don't know anything about Delphi, so I cannot do
> it myself.

Re:creating instance by class name does not work


Hi!

Quote
"Remy Lebeau [TeamB]" wrote:
> Just copy/paste my earlier code on top of the existing function in the
> existing unit you already have.

I was trying to explain that I DID NOT HAVE A WORKING UNIT !!! So even
if I had copied your code into my not working unit it wouldn't work (I
thought)!! Now that I figured I was missing a ";" somewhere I got it to
work. But it would have been easier if you had posted one complete pas
unit (complete from "unit" to "end.") right away. I have been in the
public library today and looked into a Delphi book. From there I figured
the missing semicolon after some "begin".

I hope you see my point: I have no clue about Delphi and needed a
working (complete) example.

Your code didn't compile as it is. I need to do some changes. I compared
it to the "old function" I have made working.

finally it works as expected, thanks Remy

Frank

Other Threads