Message Loop

【勇芳软件工作室】汉化HomePreviousNext

一个简单的消息循环包括对这三个函数中的每一个的一个函数调用:GetMessageTranslateMessageDispatchMessage.

MSG msg;

while(GetMessage(& msg,NULL,0,0))

{

TranslateMessage( &msg );

DispatchMessage( &msg );

}

GetMessage函数从队列中检索一条消息,并将其复制到类型为MSG的结构。它返回TRUE,除非它遇到WM_QUIT消息,在这种情况下它返回FALSE并结束循环。在单线程应用程序中,结束消息循环通常是关闭应用程序的第一步。应用程序可以使用PostQuitMessage函数来结束自己的循环,通常在应用程序主窗口的窗口过程中响应WM_DESTROY消息。

如果您将窗口句柄指定为第二个参数GetMessage,则仅从队列中检索指定窗口的消息。GetMessage也可以过滤队列中的消息,仅检索那些落在指定范围内的消息。有关过滤邮件的更多信息,请参阅邮件过滤.

线程的消息循环必须包含TranslateMessage如果线程要从键盘接收字符输入。每次用户按下密钥时,Windows会生成虚拟密钥消息(WM_KEYDOWNWM_KEYUP)。虚拟键消息包含一个虚拟键代码,用于标识按下哪个键,而不是其字符值。要检索此值,消息循环必须包含TranslateMessage,它将虚拟键消息转换为字符消息(WM_CHAR),并将其放回到应用程序消息队列中。然后可以在消息循环的后续迭代中删除字符消息,并将其分派到窗口过程。

DispatchMessage函数向与MSG结构中指定的窗口句柄相关联的窗口过程发送一条消息。如果窗口句柄是HWND_TOPMOST,DispatchMessage将消息发送到系统中所有顶级窗口的窗口过程。如果窗口句柄为NULL,则DispatchMessage对该消息不执行任何操作。

应用程序的主线程在初始化应用程序并创建至少一个窗口之后启动其消息循环。一旦启动,消息循环将继续从线程的消息队列中检索消息,并将其发送到相应的窗口。当GetMessage功能从消息队列中删除WM_QUIT消息时,消息循环结束。

消息队列只需要一个消息循环,即使应用程序包含许多窗口。DispatchMessage总是将消息发送到正确的窗口;这是因为队列中的每个消息都是包含消息所属窗口的句柄的MSG结构。

您可以通过各种方式修改消息循环。例如,您可以从队列中检索邮件而不将其分派到窗口。这对于发布不指定窗口的消息的应用程序很有用。您还可以指示GetMessage搜索特定邮件,将其他邮件留在队列中。如果您必须临时绕过消息队列的通常FIFO顺序,这将非常有用。

使用加速键的应用程序必须能够将键盘消息转换为命令消息。为此,应用程序的消息循环必须包含对TranslateAccelerator函数的调用。有关加速键的更多信息,请参阅键盘加速器.

如果线程使用无模式对话框,则消息循环必须包含IsDialogMessage函数,以便对话框可以接收键盘输入。