Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2004-11

Creating new classes at runtime

6 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Mattias Gaertner

I don't know, if this is the right list, but the topic is quite fpc specific and needs some compiler gurus:

The Lazarus IDE needs to create new example when loading/creating a descendent of TDataModule named TMyDataModule, it needs a unique TMyDataModule = class(TDataModule) complete with vmt, method table (empty), field table (empty), typeinfo (no properties), and .. ? At the moment lazarus only supports TDataModule and TForm, so I was able to just define the two and copy. But for inheriting I need 'real' custom classes.

Creating the empty method table, field table and new typeinfo seems to be easy. But I found some fields, which I don't know:
In objpash.inc there is
    const
       vmtInstanceSize         = 0;
       vmtParent               = sizeof(ptrint)*2;

The fields behind vmtParent are easy (at least I think so). But what about the 8 bytes (i386) behind vmtInstanceSize and in front of vmtParent? They seem to be a negative number and a pointer? What are they are good for?

And: Is this solution portable or will I get into trouble?

Mattias

Reply by email

Unknown author
to Mattias Gaertner
Mattias Gaertner wrote 19 lines
I don't know, if this is the right list, but the topic is quite fpc specific and needs some compiler gurus: The Lazarus IDE needs to create new example when loading/creating a descendent of TDataModule named TMyDataModule, it needs a unique TMyDataModule = class(TDataModule) complete with vmt, method table (empty), field table (empty), typeinfo (no properties), and .. ? At the moment lazarus only supports TDataModule and TForm, so I was able to just define the two and copy. But for inheriting I need 'real' custom classes. Creating the empty method table, field table and new typeinfo seems to be easy. But I found some fields, which I don't know: In objpash.inc there is const vmtInstanceSize = 0; vmtParent = sizeof(ptrint)*2; The fields behind vmtParent are easy (at least I think so). But what about the 8 bytes (i386) behind vmtInstanceSize and in front of vmtParent? They seem to be a negative number and a pointer? What are they are good for? And: Is this solution portable or will I get into trouble?

What are you trying to do ?

As soon as you have the class, you know everything there is to know or that you need to know. You don't need to have more than the TMyClass class pointer.

In the case of TMyDatamodule, you have the TMyDataModule class pointer, so You can create an instance and 'show' that on screen ?

For forms you must only assume it is a descendant of TCustomForm.

The Delphi IDE also can only handle things that descend from TCustomForm and TDatamodule. When registering custom forms or datamodules in the IDE, you need to supply Delphi with the actual class pointer, and then it knows what to do...

If you want I can show you code that registers custom forms in the Delphi IDE, I use it .

Reply by email

Mattias Gaertner
to Unknown author
Show quoted text 25 lines
On Fri, 12 Nov 2004, Mattias Gaertner wrote: > > I don't know, if this is the right list, but the topic is quite fpc specific and needs some compiler gurus: > > The Lazarus IDE needs to create new example when loading/creating a descendent of TDataModule named TMyDataModule, > it needs a unique TMyDataModule = class(TDataModule) complete with vmt, method table (empty), field table (empty), typeinfo > (no properties), and .. ? > At the moment lazarus only supports TDataModule and TForm, so I was able to just define the two and copy. > But for inheriting I need 'real' custom classes. > > Creating the empty method table, field table and new typeinfo seems to be easy. But I found some fields, which I don't know: > In objpash.inc there is > const > vmtInstanceSize = 0; > vmtParent = sizeof(ptrint)*2; > > The fields behind vmtParent are easy (at least I think so). But what about the 8 bytes (i386) behind vmtInstanceSize and in front of vmtParent? > They seem to be a negative number and a pointer? What are they are good for? > > And: Is this solution portable or will I get into trouble? What are you trying to do ?

Well, that's a long story ...

As soon as you have the class, you know everything there is to know or that you need to know. You don't need to have more than the TMyClass class pointer.

Wow. That would be great.

In the case of TMyDatamodule, you have the TMyDataModule class pointer, so You can create an instance and 'show' that on screen ?

