0

我读过一篇 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 说使用此代码,我们可以在长时间操作期间检查消息队列并在鼠标单击或键盘按键按下的情况下取消它。这是怎么回事?

当 DoLengthyOperation 开始时直到它完成才会返回,并且 PeekMessage 不会在这个时候调用并且不能取消操作。

msdn 链接:https ://msdn.microsoft.com/en-us/library/windows/desktop/ms644928

4

1 回答 1

0

要执行您的要求,您需要从内部查看消息队列DoLengthyOperation(),例如:

BOOL fDone = FALSE; 
do
{ 
    fDone = DoLengthyOperation();
} 
while (!fDone);

...

BOOL DoLengthyOperation()
{
    MSG msg; 

    ...

    if (PeekMessage(&msg, hwnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) ||
        PeekMessage(&msg, hwnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)) 
    { 
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        return TRUE;
    } 

    ...

    if (PeekMessage(&msg, hwnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) ||
        PeekMessage(&msg, hwnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)) 
    { 
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        return TRUE;
    } 

    ...

    return FALSE;
}

否则,您应该将冗长的操作移至单独的工作线程,而不是阻塞主 UI 消息队列。当主消息循环正常接收到鼠标/键盘输入时,如果线程正在运行,您可以向线程发出终止自身的信号。

于 2017-04-11T18:25:31.197 回答