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

Agn*_*ian 7 winapi windows-messages

我以前认为WM_CREATE是窗口收到的第一条消息.但是,在顶级窗口上测试此假设时,结果却是错误的.在我的测试中,WM_MINMAXINFO显示为第一条消息.

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

gav*_*inb 15

WM_NCCREATE实际上是您的窗口将收到的第一条消息,它将在之前到达WM_CREATE.它与创建非客户区域(例如标题栏,系统菜单等)有关,因此也与NC前缀有关.

WM_GETMINMAXINFO在窗口大小/位置发生变化之前发送,并且可能在之前到达WM_CREATE(有关详细信息,请参阅下文).

WM_CREATE消息之前发送CreateWindow()的回报,这样就可以保证每个窗口初始化已经由点执行.您的窗口过程将WM_CREATE在创建窗口后但在窗口变为可见(WM_SHOWWINDOW)之前收到.

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

  • CreateWindow():WM_CREATE,WM_GETMINMAXINFOWM_NCCREATE
  • CreateWindowEx():WM_NCCREATE,WM_NCCALCSIZE,和WM_CREATE

我强烈怀疑所描述的消息顺序CreateWindow()应该是WM_NCCREATEWM_CREATE一个,而是常规的最后一个,这与通知文档和CreateWindowEx()引用一致(并且与您描述的内容一致).

Raymond Chen也有一些有关窗口创建/销毁的有趣信息.

它只是表明,即使看似简单的东西也会越复杂,你看它们就越多.

  • @gavinb,这是错误的!经过多次测试,我发现第一条消息是(为什么)WM_GETMINMAXINFO。所以正确的链是:`WM_GETMINMAXINFO -> WM_NCCREATE -> WM_CREATE` (3认同)
  • WM_NCCREATE自Windows 1.0以来一直存在.Petzold从未试图覆盖很多东西. (2认同)
  • @gavinb 不,我没有这方面的参考。我已经记录了发布到消息循环的消息。第一个发生的是 WM_GETMINMAXINFO。我多次尝试此操作,每次收到的第一条消息都是 WM_GETMINMAXINFO (0x36)。 (2认同)

小智 7

你是在自问自答.在CreateWindowEx()甚至将句柄返回到正在创建的窗口之前,我也在Windows XP SP3上看到WM_GETMINMAXINFO,然后是WM_NCCREATE,WM_NCCALCSIZE,最后是WM_CREATE.什么garabage'

一般的答案是,在有序创建和销毁对象时,Microsoft是无能的.他们弄错了Windows,COM和设备驱动程序.总有一些捕获物22,其中物体是半成品或半摧毁的,需要一些圆形的复杂解决方案才能生产出可靠的产品.


rxa*_*tos 5

实验的结果比仅仅信任源代码要好,特别是因为源代码是由大量程序员编写的,而且没有人知道所有代码。那是说:

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

我可以假设它永远是第一条消息吗?否,因为 Windows 版本之间的代码发生了变化,并且 Microsoft 尚未记录保证是第一个收到的消息。

底线:不要假设 WM_CREATE 在另一条消息之前被调用。

  • 不,实验从来都不是一个好主意。这些事情没有记录是有原因的。无法保证“WM_GETMINMAXINFO”将*始终*是发送的第一条消息,无论哪个版本的 Windows 以及用户计算机的配置。任何依赖于像这样按特定顺序接收消息的应用程序都从根本上被破坏了。该文档告诉您假设“WM_NCCREATE”是收到的第一条消息。您应该在那里完成所有初始化:无论您的应用程序在什么系统上运行,它每次都会工作。不要对 Windows 进行逆向工程。 (5认同)