Where do I get this TMyDataModule class pointer?
I also want TMyDataModule1, TMyOwnDataModule, TAnotherMyDataModule, ... . The classname should be different. And I want a TMyGrandChildDataModule = class(TAnotherMyDataModule) = class(TMyDataModule) = class(TDataModule). I only have a TDataModule class pointer. The rest should be created by the IDE just from class names. But maybe I think too complicated. Fact is, I have class names and I need class pointers.

For forms you must only assume it is a descendant of TCustomForm. The Delphi IDE also can only handle things that descend from TCustomForm and TDatamodule.

That's not sufficient. I want at least TComponent.

Show quoted text 5 lines
When registering custom forms or datamodules in the IDE, you need to supply Delphi with the actual class pointer, and then it knows what to do... If you want I can show you code that registers custom forms in the Delphi IDE, I use it , please enlighten me. :)

Mattias

Reply by email

Unknown author
to Mattias Gaertner
Mattias Gaertner wrote 49 lines
On Fri, 12 Nov 2004 22:32:48 +0100 (CET) wrote: > > > On Fri, 12 Nov 2004, Mattias Gaertner wrote: > > > > > I don't know, if this is the right list, but the topic is quite fpc specific and needs some compiler gurus: > > > > The Lazarus IDE needs to create new example when loading/creating a descendent of TDataModule named TMyDataModule, > > it needs a unique TMyDataModule = class(TDataModule) complete with vmt, method table (empty), field table (empty), typeinfo > > (no properties), and .. ? > > At the moment lazarus only supports TDataModule and TForm, so I was able to just define the two and copy. > > But for inheriting I need 'real' custom classes. > > > > Creating the empty method table, field table and new typeinfo seems to be easy. But I found some fields, which I don't know: > > In objpash.inc there is > > const > > vmtInstanceSize = 0; > > vmtParent = sizeof(ptrint)*2; > > > > The fields behind vmtParent are easy (at least I think so). But what about the 8 bytes (i386) behind vmtInstanceSize and in front of vmtParent? > > They seem to be a negative number and a pointer? What are they are good for? > > > > And: Is this solution portable or will I get into trouble? > > What are you trying to do ? Well, that's a long story ... > As soon as you have the class, you know everything there is to know or that > you need to know. You don't need to have more than the TMyClass class pointer. Wow. That would be great. > In the case of TMyDatamodule, you have the TMyDataModule class pointer, so > You can create an instance and 'show' that on screen ? Where do I get this TMyDataModule class pointer? From the registration routine, of course. You must register it somewhere... I also want TMyDataModule1, TMyOwnDataModule, TAnotherMyDataModule, ... . The classname should be different. And I want a TMyGrandChildDataModule = class(TAnotherMyDataModule) = class(TMyDataModule) = class(TDataModule). I only have a TDataModule class pointer. The rest should be created by the IDE just from class names. But maybe I think too complicated. Fact is, I have class names and I need class pointers.

You must require a class pointer, there is no other way. It is no different from registering components in the IDE.

Show quoted text 8 lines
> For forms you must only assume it is a descendant of TCustomForm. > > The Delphi IDE also can only handle things that descend from TCustomForm and > TDatamodule. That's not sufficient. I want at least TComponent.

That is not practical, since you cannot 'show' a TComponent on screen ? TDataModule and TCustomform can be 'shown'. An arbitrary TComponent can only be shown as an icon on a form or datamodule. If this is your intention, then you already have it in the IDE.

How will you show e.g. TDBManager ? (just picking an arbitrary component I have at work)

Show quoted text 7 lines
> When registering custom forms or datamodules in the IDE, you > need to supply Delphi with the actual class pointer, and then it knows what > to do... > If you want I can show you code that registers custom forms in the Delphi > IDE, I use it myself at work. Yes, please enlighten me. :)

I'll send the code to you in private.

Michael.

Reply by email

