WinMain中没有消息循环是否可取?

时间:2009-06-01 20:46:24

标签: winapi

这可能是有史以来最简单的win32计划..

#include <windows.h>

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR cmdLine, int show)
{
    MessageBox(0, "Hello world..", "Salutations!", MB_OK);
    return 0;
}

..它不会对通常的GetMessage()调用进行任何调用。我的问题是:如果我的程序没有处理任何窗口消息,操作系统可以应对吗?即,它是否会导致内存泄漏?或者其他一些不明显的资源,除非我运行16K次?

从更广泛的意义上说,Win32对于处理邮件的应用程序究竟是如何“依赖”的?我希望当编译器将可执行文件链接为一个Windows程序时,运行时将能够清理任何类型的消息队列,无论是否清空。

6 个答案:

答案 0 :(得分:11)

只是技术性,但你确实有一个窗口,你确实有一个消息循环,而不是你的代码。

MessageBox()的调用会创建一个窗口(类#32770)并运行本地消息循环,在消息循环消失之前不会返回到您的代码,可能是在发送WM_NCDESTROY时。我认为这是响应DialogBox()而运行的相同消息循环。

但你可以用{em>不创建消息循环的任何其他内容替换你的MessageBox()来电,你仍然可以。 Windows并不关心你是否有消息循环,尽管有一些功能(主要是UI相关)很难或不可能没有它。实际上,您根本不必链接到user32,而某些没有用户界面的应用则不需要。

现在,如果您创建一个窗口并且不以某种方式为其处理消息,Windows XP及更高版本将使用具有白色客户端区域和任务的“ghost”窗口替换您的窗口管理员会告诉用户应用程序没有响应。

虽然起初看起来似乎如此,但消息循环并不是魔术或Windows样板的严格要求部分。但 在大多数Windows应用程序中作为标准高度根深蒂固,因为它是处理窗口消息调度的最佳方式。大多数Windows应用程序的“事件驱动”特性使我们有时忘记Windows应用程序最初被设计为单线程,并且在这个模型中,它是在单个线程内运行的代码,而不是操作系统中的一些看不见的力量,必须在我们的代码中调用每个函数。多线程的添加有所改变,但基本模型仍然保持不变。

修改

关于邮件队列的说明:

如其他地方所述,只有在该线程创建窗口时才会创建消息队列(并且基于每个线程)。您的示例程序在创建消息框时, 创建消息队列。但是当您的应用程序退出时,此队列不必为空。这个队列只是一个内存结构。它是一个可以容纳一定数量的消息对象的内存块(指定目标hWnd,消息ID,wParam,lParam,发布消息时的系统时间,发布消息时的鼠标位置,以及允许派生键盘的一些数据)消息发布时的鼠标按钮状态,以及指向队列头部和尾部的指针(我假设它是一个循环队列)。当应用程序退出时,该内存与属于该进程的所有内存一样,将被即时释放。

当然,在您的流程之外还有其他必须清理的事情。操作系统必须保留所有现有窗口的表格,例如,创建它们的线程和进程。当然,这些都是自动清理的。

答案 1 :(得分:4)

由于您没有窗口,因此不需要消息循环。在Win32中,消息被发送到窗口,而不是应用程序。

答案 2 :(得分:3)

你有一个消息循环 - MessageBox是一个模态对话框,因此包含一个消息循环。

答案 3 :(得分:2)

您不必创建窗口。但是,仍有某种消息,比如

  • WM_TIMER
  • WM_TIMECHANGE
  • WM_CLIPBOARDUPDATE
  • WM_COPYDATA
  • WM_POWER
你可能需要的。所以,一个 ghost 窗口闲逛并不坏。

答案 4 :(得分:1)

如果你没有窗口,那就没问题,但是如果你这样做,那么你需要确保为它抽取信息。否则,系统可以挂起等待您响应的广播消息。这对于像COM那样为消息处理创建隐藏窗口的东西很重要。如果您的主线程没有抽取消息(例如,通过调用WaitForSingleObject),则不会处理对COM对象的调用,并且任何发送广播的程序都将显示为挂起。

答案 5 :(得分:0)

我在某处读过(并且找不到引用)是Windows将按需创建消息队列。如果您从未调用查找消息队列的函数,则永远不会创建消息队列。这是在每个线程的基础上发生的。