17

在我的演示应用中

case WM_CLOSE:
    DestroyWindow(hndl);
    return 0;

case WM_CLOSE:
    PostQuitMessage(0);
    return 0;

照着做。每次打电话时,窗帘后面有什么不同?DestroyWindow 是否更直接,因为 PostQuitMessage 必须通过返回 false 的 getmessage 循环?

4

3 回答 3

21

DestroyWindow破坏窗口(惊喜)并将 a WM_DESTROY(您还将获得 a WM_NCDESTROY)发布到消息队列。这是 的默认行为WM_CLOSE。然而,仅仅因为一个窗口被销毁并不意味着消息循环应该结束。这可能是具有在关闭时结束应用程序的特定窗口和在关闭时对应用程序不做任何事情的其他窗口(例如,选项页面)的情况。

PostQuitMessage将 a 发布WM_QUIT到消息队列,通常会导致消息循环结束。例如,GetMessage当它拉出时将返回 0 WM_QUIT。这通常会在WM_DESTROY主窗口的处理程序中调用。这不是默认行为;你必须自己做。

于 2013-05-25T11:46:44.400 回答
17

两个片段都不正确。第一个将执行默认窗口过程在处理 WM_CLOSE 消息时已经执行的操作,因此是多余的。但不会以其他方式使应用程序退出,它应该继续运行,并且您通常必须使用 Debug + Stop Debugging 强制调试器停止。如果您在没有调试器的情况下运行它,那么您将保持进程运行但没有窗口,因此您无法判断它仍在运行。使用 Taskmgr.exe,进程选项卡查看那些僵尸进程。

第二个片段将终止应用程序,但不会正确清理,因为您没有将 WM_CLOSE 消息传递给默认窗口过程。窗户不会被破坏。尽管操作系统会为您清理,所以这一切都结束了,只是没有任何优雅的加分。

正确的方法是在主窗口被破坏时退出。您将从发生这种情况时发送的 WM_DESTROY 通知中了解它:

case WM_DESTROY:
    PostQuitMessage(0);
    return 0;
于 2013-05-25T12:04:53.703 回答
0

PostQuitMessage 并不一定意味着应用程序的结束。它只是将 WM_QUIT 发布到消息循环并允许您退出消息循环,因此在大多数情况下,这意味着应用程序的结束。但是,在多线程应用程序中,如果您为每个线程创建了消息循环,则 PostQuitMessage 只会关闭该线程。

附带说明一下,如果您需要在消息循环之后执行更多代码行(例如进一步清理),PostQuitMessage 是一种更好的方法,因为 DestroyWindow 会在不通过消息循环的情况下销毁窗口,而忽略任何消息循环后剩余的清理代码。有些人可能称其为不太好的编码实践,但有时您无法避免这样的情况。

于 2016-06-25T03:31:56.583 回答