How Can I Cancel LengthyOperation In WindowProc

64 Views Asked by At

I Have Read An MSDN Article And Completely Confused:

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 Says With This Code We Can examine the message queue during a lengthy operation & cancel it In Case Of Mouse Click Or Keyboard KeyDown. how thishappend?

when DoLengthyOperation starts does not returned until it finished and PeekMessage does not call in this time and cant cancel the operation.

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

1

There are 1 best solutions below

0
Remy Lebeau On

To do what you are asking for, you need to peek the message queue from inside of DoLengthyOperation() itself, eg:

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;
}

Otherwise, you should move the lengthy operation to a separate worker thread instead, don't block the main UI message queue at all. When the main message loop receives mouse/keyboard input normally, you can then signal the thread to terminate itself if it is running.