CreateWnd和CreateWindowHandle有什么区别?

时间:2009-02-24 18:19:27

标签: delphi components

Delphi组件包含CreateWndCreateWindowHandle(以及DestroyWndDestroyWindowHandle)。它们都打算被后代覆盖,对吧?除了底层的VCL实现之外,不打算调用它?

他们之间有什么区别;应该何时覆盖其中任何一个?

4 个答案:

答案 0 :(得分:39)

到目前为止,这里的大部分答案都非常重要,你应该注意他们的建议。但是,这个故事还有一点。对于你何时会覆盖其中一个或哪一个的具体问题,我会尝试简单地解释一下。

<强>的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()完全不同的方式完成的。

我确实注意到你的问题仅仅是询问创建过程,但是在某些情况下有一些相应的方法可以覆盖句柄销毁和有时围绕处理娱乐的“伏都教”。但这些是应该单独讨论的其他主题: - )。

答案 1 :(得分:4)

CreateWnd首先调用CreateParams,然后使用创建的Params调用CreateWindowHandle。通常,您将覆盖CreateWnd和CreateParams而不是CreateWindowHandle。

我希望这有帮助!

答案 2 :(得分:2)

谁做了什么:
CreateWnd 是为WinControl创建完整窗口的总承包商 首先,它必须通过调用 CreateParams 并确保它已正确注册来为WindowClass设置所需的属性。
然后通过调用 CreateWindowHandle 来获取实际创建的窗口,该窗口从操作系统返回结果Handle。
之后,我们有一个能够处理消息的有效窗口, CreateWnd 进行最后的修饰,调整大小,字体等不同的视觉方面。

在CreateWnd完成后, CreateHandle 也会在稍后完成,以帮助VCL管理其窗口(标识,父母,...)。

答案 3 :(得分:0)

我确信最后的答案只能来自参与创建VCL的人(艾伦?),但恕我直言,应该忽略责任最小的/在呼叫链中最低的虚拟方法。这就是为什么我总是重写 CreateParams() CreateWindowHandle()。这看起来很合适,因为它们都被 CreateWnd()调用,并且两者都只做了一件特别的事。

最后,这可能是一个偏好问题。