2011-12-29 3 views
1

내 메인 대화 상자에 프로세스를 생성하고 완료 될 때까지 기다리는 기능이 있습니다. 최대 15-20 초가 걸릴 수 있습니다. WaitForSingleObject를 사용하여 대기하는 경우 대화 상자가 응답하지 않게됩니다.내부 메시지 루프

내 대화 상자 블록을 만들기 위해 EnableWindow (FALSE)와 내부 메시지 루프의 조합을 사용하고 싶지만 MessageBox와 DoModal의 작동 방식은 앱이 멈추지 않아도됩니다. 하지만 내부 메시지 루프를 수행하는 방법을 잘 모르겠습니다.

답변

2

내부 메시지 루프를 실행하는 것은 사소한 코딩입니다. 다음과 같은

뭔가 전부입니다 :

EnableWindow(FALSE); 
while (/* check for my exit condition */) 
{ 
    MSG msg; 
    if(::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) 
    { 
     if(!AfxGetApp()->PumpMessage()) 
     { 
      ::PostQuitMessage(0); 
     } 
    } 
} 
EnableWindow(TRUE); 

가 프로세스 종료를 기다릴하려면 (< 30ms의) 시간 초과 메시지 루프에서 WaitForSingleObject 전화 매우 짧은 사용할 수 있습니다. 또는 MsgWaitForMultipleObjects. 또는 GetExitCodeProcess.

다른 접근 방법을 권하고 싶습니다. 프로세스가 여전히 GetExitCodeProcess
4, OnTimer 처리기에서 실행중인 경우 프로세스가 어떤을 때
1) EndDialog에 전화)의 OnInitDialog 처리기에서 프로세스를 시작합니다) 새로운 모달 팝업
2를 표시하지 않고 타이머
3) 확인을 시작합니다 이상

3

귀하의 접근 방식이 작동하지 않을 까봐 두렵습니다. 귀하의 애플 리케이션은 싱글 스레드 또는 적어도 귀하의 UI입니다. WaitForSingleObject를 호출하면 스레드가 잠자기 상태가되고 Windows 메시지를 처리하지 않습니다. 내부 메시지 루프가 있다는 사실은 중요하지 않습니다. 아마도 새 스레드를 시작하고 프로세스가 완료 될 때까지 기다린 다음 UI 스레드에 알리고 종료해야합니다. 아니면 그 라인을 따라 뭔가.

1

MsgWaitForMultipleObjects 함수를 사용해보십시오. 이벤트 객체를 기다리는 동안 Windows 메시지를 처리 ​​할 수 ​​있습니다.

1

을 실행하면 수 :

  • (조금 복잡가), 언하는 메시지 또는을 마무리하는 과정을 기다릴 MsgWaitForMultipleObjects (또는 MsgWaitForMultipleObjectsEx)를 사용 ive (정상적인 방법으로 처리).
  • (단순) RegisterWaitForSingleObject를 사용하면 프로세스가 종료 될 때 별도의 스레드에서 호출되는 콜백을 등록 할 수 있습니다. 콜백을 사용하면 윈도우에 메시지를 게시 할 수 있습니다.
  • (매우 간단)에서 대기 할 수있는 자신의 스레드를 만들 수 있습니다.

나는 2 옵션과 함께 갈 것입니다.

0
DWORD ec; 

    if(CreateProcess(NULL, // No module name (use command line). 
     szExe,     // Command line. 
     NULL,           // Process handle not inheritable. 
     NULL,           // Thread handle not inheritable. 
     FALSE,          // Set handle inheritance to FALSE. 
     procFlags,    // No creation flags. 
     NULL,           // Use parent's environment block. 
     NULL,           // Use parent's starting directory. 
     &si,           // Pointer to STARTUPINFO structure. 
     &pi)           // Pointer to PROCESS_INFORMATION structure. 
     ) 
{ 

    while(GetExitCodeProcess(pi.hProcess, &ec) && ec == STILL_ACTIVE) 
    { 
    MSG msg; 
    while(::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) 
    { 
    if(!AfxGetApp()->PumpMessage()) 
    { 
     ::PostQuitMessage(0); 
     break; 
    } 
    } 
    // let MFC do its idle processing 
    LONG lIdle = 0; 
    while(AfxGetApp()->OnIdle(lIdle++)) 
    ; 
    } 
    } 
    if(ec) 
    { 
    CloseHandle(pi.hProcess); 
    }