Delphi组件有CreateWnd
和CreateWindowHandle
(DestroyWnd
和DestroyWindowHandle
).它们都打算被后代覆盖,对吧?除了底层的VCL实现之外,不打算调用它?
它们之间有什么区别; 什么时候应该被覆盖?
到目前为止,这里的大多数答案都非常重要,你应该注意他们的建议.但是,这个故事还有一点.对于你何时会覆盖其中一个或哪一个的具体问题,我会尝试简单地解释一下.
的CreateParams();
通常,大多数情况下,您真正需要做的是覆盖CreateParams().如果你想做的只是子类(记住Windows风格"子类化?"参见Petzold关于Windows编程的开创性工作)现有的控件类并将其包装在VCL控件中,你可以从CreateParams中完成.您还可以控制设置的样式位和其他各种参数.我们创建"子类"的过程非常简单.只需从CreateParams()方法中调用CreateSubClass()即可.有关TCheckBox或TButton等示例,请参阅核心VCL控件.
CreateWnd方法();
如果在创建窗口句柄后需要对窗口句柄执行更多操作,则可以覆盖此窗口.例如,如果您的控件是某种列表,树或其他需要创建后配置的控件,那么您可以在此处执行此操作.调用继承的CreateWnd,当它返回时(如果你从CreateWnd返回,你知道你有一个有效的句柄,因为如果出现问题会引发异常),只需应用你的额外魔法.常见的情况是获取缓存在实例TStrings列表中的数据,并将其实际移动到基础窗口控件中.TListBox就是一个典型的例子.
CreateWindowHandle();
我不得不在这一个上刷新我的记忆,但似乎这是很少,如果有的话,被覆盖.在VCL本身的少数情况下,它似乎用于解决特定的Windows版本和区域设置奇怪与一些控件,如TEdit和TMemo.另一个更明确的案例是TCustomForm本身.在这种情况下,它支持旧的MDI(多文档界面)模型.在这种情况下,无法使用普通的CreateWindowEx()API创建MDI子项,您必须向MDI父帧发送消息以实际创建句柄.因此,覆盖此方法的唯一原因是,创建句柄的实际过程是通过与旧的经过验证的CreateWindowEx()完全不同的方式完成的.
我确实注意到你的问题只是询问创建过程,但是在某些情况下,有一些相应的方法被覆盖,用于处理销毁和有时围绕处理娱乐的"伏都教".但这些是应该单独讨论的其他主题:-).