Mattias Gaertner
to Unknown author
Show quoted text 56 lines
On Sat, 13 Nov 2004, Mattias Gaertner wrote: > On Fri, 12 Nov 2004 22:32:48 +0100 (CET) > wrote: > > > > > > > On Fri, 12 Nov 2004, Mattias Gaertner wrote: > > > > > > > > I don't know, if this is the right list, but the topic is quite fpc specific and needs some compiler gurus: > > > > > > The Lazarus IDE needs to create new example when loading/creating a descendent of TDataModule named TMyDataModule, > > > it needs a unique TMyDataModule = class(TDataModule) complete with vmt, method table (empty), field table (empty), typeinfo > > > (no properties), and .. ? > > > At the moment lazarus only supports TDataModule and TForm, so I was able to just define the two and copy. > > > But for inheriting I need 'real' custom classes. > > > > > > Creating the empty method table, field table and new typeinfo seems to be easy. But I found some fields, which I don't know: > > > In objpash.inc there is > > > const > > > vmtInstanceSize = 0; > > > vmtParent = sizeof(ptrint)*2; > > > > > > The fields behind vmtParent are easy (at least I think so). But what about the 8 bytes (i386) behind vmtInstanceSize and in front of vmtParent? > > > They seem to be a negative number and a pointer? What are they are good for? > > > > > > And: Is this solution portable or will I get into trouble? > > > > What are you trying to do ? > > Well, that's a long story ... > > > > As soon as you have the class, you know everything there is to know or that > > you need to know. You don't need to have more than the TMyClass class pointer. > > Wow. That would be great. > > > > In the case of TMyDatamodule, you have the TMyDataModule class pointer, so > > You can create an instance and 'show' that on screen ? > > Where do I get this TMyDataModule class pointer? >From the registration routine, of course. You must register it somewhere... > I also want TMyDataModule1, TMyOwnDataModule, TAnotherMyDataModule, ... . The classname should be different. > And I want a TMyGrandChildDataModule = class(TAnotherMyDataModule) = class(TMyDataModule) = class(TDataModule). > I only have a TDataModule class pointer. The rest should be created by the IDE just from class names. > But maybe I think too complicated. Fact is, I have class names and I need class pointers. You must require a class pointer, there is no other way. It is no different from registering components in the IDE.

A Button1 is always a TButton, but Form1 is TForm1, not just TForm.

Show quoted text 11 lines
> > For forms you must only assume it is a descendant of TCustomForm. > > > > The Delphi IDE also can only handle things that descend from TCustomForm and > > TDatamodule. > > That's not sufficient. I want at least TComponent. That is not practical, since you cannot 'show' a TComponent on screen ? TDataModule and TCustomform can be 'shown'. An arbitrary TComponent can only be shown as an icon on a form or datamodule. If this is your intention, then you already have it in the IDE.

For most parts of the IDE a TDataModule is just a non visual root TComponent. The same way I can/want to show any other custom resource TComponent as well. A resource component is here: The root component of a unit, which class is defined in the source and which is streamed by the IDE to the lrs file. At the moment this can only be a direct TDataModule descendent. But I only need this class creation and it will work for any custom component.

How will you show e.g. TDBManager ? (just picking an arbitrary component I have at work)

It can (eventually) be done the same way as a TDataModule. See above.

Show quoted text 9 lines
> > When registering custom forms or datamodules in the IDE, you > > need to supply Delphi with the actual class pointer, and then it knows what > > to do... > > If you want I can show you code that registers custom forms in the Delphi > > IDE, I use it myself at work. > > Yes, please enlighten me. :) I'll send the code to you in private.

Thanks.

Mattias

Reply by email

Mattias Gaertner
to Mattias Gaertner

Thanks to Florian I can now create any classes at runtime. ;)

The only missing piece is now renaming of a TComponent. Normally, when a TComponent is renamed TComponent.ValidateRename is called, which calls on a TCustomForm the designer. For TDataModule lazarus was using a workaround, which should not be used any longer.

How can the IDE be notified on rename and how can it stop the rename?

a) add a hook to TComponent in classes.pp
b) add a virtual method to the run time class to override ValidateRename. Sounds a little bit complicated. c) ?

Mattias

Reply by email