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