在我的示范应用中
case WM_CLOSE:
DestroyWindow(hndl);
return 0;
和
case WM_CLOSE:
PostQuitMessage(0);
return 0;
执行相同的操作。当调用它们时,幕后有何不同之处?是DestroyWindow更直接,而PostQuitMessage必须通过getmessage循环返回false吗?
DestroyWindow
函数销毁窗口并在消息队列中发送WM_DESTROY
(同时也会收到一个 WM_NCDESTROY
)。这是WM_CLOSE
的默认行为。但是,仅仅因为一个窗口被销毁了并不意味着消息循环应该结束。例如,在关闭特定窗口时结束应用程序而在关闭其他窗口时不影响应用程序(例如选项页面)。
PostQuitMessage
函数向消息队列中发布WM_QUIT
,通常会导致消息循环结束。例如,当获取到WM_QUIT
时,GetMessage
函数将返回0。通常在主窗口的WM_DESTROY
处理程序中调用此函数。这不是默认行为,您需要自己执行。
两种代码片段都不正确。第一个片段将执行默认窗口过程在处理WM_CLOSE消息时所做的操作,因此是多余的。但它并不会使应用程序退出,应该继续运行,通常需要使用Debug + Stop Debugging强制停止调试器。如果你没有使用调试器运行它,那么进程将继续运行,但没有窗口,因此无法判断它是否仍在运行。使用任务管理器(Taskmgr.exe),进程选项卡可以查看这些僵尸进程。
第二个代码片段将终止应用程序,但由于没有将WM_CLOSE消息传递给默认窗口过程,因此不会正确清理。窗口不会被销毁,尽管操作系统会为您清理,但没有任何优雅的加分点。
正确的方法是在主窗口被销毁时退出。当发生这种情况时,您将收到发送的WM_DESTROY通知:
case WM_DESTROY:
PostQuitMessage(0);
return 0;
PostQuitMessage并不一定意味着应用程序的结束。它只是将WM_QUIT发布到消息循环并允许您退出消息循环,因此在大多数情况下,这意味着应用程序的结束。但是,在多线程应用程序中,如果为每个线程创建了消息循环,则PostQuitMessage仅关闭该线程。
作为副笔,如果您需要在消息循环之后执行更多行代码(例如进一步的清理),那么PostQuitMessage是更好的选择,因为DestroyWindow会在不经过消息循环的情况下销毁窗口,并忽略消息循环后剩余的任何清除代码。有些人可能认为这不是很好的编码实践,但有时您无法避免这种情况。
DestroyWindow
销毁一个窗口。PostQuitMessage
会发布一个退出消息:即它表明整个应用程序想要退出。 - jalf