如何在Delphi中在运行时更改继承类的父类?

3

您好,我正在开发一个 TControl 的子类,我们称之为 THTMLBaseControl。在运行时,该控件仅基于其设置生成和输出 HTML 代码,因此基本的 TControl 类和方法,包括 Windows 消息系统,在运行时并未被使用,却会导致内存开销。

我需要该控件从 TControl 继承,以便在设计时可以使用所有 IDE 设计器工具。

但是在运行时,几乎所有那些在设计时需要的属性都不需要了。

我还将所有控件都继承自 THTMLBaseControl,因此对于每个控件类创建一个包装器类不是一个选项,因为这将大量重复代码。

所以我需要的是,在实例化类之前,在运行时更改父类,使其基于另一个类(可能名为 TmyBaseControl),该类继承自 "TComponent",就像 TControl 做的那样,但它不会有 TControl 的所有内存开销,只有 THTMLBaseControl 所需的属性和方法。

我真的没有 GUI 在 rutime 是一个仅提供 HTML 的 Web 服务器,这是 intraweb 和 Raudus 所做的事情,但问题始终是所有基于 TControl,因此必须在运行时创建并生成大量不使用的内存和处理开销。也许有一种解决方案,使在运行时实例化的任何 THTMlBaseControl 子类都将继承自 TmyBaseControl 的所有属性和方法,而不是从 TControl 继承。

我已经看到有一些方法可以破解 VMT,但也许还有其他解决方案,我还没有看到。我已经完成了更改 NewInstance、ClassParent 和 TnstanceSize 类方法,但我必须指定从哪个类开始,并且显然,我必须为每个继承的 THTMLBaseControl 类执行相同的步骤。

为了大家的利益:

这只是一个疑问,我需要组件像 TEdit、TPanel 那样成为控件,并且可以由设计 IDE 可见和可编辑。我甚至可以创建自己的 TControl 类,但我只是在想是否可以重用已经存在的代码。

谢谢


你提出的方案并不是解决问题的方法,即使可能也不行。你主要关心的是开销吗?你有多少个这个对象的实例?你知道TComponent派生类的属性会显示在设计器中吗? - David Heffernan
1
@Lightbulb,你为什么要使用TCustomControl?TCustomControl与TConrol相同,只是它有更多的东西,特别是一个窗口句柄和画布。 - Rob Kennedy
1
这真的非常错误。没有足够的细节可以说,您是否考虑过使用THTMLControlConfigComponent来进行设计时行为,然后根据其设置实例化控件? - Tony Hopkinson
@RobKennedy,抱歉。我一直以为“TControl”是源于“TCustomControl”的。但我之前从未使用过它,现在我特意去查了一下。你是正确的,“TComponent”是这里最好的选择。 - LightBulb
@David Heffernan:如果你仔细看,它说的是“我已经完成了”。我从未忽略建议,这些事情在我提出问题之前就已经完成了。我只是想知道是否还有其他方法,这是一个开放性的问题。这就是为什么我提出这个问题,寻求建议和获取知识,而不是要得到评判。对于一开始漏写东西或者不够清晰,我很抱歉,这是我在stackoverflow上的第一篇帖子,下次我会更加详细和谨慎。 - fduenas
显示剩余6条评论
1个回答

10

在运行时你不能改变一个对象所属的类。一旦实例化了一个对象,它的类就被固定了。你 可以 黑客操作该对象以更改它的VMT指针,使其引用不同的类,但这仍然无法解决你的主要问题,即内存使用情况 — 即使你改变了VMT指针,该对象的所有内存已经被分配;改变VMT指针并不能神奇地使对象占用更少的内存。

你可以做的第一件事是停止从 TControl 派生。正如你已经注意到的那样,你不需要它提供的任何东西。你只想要一些可在设计时放置并设置其属性的内容。为此,你只需要 TComponent,因此将作为基类而不是TControl。然后你会得到像 TTimer 这样没有GUI的东西。一旦这样做,你也不再需要 TForm。相反,你可以将组件放在一个 TDataModule 上,在设计时专门管理非可视组件。


谢谢,这只是一个疑问,我需要组件像TEdit、TPanel一样成为控件,并且可以被设计师IDE可见和编辑。我甚至可以创建自己的TControl类,但我在想是否可以重用已经存在的代码。祝好。 - fduenas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接