2011-12-29 159 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); 

等待進程退出,你可以用很短(< 30毫秒)的超時WaitForSingleObject調用消息循環。或MsgWaitForMultipleObjects。或GetExitCodeProcess

我想推薦另一種方法。
1)顯示新模式彈出
2)開始在OnInitDialog處理程序的過程,並啓動一個定時器
3)檢查過程仍在的OnTimer處理程序運行,通過GetExitCodeProcess
4)調用的EndDialog時,這個過程是不更長的運行

3

恐怕你的做法不行。你的應用程序是單線程的,或者至少你的UI是。在您調用WaitForSingleObject之後,您的線程將進入休眠狀態,並且不會處理Windows消息。你有一個內部消息循環的事實並不重要。您可能應該啓動一個新線程並使用它來等待進程完成,然後通知您的UI線程並退出。或類似的規定。

1

嘗試MsgWaitForMultipleObjects函數;它可以在等待事件對象時處理Windows消息。

1

,你可以:

  • (有點複雜)使用MsgWaitForMultipleObjects(或MsgWaitForMultipleObjectsEx)等待進程結束的消息arr中ive(以正常方式處理它)。
  • (簡單)使用RegisterWaitForSingleObject註冊一個在進程退出時在單獨的線程中調用的回調函數(也許該回調函數只是將消息發佈到窗口中)。
  • (很簡單)創建自己的線程來執行在等待。

我會用第二個選項去。

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