Winapi Windows API:窗口保证收到的第一条消息是什么?

Winapi Windows API:窗口保证收到的第一条消息是什么?,winapi,windows-messages,Winapi,Windows Messages,我一直认为WM_CREATE是窗口收到的第一条消息。然而,当在顶级窗口上测试这个假设时,结果是错误的。在我的测试中,WM_MINMAXINFO作为第一条消息出现 那么,窗口保证收到的第一条消息是什么?WM\u NCCREATE实际上是在WM\u CREATE之前到达的消息。它与创建非客户端区域(例如标题栏、系统菜单等)相关,因此为NC前缀 WM_GETMINMAXINFO已发送,并且可能在WM_CREATE之前到达(有关更多信息,请参阅下文) WM_CREATE消息在CreateWindow()

我一直认为WM_CREATE是窗口收到的第一条消息。然而,当在顶级窗口上测试这个假设时,结果是错误的。在我的测试中,WM_MINMAXINFO作为第一条消息出现


那么,窗口保证收到的第一条消息是什么?

WM\u NCCREATE
实际上是在
WM\u CREATE
之前到达的消息。它与创建非客户端区域(例如标题栏、系统菜单等)相关,因此为
NC
前缀

WM_GETMINMAXINFO
已发送,并且可能在
WM_CREATE
之前到达(有关更多信息,请参阅下文)

WM_CREATE
消息在
CreateWindow()
返回之前发送,因此您可以保证在该点执行了每个窗口的初始化。您的窗口进程将在创建窗口之后,但在窗口可见之前(
WM\u SHOWWINDOW
)接收
WM\u CREATE

实际上,MSDN文档中存在一个有趣的不一致性-创建消息似乎取决于您是否调用或,但是它没有指定消息必须按调度顺序列出

  • CreateWindow()
    WM\u CREATE
    WM\u GETMINMAXINFO
    WM\u NCCREATE
  • CreateWindowEx()
    WM\u NCCREATE
    WM\u NCCALCSIZE
    WM\u CREATE
我强烈怀疑
CreateWindow()
中描述的消息顺序应该首先是
WM\u NCCREATE
,最后是常规的
WM\u CREATE
,这与通知文档和
CreateWindowEx()
参考一致(也与您描述的内容一致)

陈雷蒙也有一些有趣的故事


这就说明,即使看起来很简单的事情,你看得越多也会变得越复杂。

你可以使用visual studio附带的spy++来查看应用程序或窗口启动时生成的消息。

你回答了自己的问题。我也在WindowsXPSP3上看到了WM_GETMINMAXINFO,然后是WM_NCCREATE、WM_NCCALCSIZE,最后是WM_CREATE,甚至在CreateWindowEx()返回所创建窗口的句柄之前。什么是garabage


一般的答案是,微软在有序创建和销毁对象方面是无能的。他们在windows、COM和设备驱动程序上犯了错误。总是有一些“第二十二条军规”,即一个对象被半创建或半销毁,这需要一些迂回的复杂解决方案来产生可靠的产品。

实验结果比仅仅相信源代码要好,特别是因为源代码是由一群程序员组成的,没有人知道所有代码。也就是说:

我收到的第一条消息是0x24(WM_GETMINMAXINFO)

我能假设它总是第一条信息吗?不会,因为windows版本之间的代码会发生变化,而且Microsoft没有记录保证第一个收到的消息

底线:
不要认为WM_CREATE是在另一条消息之前调用的。

这个问题毫无意义。正如您所指出的,第一条消息并不总是相同的。根据创建的窗口是否可见,在CreateWindow返回之前,可能会有大量消息到达WindowPRoc。哪些消息及其顺序在windows版本之间已更改。你所能保证的就是WM_CREATE——现在是WM_NCREATE——将在CreateWindow返回之前发送(假设窗口创建成功)。Chris,为什么要用注释而不是答案?还有,这有什么意义吗?我打赌90%的Win32开发者会发誓WM_CREATE是第一个收到的消息(直到30秒前我还是其中之一)。毕竟,这是我们在课本上读到的。Serge Wautier同意,在我做一个小测试之前,我也这么想。这是我在WM_CREATE之前所有WM消息的顺序:WM_GETMINMAXINFO、WM_NCCREATE、WM_NCCALCSIZE、WM_CREATE.WM_NCCREATE自Windows 1.0以来一直存在。佩佐尔德从未试图报道过很多事情。这里有很多有用的信息,很抱歉我投了反对票。然而,WM_NCCREATE是仅针对顶级窗口的第一条消息。更正我之前的评论。WM_NCCREATE是仅针对非顶级窗口的第一条消息。抱歉,更正此错误时出现延迟。:)@加文布,那是错误的!经过几次测试,我发现第一条消息是(为什么会是)WM_GETMINMAXINFO。所以正确的链接是:
WM\u GETMINMAXINFO->WM\u NCCREATE->WM\u CREATE
@gavinb不,我没有这方面的参考。我已经记录了发布到消息循环中的消息。第一个是WM_GETMINMAXINFO。我尝试了不止一次,每次我收到的第一条消息都是WM_GETMINMAXINFO(0x36)。WM_GETMINMAXINFO是顶级窗口的第一条消息。对于其他窗口,它看起来像WM_NCCREATE.No,实验从来都不是一个好主意。这些东西没有记录是有原因的。无论Windows的哪个版本和用户机器的配置如何,都不能保证
WM_GETMINMAXINFO
始终是发送的第一条消息。任何依赖于以这样的顺序接收消息的应用程序都会从根本上崩溃。文档告诉您假定
WM\NCCREATE
是收到的第一条消息。你应该在那里完成所有的初始化:无论你的应用程序运行在什么系统上,它每次都会工作。不要对窗口进行反向工程。