2017-03-28 18 views
0
에서 LengthyOperation을 취소 할 수 있습니다 어떻게

나는 완전히 혼란 MSDN의 기사 등을 읽고 :내가 WindowProc

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

+0

아마도이 함수는 * 오랫동안 * false *를 반환하여 긴 작업이 아직 수행되지 않았 음을 나타냅니다. 핵심은 하나의 긴 작업을 여러 개의 작은 작업으로 나누는 것입니다. –

+0

* GUI * 스레드에서 DoLengthyOperation();을 호출하면 안됩니다. 별도의 작업 스레드에서 호출해야합니다. 당신의 코드 예제에서'DoLengthyOperation();'이 실행될 때까지'PeekMessage'를 호출하지 않고 윈도우 메시지를 전혀 얻지 못하고 UI가 동결됩니다. – RbMm

+0

@HansPassant 함수가 다음 호출에서 잠시 동안 false를 반환하면 어떻게 되나요? 이전 호출에서 실행 된 코드의 마지막 줄부터? 다음 호출 함수에서 첫 번째 줄에서 다시 실행 –

답변

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 메시지 대기열을 전혀 차단하지 마십시오. 메인 메시지 루프가 마우스/키보드 입력을 정상적으로 수신하면 스레드가 실행 중일 때 스레드가 종료되도록 신호 할 수 있습니다.