窗口消息:WM_CREATE和WM_NCCREATE之间有什么不同?

时间:2011-06-09 07:02:15

标签: c++ windows

我尝试在WM_NCCREATE消息中创建按钮(子窗口),并且它的位置似乎被创建为尊重屏幕坐标,而不是客户端坐标。起初,我认为WM_CREATE和WM_NCCREATE为我们提供了与窗口相同的句柄,但这似乎是不真实的。因此,任何人都可以解释WM_CREATE和WM_NCCREATE消息之间的区别吗?另外WM_CREATE和WM_NCCREATE中窗口句柄的区别是什么?

5 个答案:

答案 0 :(得分:11)

WM_NC消息用于非客户区域,即窗口边框和标题。根据您的需求,您对这些非客户端消息不感兴趣。

答案 1 :(得分:10)

WM_NCCREATE是正在进行的军备竞赛的一个例子。它似乎已被引入以满足需求,其中DefWindowProc(或通用子类窗口的基本窗口proc)需要在处理WM_CREATE之前执行某些初始化(或者弥补许多窗口实现直接处理WM_CREATE的事实)返回TRUE而不是将其传递给DefWindowProc。

WM_NCCREATE因此是您应该响应的消息,如果您正在实现默认窗口过程,需要在用户窗口proc处理WM_CREATE消息之前执行初始化。 WM_NCCREATE也必须传递给相应的DefWindowProc,可能在你自己进行处理之前,因为在处理WM_NCCREATE之前,窗口的某些低级方面显然处于未初始化状态。

如果尝试保证第一次处理不是您的考虑因素,那么WM_CREATE是执行窗口初始化的合适位置:所有其他可能通过WM_NCCREATE进行实时设置的图层已经完成,窗口是处于稳定状态,例如非客户指标,屏幕位置等。

或者:如果您不知道为什么要使用WM_NCCREATE而不是WM_CREATE,那么您不应该使用WM_NCCREATE。

答案 2 :(得分:5)

每个MSDN:

WM_NCCREATE:

  

在WM_CREATE消息之前发送   首次创建窗口时。

返回值

  

如果应用程序处理此问题   消息,它应该返回TRUE   继续创建窗口。如果   应用程序返回FALSE,即   CreateWindow或CreateWindowEx   函数将返回一个NULL句柄。

WM_CREATE:

  

应用程序请求时发送   通过调用创建一个窗口   CreateWindowEx或CreateWindow   功能。 (之前发送消息   函数返回。)窗口   新窗口的程序收到   窗口后面的这条消息是   创建,但在窗口成为之前   可见。

返回值

  

如果应用程序处理此问题   消息,它应该返回零   继续创建窗口。如果   应用程序返回-1,即窗口   被销毁和CreateWindowEx或   CreateWindow函数返回NULL   处理

答案 3 :(得分:0)

此设备上下文除了客户端外还包括窗口标题栏,菜单,滚动条和框架 区。应用程序很少使用GetWindowDC函数。如果您想尝试一下 您还应该捕获WM_NCPAINT(“非客户绘画”)消息,该消息是Windows 用于绘制窗口的非客户区域。

来自:《 Programming Windows Fifth Edition》 -Charles Petzold

因此,尽管MSDN没有说出来,但我认为它是可信的。

答案 4 :(得分:-1)

不确定为什么要在WM_NCCREATE中创建一个按钮 - 因为按钮出现的窗口尚不存在,因此(我相信)destop coords。当即将创建窗口的“非客户”区域时,WM_NCCREATE会发送给您(非客户区域,例如窗口的边框,标题栏等)

您是否需要在非客户区域设置按钮?如果答案是否定的,那么为什么不在里面创建按钮 WM_CREATE。

如果由于某种原因必须在WM_NCCREATE内创建按钮,那么为什么不存储Createwindow()调用返回的窗口句柄。然后,在WM_CREATE消息处理程序中,抓住该按钮的窗口句柄,并使用应用程序窗口对其执行“MoveWindow(...)”,当您处于WM_CREATE消息处理程序中时,该窗口应该具有坐标。

我相信您可以传递给CreateWindow(...)调用以创建按钮的参数之一允许您指定'SW _...' 标志,例如'SW_HIDE',如果内存让我正确的话。所以如果你必须创建但不要在WM_NCCREATE处理中显示按钮,那么当WM_CREATE快速到来之后,做一个'MoveWindow(.... window coords,...... SW_SHOW,......)等等 定位并使按钮可见。