请教大家一个问题:如何让子进程呈现模态效果?
以下代码虽然可以阻塞主进程,但Bug很明显:
1 当子进程退出时,主进程窗体会跑到其他程序窗体的后面去。
// 可能是由于主进程没有Focus导致;如果此时使用SetForgroudWindow强行提前,会产生闪烁,效果不理想
2 当点击父进程在任务栏上的主窗体按钮时,父进程的主窗体会被提前。
另外,我见过一个软,也是多进程协作工作,它能让子进程以“模态”的方式工作的非常好,基本上和模态Dlg一样的效果,比如点击主进程窗体(处于Disable状态),子进程的窗体会标题栏会闪动,点击任务栏按钮也是模态效果。
请问大家是否有这方面的经验,或者能给出一个方案达到比较高仿真模态的效果?
请大家帮忙分析一下!!
在下谢了!!!
------一CNPack的老用户,忠实用户!!
有问题的代码:
bool execAppByCmd(UnicodeString cmdStr, bool shellExec)
{
TShellExecuteInfoW aExecInfo;
TProcessInformation lpi;
STARTUPINFOW startInfo;
ULONG dwExit;
void* hProcess;
void* hThread;
void* wndList;
bool ret = false;
wndList = DisableTaskWindows(0 /*Application->Handle*/); // Disable窗体
try {
// 执行命令行
if (shellExec) {
ZeroMemory(&aExecInfo, sizeof(aExecInfo));
aExecInfo.cbSize = sizeof(aExecInfo);
aExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
aExecInfo.nShow = SW_SHOW;
aExecInfo.lpVerb = L"open";
aExecInfo.lpFile = cmdStr.w_str();
aExecInfo.lpParameters = NULL;
ret = ShellExecuteExW(&aExecInfo);
hProcess = aExecInfo.hProcess;
hThread = 0;
}
else {
GetStartupInfoW(&startInfo);
startInfo.cb = sizeof(startInfo);
ret = CreateProcessW(NULL, cmdStr.w_str(), NULL, NULL, false,
0, NULL, NULL, &startInfo, &lpi);
hProcess = lpi.hProcess;
hThread = lpi.hThread;
}
if (ret) { // 创建应用程序成功
// 注意,需要等待该进程向Windows系统注册完
WaitForInputIdle(hProcess, INFINITE);
// 模态显示,等待进程退出
while (true) {
GetExitCodeProcess(hProcess, &dwExit);
if (dwExit != STILL_ACTIVE) {
break;
}
switch (WaitForSingleObject(hProcess, 10)) {
case WAIT_TIMEOUT:
Application->ProcessMessages(); // 处理消息队列
continue;
case WAIT_ABANDONED:
break;
case WAIT_FAILED:
break;
}
}
// 关闭句柄
if (hThread != 0)
CloseHandle(hThread);
if (hProcess != 0)
CloseHandle(hProcess);
}
}
__finally {
if (wndList != NULL) {
EnableTaskWindows(wndList); // Enable窗体
}
}
return ret;
}
[ 本帖最后由 starsite 于 2010-9-8 13:52 编辑 ]
|