Внутренняя петля сообщений - PullRequest
1 голос
/ 29 декабря 2011

В моем главном диалоге у меня есть функция, которая создает процесс и ожидает его завершения. Это может занять до 15-20 секунд. Если я просто жду, используя WaitForSingleObject, мой диалог перестает отвечать на запросы.

Я хочу использовать комбинацию EnableWindow (FALSE) и внутренний цикл обработки сообщений, чтобы сделать мой диалоговый блок, но, не смотря на то, что приложение зависает, как это делают MessageBox и DoModal. Но я не уверен, как сделать это внутренним циклом сообщений.

Ответы [ 5 ]

3 голосов
/ 29 декабря 2011

Боюсь, ваш подход не сработает. Ваше приложение однопоточное или, по крайней мере, ваш пользовательский интерфейс. После вызова WaitForSingleObject ваш поток переводится в спящий режим, и он не будет обрабатывать сообщения Windows. Тот факт, что у вас есть внутренний цикл сообщений, не имеет значения. Вероятно, вам следует запустить новый поток и использовать его, чтобы дождаться завершения процесса, а затем уведомить ваш поток пользовательского интерфейса и выйти. Или что-то в этом роде.

2 голосов
/ 29 декабря 2011

Выполнение внутреннего цикла сообщений - довольно тривиальное кодирование.

Все, что показано ниже, это все:

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

Чтобы дождаться завершения процесса, вы можете использовать очень короткий (<30 мс) тайм-аут<code>WaitForSingleObject вызов в цикле сообщений.Или MsgWaitForMultipleObjects.Или GetExitCodeProcess.

Я хотел бы рекомендовать другой подход.
1) Показать новое модальное всплывающее окно
2) Запустить процесс в обработчике OnInitDialog и запустить таймер
3) Проверитьесли процесс все еще выполняется в обработчике OnTimer, GetExitCodeProcess
4) Вызвать EndDialog, когда процесс больше не выполняется

1 голос
/ 29 декабря 2011

Вы могли бы:

  • (немного сложно) используйте MsgWaitForMultipleObjects (или MsgWaitForMultipleObjectsEx), чтобы дождаться завершения процесса или для получения сообщения (обрабатывая его обычным способом).
  • (просто) используйте RegisterWaitForSingleObject для регистрации обратного вызова, который вызывается в отдельном потоке при выходе из процесса (и, возможно, этот обратный вызов просто отправляет сообщение в ваше окно).
  • (довольно просто) создайте свой собственный поток для ожидания.

Я бы выбрал второй вариант.

1 голос
/ 29 декабря 2011

Попробуйте функцию MsgWaitForMultipleObjects;он может обрабатывать сообщения Windows во время ожидания объекта события.

0 голосов
/ 29 августа 2013
    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);
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...