我一直认为 WM_CREATE 是窗口收到的第一条消息。然而,在顶层窗口上测试这个假设时,结果证明是错误的。在我的测试中,WM_MINMAXINFO 作为第一条消息出现。
那么,一个窗口保证接收的第一条消息是什么?
我一直认为 WM_CREATE 是窗口收到的第一条消息。然而,在顶层窗口上测试这个假设时,结果证明是错误的。在我的测试中,WM_MINMAXINFO 作为第一条消息出现。
那么,一个窗口保证接收的第一条消息是什么?
WM_NCCREATE
实际上是您的窗口将收到的第一条消息,它会在之前到达WM_CREATE
。它与创建非客户区(例如标题栏、系统菜单等)有关,因此是NC
前缀。
WM_GETMINMAXINFO
在窗口大小/位置改变之前发送,并且可能在之前到达WM_CREATE
(更多信息见下文)。
WM_CREATE
消息在返回之前发送,CreateWindow()
因此您可以保证每个窗口的初始化已在该点执行。您的窗口 proc 将WM_CREATE
在窗口创建后但在窗口变为可见之前(WM_SHOWWINDOW
)接收。
实际上,MSDN 文档中有一个有趣的不一致之处——创建消息似乎取决于您是否调用CreateWindow()
或CreateWindowEx()
,但它并未指定消息必须按调度顺序列出。
CreateWindow()
:和WM_CREATE
_WM_GETMINMAXINFO
WM_NCCREATE
CreateWindowEx()
: WM_NCCREATE
,WM_NCCALCSIZE
和WM_CREATE
我强烈怀疑中描述的消息顺序CreateWindow()
应该有WM_NCCREATE
第一个,常规的WM_CREATE
最后一个,这与通知文档和CreateWindowEx()
参考一致(也与您描述的一致)。
Raymond Chen 也有一些关于窗口创建/销毁的有趣信息。
它只是表明,即使是看似简单的事情,你越看越复杂。
你是在自问自答。我也在 Windows XP SP3 上看到 WM_GETMINMAXINFO,然后是 WM_NCCREATE、WM_NCCALCSIZE,最后是 WM_CREATE,然后 CreateWindowEx() 甚至还返回了正在创建的窗口的句柄。什么垃圾'
一般的答案是微软在有序地创建和销毁对象方面是无能的。他们在 windows、COM 和设备驱动程序上都搞错了。总是有一些 catch-22 对象是半创建或半破坏的,这需要一些迂回复杂的解决方案来生产可靠的产品。
通过实验得出的结果比仅仅相信源代码要好,尤其是因为源代码是由大量程序员组成的,而且没有人知道所有的代码。那说:
我收到的第一条消息是 0x24 (WM_GETMINMAXINFO)。
我可以假设它永远是第一条消息吗?不,因为 Windows 版本之间的代码更改,并且 Microsoft 没有记录保证是第一个收到的消息。
底线:不要假设 WM_CREATE 在另一条消息之前被调用。
您可以使用 Visual Studio 附带的 spy++ 来查看启动应用程序或窗口时生成的消息。