DestroyWindow函数----销毁窗口的正牌函数
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
DestroyWindow函数----销毁窗⼝的正牌函数
DestroyWindow销毁窗⼝的正牌函数
DestroyWindows的MSDN说明如下:
The DestroyWindow function destroys the specified window. The function sends WM_DESTROY and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus from it. The function also destroys the window's menu, flushes the thread message queue, destroys timers, removes clipboard ownership, and breaks the clipboard viewer chain (if the window is at the top of the viewer chain).
If the specified window is a parent or owner window, DestroyWindow automatically destroys the associated child or owned windows when it destroys the parent or owner window. The function first destroys child or owned windows, and then it destroys the parent or owner window.
DestroyWindow also destroys modeless dialog boxes created by the CreateDialog function.
A thread cannot use DestroyWindow to destroy a window created by a different thread.
If the window being destroyed is a child window that does not have the WS_EX_NOPARENTNOTIFY style, a WM_PARENTNOTIFY message is sent to the parent.
DestroyWindow的处理过程总结要点如下:
1. 向⽗窗⼝发送WM_PARENTNOTIFY消息(仅当窗⼝具有WS_EX_NOPARENTNOTIFY样式);
2. 向窗⼝发送WM_DESTROY消息;
3. 使窗⼝转⼊⾮活动状态,移除键盘焦点;
4. 销毁⼦窗⼝(应该是通过递归调⽤DestroyWindow完成);
5. 销毁⽬标窗⼝资源:销毁菜单,清空线程的消息队列,销毁与窗⼝过程相关的定时器,解除窗⼝对剪贴板的拥有权,打断剪贴板器的查看链;
6. 向窗⼝发送WM_NCDESTROY消息;
上述条⽬⼤致从前往后执⾏(1、2、3的顺序不⼀定,5、6的顺序不⼀定)。
依据是:
1. 根据WM_PARENTNOTIFY说明:销毁窗⼝时,系统在任何销毁窗⼝的操作执⾏前发送WM_PARENTNOTIFY⾄⽗窗⼝;
2. 根据WM_DESTROY说明:此消息先被发送⾄⽬标窗⼝,然后发送给⽬标窗⼝的所有⼦窗⼝,处理此消息时,可以假定所有⼦窗⼝还存在着;
3. 根据DestroyWindow说明:函数先销毁⼦窗⼝及所拥有的窗⼝,然后销毁⽬标窗⼝;
4. 根据WM_NCDESTROY说明:与WM_DESTROY相反的是,此消息在所有⼦窗⼝销毁之后发送;没有去看汇编代码,只是根据各个MSDN说明来⼤致推测的,基本够⽤了吧。
根据MSDN说明,不能在⾮创建线程上调⽤DestroyWindow;若要在其它线程上关闭窗⼝,不可以直接调⽤DestroyWindow(错误"拒绝访问"),也不可以只发送WM_DESTROY,因为DestroyWindow才能完整的关闭窗⼝,WM_DESTROY消息只是关闭流程的⼀部分,甚⾄是最"⽆⽤"的⼀部分--WM_DESTROY只是⽤户响应的接⼝,⽽真正清理窗⼝的⼯作由DestroyWindow的其它部分完成。
要在其它线程上关闭窗⼝,可以向窗⼝发送WM_CLOSE消息,若窗⼝过程未在WM_CLOSE的处理中取消关闭操作,则DefWindowProc会默认调⽤DestroyWindow(彼时⾃然是在窗⼝的创建线程上)。
WM_CLOSE消息
WM_CLOSE的MSDN说明如下:
An application can prompt the user for confirmation, prior to destroying a window, by processing the WM_CLOSE message and calling the DestroyWindow function only if the user confirms the choice.
By default, the DefWindowProc function calls the DestroyWindow function to destroy the window.
WM_CLOSE消息提供取消关闭窗⼝操作的接⼝,也可以作为窗⼝关闭的关联处理的统⼀⼊⼝。
点击窗⼝右上⾓的关闭按钮将导致窗⼝收到WM_CLOSE消息,⼀般情况下,菜单中的Exit项的处理代码中也应向窗⼝发送WM_CLOSE消息,这样可以使⽆论何种⽅式触发的窗⼝关闭操作,其程序流均会流⼊WM_CLOSE消息的处理过程。
在WM_CLOSE中可以对程序状态进⾏确认,⾃动或由⽤户确认是否取消关闭操作。
与接下来的其它消息相⽐,WM_CLOSE的特殊之处在于它发⽣在销毁过程启动之前。
⽤户处理完WM_CLOSE消息后,如未取消,则DefWindowProc将调⽤DestroyWindow来关闭窗⼝,⼀旦进⼊DestroyWindow,则关闭过程将不可逆转。
WM_DESTROY消息
WM_DESTROY的MSDN说明如下:
The WM_DESTROY message is sent when a window is being destroyed. It is sent to the window procedure of the window being destroyed after the window is removed from the screen.
This message is sent first to the window being destroyed and then to the child windows (if any) as they are destroyed. During the processing of the message, it can be assumed that all child windows still exist.
A window receives this message through its WindowProc function.
If the window being destroyed is part of the clipboard viewer chain (set by calling the SetClipboardViewer function), the window must remove itself from the chain by processing the ChangeClipboardChain function before returning from the WM_DESTROY message.
最后⼀句值得注意,不过对剪贴板涉猎不多,暂且不究。
WM_PARENTNOTIFY消息
WM_PARENTNOTIFY的MSDN说明如下:
The WM_PARENTNOTIFY message is sent to the parent of a child window when the child window is created or destroyed, or when the user clicks a mouse button while the cursor is over the child window. When the child window is being created, the system sends
WM_PARENTNOTIFY just before the CreateWindow or CreateWindowEx function that creates the window returns. When the child window is being destroyed, the system sends the message before any processing to destroy the window takes place.
A window receives this message through its WindowProc function.
WM_NCDESTROY消息
WM_NCDESTROY的MSDN说明如下:
The WM_NCDESTROY message informs a window that its nonclient area is being destroyed. The DestroyWindow function sends the WM_NCDESTROY message to the window following the WM_DESTROY message. WM_DESTROY is used to free the allocated memory object associated with the window. The WM_NCDESTROY message is sent after the child windows have been destroyed. In contrast, WM_DESTROY is sent before the child windows are destroyed. A window receives this message through its WindowProc function. This message frees any memory internally allocated for the window.
关于WM_DESTROY与WM_NCDESTROY,从各种说明可以看出,⼀个⼤约充当关闭操作启动时的通知接⼝,⼀个⼤约充当关闭操作完成时的通知接⼝。
这也是我认为在DestroyWindow的处理流程中,第6条在第5条之后的原因。
另外,说明中有个值得⼀提的地⽅在于:WM_DESTROY⽤于释放关联到(associated to)窗⼝的已分配内存对象,WM_NCDESTROY⽤于释放内部为窗⼝分配的(internally allocated for)内存。
可以想象,后者应当指窗⼝的内核数据,但前者则有各种可能,菜单资源?GDI 资源?异或是⼦窗⼝资源?这个就不好说了。
⽽且,根据这两句话的表述,似乎这两个清理操作是在消息的处理过程中发⽣的,然⽽显然⼜不是由⽤户来完成的⼯作,那么就应当是在DefWindowProc中完成的了。
为什么不直接拿到Destroywindow中来执⾏呢?
ActiveX控件的销毁。