在我的主对话框中,我有一个创建进程并等待它完成的函数。可能需要15-20秒。如果我只是等待使用WaitForSingleObject,我的对话框就会没有响应。
我想使用EnableWindow(FALSE)和内部消息循环的组合来使我的对话框阻止,但看起来不像应用程序冻结,就像MessageBox和DoModal那样。但我不知道如何做一个内部消息循环。
答案 0 :(得分:3)
我担心你的方法不起作用。您的应用是单线程的,或者至少是您的用户界面。在调用WaitForSingleObject之后,您的线程将进入休眠状态,并且它不会处理Windows消息。你有一个内部消息循环的事实并不重要。您可能应该启动一个新线程并使用它等待进程完成,然后通知您的UI线程并退出。或者沿着这些方向发展。
答案 1 :(得分: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
。
我想推荐另一种方法
1)显示新的模态弹出窗口
2)在OnInitDialog处理程序中启动进程并启动计时器
3)检查进程是否仍在OnTimer处理程序中运行,GetExitCodeProcess
4)当进程不再运行时调用EndDialog
答案 2 :(得分:1)
尝试MsgWaitForMultipleObjects函数;它可以在等待事件对象时处理Windows消息。
答案 3 :(得分:1)
你可以:
我会选择第二个选项。
答案 4 :(得分: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);
}