windows 窗口信息:WM_CREATE 和 WM_NCCREATE 的区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6289196/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Window message: Different between WM_CREATE and WM_NCCREATE?
提问by biloon
I tried to create button (child window) inside WM_NCCREATE message, and its position seemed to be created respected to screen coordinates, rather than client coordinates. At first, I thought WM_CREATE and WM_NCCREATE provide us the same handle to window, but this seem to be untrue. Therefore, can anyone explain me the differences between WM_CREATE and WM_NCCREATE messages? Also what are the differences between handle to window in WM_CREATE and in WM_NCCREATE?
我试图在 WM_NCCREATE 消息中创建按钮(子窗口),它的位置似乎是根据屏幕坐标而不是客户端坐标创建的。起初,我认为 WM_CREATE 和 WM_NCCREATE 为我们提供了相同的窗口句柄,但这似乎是不正确的。因此,谁能解释一下 WM_CREATE 和 WM_NCCREATE 消息之间的区别?另外,WM_CREATE 和 WM_NCCREATE 中的窗口句柄有什么区别?
采纳答案by Tony The Lion
Per MSDN:
根据 MSDN:
WM_NCCREATE:
WM_NCCREATE:
Sent prior to the WM_CREATE message when a window is first created.
首次创建窗口时,在 WM_CREATE 消息之前发送。
Return Value:
返回值:
If an application processes this message, it should return TRUE to continue creation of the window. If the application returns FALSE, the CreateWindow or CreateWindowEx function will return a NULL handle.
如果应用程序处理此消息,它应返回 TRUE 以继续创建窗口。如果应用程序返回 FALSE,则 CreateWindow 或 CreateWindowEx 函数将返回一个 NULL 句柄。
WM_CREATE:
WM_CREATE:
Sent when an application requests that a window be created by calling the CreateWindowEx or CreateWindow function. (The message is sent before the function returns.) The window procedure of the new window receives this message after the window is created, but before the window becomes visible.
当应用程序通过调用 CreateWindowEx 或 CreateWindow 函数请求创建窗口时发送。(消息在函数返回之前发送。)新窗口的窗口过程在窗口创建之后,但在窗口变为可见之前收到此消息。
Return Value:
返回值:
If an application processes this message, it should return zero to continue creation of the window. If the application returns –1, the window is destroyed and the CreateWindowEx or CreateWindow function returns a NULL handle.
如果应用程序处理此消息,它应该返回零以继续创建窗口。如果应用程序返回 –1,则窗口被销毁并且 CreateWindowEx 或 CreateWindow 函数返回一个 NULL 句柄。
回答by David Heffernan
The WM_NC messages are for the non-client area, i.e. the window border and caption. For your needs you are not interested in these non-client messages.
WM_NC 消息用于非客户区,即窗口边框和标题。根据您的需要,您对这些非客户端消息不感兴趣。
回答by Chris Becke
WM_NCCREATE is an example of an arms race in progress. It seems to have been introduced to serve a need where DefWindowProc (or the base window proc of a commonly subclassed window) needed to perform some initialization perhaps before WM_CREATE was processed (or to make up for the fact that many window implementations handle WM_CREATE directly and return TRUE rather than passing it on to DefWindowProc).
WM_NCCREATE 是正在进行的军备竞赛的一个例子。它似乎是为了满足 DefWindowProc(或通常子类窗口的基本窗口过程)需要在处理 WM_CREATE 之前执行一些初始化的需要(或为了弥补许多窗口实现直接处理 WM_CREATE 和返回 TRUE 而不是将其传递给 DefWindowProc)。
WM_NCCREATE therefore is the message you should respond to if you are implementing a default window procedure, that needs to perform initialization before the users window proc handles the WM_CREATE message. WM_NCCREATE also MUST be passed on to the appropriate DefWindowProc, probably before you do your own processing as some lower level aspects of the window are clearly in an uninitialized state before WM_NCCREATE is processed.
因此,WM_NCCREATE 是您在实现默认窗口过程时应该响应的消息,该过程需要在用户窗口过程处理 WM_CREATE 消息之前执行初始化。WM_NCCREATE 也必须传递给适当的 DefWindowProc,可能在您进行自己的处理之前,因为在处理 WM_NCCREATE 之前,窗口的某些较低级别的方面显然处于未初始化状态。
If trying to guarantee first-look processing is NOT your consideration, then WM_CREATE is the appropriate place to perform your window initialization: All other layers that might have jist-in-time setup via WM_NCCREATE have been done, and the window is in a stable state wrt things like its non client metrics, screen position etc.
如果尝试保证优先处理不是您的考虑因素,那么 WM_CREATE 是执行窗口初始化的合适位置:所有其他可能通过 WM_NCCREATE 进行即时设置的层都已完成,并且窗口处于稳定状态陈述诸如非客户端指标、屏幕位置等内容。
Or: If you don't know why you should use WM_NCCREATE over WM_CREATE, then you should not be using WM_NCCREATE.
或者:如果您不知道为什么应该使用 WM_NCCREATE 而不是 WM_CREATE,那么您不应该使用 WM_NCCREATE。
回答by wantTheBest
Not sure why you're creating a button in the WM_NCCREATE -- because the window onto which the button will appear doesn't exist yet, hence (I believe) the destop coords. WM_NCCREATE gets sent to you when the 'non-client' areas of the window are about to be created (non-client areas such as the window's border, title bar, etc.)
不知道为什么要在 WM_NCCREATE 中创建按钮——因为按钮将出现的窗口尚不存在,因此(我相信)停止坐标。WM_NCCREATE 在窗口的“非客户”区域即将创建时发送给您(非客户区域,例如窗口的边框、标题栏等)
Are you needing to put a button on the non-client area? If the answer is no, then why not do the button create inside WM_CREATE.
你需要在非客户区放一个按钮吗?如果答案是否定的,那么为什么不在 WM_CREATE 中创建按钮。
If you have to create the button for some reason inside WM_NCCREATE, then why not store the window handle returned by your Createwindow() call. Then, inside your WM_CREATE message handler, grab that button's window handle and do a 'MoveWindow(...)' on it using the app window which you should now have coordinates to when you're in the WM_CREATE message handler.
如果出于某种原因必须在 WM_NCCREATE 中创建按钮,那么为什么不存储由 Createwindow() 调用返回的窗口句柄。然后,在您的 WM_CREATE 消息处理程序中,获取该按钮的窗口句柄并使用应用程序窗口对其执行“MoveWindow(...)”,您现在应该拥有在 WM_CREATE 消息处理程序中时的坐标。
I believe one of the parameters you can pass to your CreateWindow(...) call to create the button allows you to specify an 'SW_...' flag, such as 'SW_HIDE' if memory serves me correct. So create but don't show the button in WM_NCCREATE handling if you must, then when WM_CREATE comes quickly afterward, do a 'MoveWindow(....window coords,......SW_SHOW,......) etc. to position and make visible the button.
我相信您可以传递给 CreateWindow(...) 调用以创建按钮的参数之一允许您指定“SW_...”标志,例如“SW_HIDE”,如果我没记错的话。因此,如果必须,创建但不要在 WM_NCCREATE 处理中显示按钮,然后当 WM_CREATE 之后快速出现时,执行 'MoveWindow(....window coords,......SW_SHOW,......)等定位按钮并使按钮可见。