在一个 Windows 窗口被销毁的时候,你会发现有两个比较类似的消息:WM_DESTROY和WM_NCDESTROY,那么,这俩兄弟之间有什么区别呢?今天就来讲讲。
不同之处在于,WM_DESTROY消息在窗口销毁序列的开头发送,而WM_NCDESTROY消息在结束时发送。当你有子窗口时,这会是一个重要的区别。如果你有一个带有子窗口的父窗口,那么消息流程(在没有奇怪的事情发生的情况下)将如下所示:
hwnd = parent, uMsg = WM_DESTROY
hwnd = child, uMsg = WM_DESTROY
hwnd = child, uMsg = WM_NCDESTROY
hwnd = parent, uMsg = WM_NCDESTROY
请注意,父窗口在销毁子窗口之前接收 WM_DESTROY,在子窗口销毁后接收 WM_NCDESTROY 消息。
有两个销毁消息,一个是自上而下的,另一个是自下而上的,这意味着在处理相应的消息时,可以执行适合特定模型的清理过程。例如,如果某些内容必须自上而下清理,则可以使用 WM_DESTROY 消息。
WM_NCDESTROY 是窗口将收到的最后一条消息(在没有奇怪的事情发生的情况下),因此它是进行 “最终清理” 的最佳位置。这就是为什么我们的例子程序要等到 WM_NCDESTROY才能销毁其实例变量。
这两个销毁消息与类似的 WM_CREATE 和 WM_NCCREATE 消息配对。正如 WM_NCDESTROY 是窗口接收的最后一条消息一样,WM_NCCREATE 条消息是第一条消息,因此这是创建实例变量的好地方。另请注意,如果 WM_NCCREATE 消息返回失败,那么你将得到的只是WM_NCDESTROY,而不会有 WM_DESTROY,因为你从未获得相应的 WM_CREATE 。
我一直提到的这种 “没有奇怪的事情发生的情况” 到底是指什么?
我们在下一篇文章中再具体说说。
总结
牢记一条:创建窗口的第一条消息:WM_NCCREATE,销毁窗口后的最后一条消息:WM_NCDESTROY。
是的,完美的东西都是这样简单而对称的。
最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《What is the difference between WM_DESTROY and WM_NCDESTROY?》