偶尔,应用程序需要从线程的消息循环外部检查线程的消息队列的内容。例如,如果应用程序的窗口过程执行长时间的绘图操作,您可能希望用户能够中断该操作。除非您的应用程序在鼠标和键盘消息操作期间定期检查消息队列,否则在操作完成后,它不会响应用户输入。原因是线程的消息循环中的DispatchMessage函数在窗口过程完成处理消息之前不会返回。
您可以使用PeekMessage功能在冗长的操作期间检查消息队列。PeekMessage类似于GetMessage函数;同时检查消息队列中是否存在与过滤条件匹配的消息,然后将消息复制到MSG结构。两个功能的主要区别是GetMessage直到符合过滤条件的消息被放置在队列中才返回,而PeekMessage立即返回,无论消息是否在队列中。
以下示例显示了如何使用PeekMessage在漫长的操作期间检查鼠标点击和键盘输入的消息队列。
HWND hwnd;
BOOL fDone;
MSG msg;
//开始操作并继续,直到完成
//或直到用户单击鼠标或按下一个键。
fDone = FALSE;
而(!fDone)
{
fDone = DoLengthyOperation(); //应用程序定义的函数
//删除任何可能在队列中的消息。如果
//队列包含任何鼠标或键盘
//消息,结束操作。
while(PeekMessage(& msg,hwnd,0,0,PM_REMOVE))
{
开关(msg.message)
{
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_KEYDOWN:
//
//执行任何所需的清理。
//
fDone = TRUE;
}
}
}
其他功能(包括GetQueueStatus和GetInputState)也允许您检查线程的消息队列的内容。GetQueueStatus返回一个指示队列中消息类型的标志数组;使用它是发现队列是否包含任何消息的最快方式。GetInputState如果队列包含鼠标或键盘消息,则返回TRUE。这两个功能都可用于确定队列是否包含需要处理的消息。