【发布时间】:2017-03-28 06:48:59
【问题描述】:
我读过一篇 MSDN 文章,完全糊涂了:
HWND hwnd;
BOOL fDone;
MSG msg;
// Begin the operation and continue until it is complete
// or until the user clicks the mouse or presses a key.
fDone = FALSE;
while (!fDone)
{
fDone = DoLengthyOperation(); // application-defined function
while (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE))
{
switch(msg.message)
{
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_KEYDOWN:
//
// Perform any required cleanup.
//
fDone = TRUE;
}
}
}
MSDN 使用此代码表示,我们可以在长时间操作期间检查消息队列并在鼠标单击或键盘 KeyDown 的情况下取消它。 这是怎么回事?
DoLengthyOperation 开始时直到完成才返回,此时 PeekMessage 不会调用并且无法取消操作。
msdn链接:https://msdn.microsoft.com/en-us/library/windows/desktop/ms644928
【问题讨论】:
-
假设该函数返回false一会,说明冗长的操作还没有完成。关键是将一项较长的操作分解为许多较小的操作。
-
你不能在 GUI 线程中调用
DoLengthyOperation();- 需要在单独的工作线程中调用它。直到在您的代码示例中执行DoLengthyOperation();- 您没有调用PeekMessage所以根本没有收到任何 Windows 消息并且您的 UI 被冻结 -
@HansPassant 如果函数返回 false 一段时间,在下一次调用中,函数如何从上一次调用中执行的最后一行代码继续?在下一个调用函数中再次从第一行运行
-
@RbMm if DoLengthyOperation();在另一个线程中调用,不需要以这种方式查看消息循环,DoLengthyOperation() 在同一个线程中调用。
-
只是概念代码sn-p,不是实际代码。你通常需要一个 InitializeLengthyOperation() 函数来初始化一个计数器。和一个 CancelLengthyOperation() 来清理。请记住,您不会经常编写这样的代码,尽管传统的游戏循环与此类似。包含这个 sn-p 肯定是为了提醒程序员,保持程序的 UI 线程响应用户输入是很重要的。就是这样。
标签: windows win32gui peekmessage