如何正确地使表单或窗口控件 RecreateWnd 感知?

Posted

技术标签:

【中文标题】如何正确地使表单或窗口控件 RecreateWnd 感知?【英文标题】:How do I make form or windowed control RecreateWnd-aware properly? 【发布时间】:2014-01-27 12:08:06 【问题描述】:

如您所知,窗口控件(包括表单)的窗口句柄被认为是易失的。也就是说,设置某些属性可能会导致控件破坏其窗口句柄,然后重新创建(该技术有很多示例,搜索StdCtrls 以查找RecreateWnd)。

所以,当我需要在创建后向操作系统注册我的 HWND 并在销毁之前取消注册它时,我应该覆盖相应的方法对。简单看看ControlsForms 给了我3对,它们都是虚拟的:

创建句柄/销毁句柄 创建窗口句柄/销毁窗口句柄 CreateWnd/DestroyWnd

还有更多的配对吗?我应该为表单覆盖哪一对?哪一对用于一般的窗口控制?

【问题讨论】:

【参考方案1】:

在大多数情况下覆盖 CreateWnd()DestroyWnd()。覆盖DestroyWnd() 以进行窗口注销,如果csRecreating 标志存在于ControlState 属性中,则临时保存任何与窗口相关的数据,并调用继承的DestroyWnd()(它调用DestroyWindowHandle())来销毁HWND。覆盖CreateWnd() 以调用继承的CreateWnd()(调用CreateWindowHandle())来创建HWND,加载和丢弃之前保存的临时窗口相关数据,并进行窗口注册。

当您需要通过普通 Win32 CreateWindow/Ex()DestroyWindow() 调用以外的其他方式获取/释放 HWND 时,覆盖 CreateWindowHandle()DestroyWindowHandle()。例如,TForm 通过向其ClientHandle 窗口发送WM_MDICREATEWM_MDIDESTROY 消息来覆盖这些以创建/释放MDI 子窗口。

我从未见过 CreateHandle()DestroyHandle() 被覆盖以获取任何有用的信息。

有关详细信息,请参阅此讨论:

What's the difference between CreateWnd and CreateWindowHandle?

【讨论】:

以上是关于如何正确地使表单或窗口控件 RecreateWnd 感知?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用角度指令动态地使表单元素只读?

使用 VBA 代码有条件地使表单行的(详细信息)按钮变灰

如何禁用表单上除按钮之外的所有控件?

如何正确地使 Symfony2 应用程序的生产缓存无效?

除了按钮之外,如何禁用表单上的所有控件?

如何正确地使在线/离线 Web 应用程序的 HTML5 缓存清单失效?