本文介绍了使用shellexecuteex和waitforsingleobject父窗口返回时会失去焦点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
使用下面的代码运行外部exe文件,当此应用程序终止时,父窗口失去焦点。我想禁用父窗口以避免任何绘制问题,并在WaitForSingleObject终止时重新激活。
有什么解决方案吗?我做错了什么?
Using the code below to run an external exe file, when this app terminates, the parent window loses its focus. I want to disable the parent window to avoid any paint problems and re-activate when the WaitForSingleObject is terminated.
Is there any solution for that ? What am i doing wrong ?
void CMainFrame::OnBtnUpdateApp() {
SHELLEXECUTEINFO lpExecInfo;
DWORD dwExitCode;
HINSTANCE hProcess = 0;
BOOL bResult;
ZeroMemory(&lpExecInfo,sizeof(lpExecInfo));
lpExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
lpExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
lpExecInfo.hwnd = GetSafeHwnd();
lpExecInfo.lpVerb = _T("open");
lpExecInfo.lpFile = _T("Update.exe");
lpExecInfo.lpParameters = _T("");
lpExecInfo.lpDirectory = _T("");
lpExecInfo.nShow = SW_SHOWNORMAL;
lpExecInfo.hInstApp = NULL;
lpExecInfo.hProcess = hProcess;
bResult = ShellExecuteEx(&lpExecInfo);
if(bResult) {
EnableWindow(FALSE);
WaitForSingleObject( lpExecInfo.hProcess, INFINITE );
if (!GetExitCodeProcess(lpExecInfo.hProcess, &dwExitCode)) {
//failed to terminate normally
}
CloseHandle(lpExecInfo.hProcess);
EnableWindow(TRUE);
} else {
//failed to execute the exe file
}
}
我尝试了什么:
我试过,BringWindowToTop(),SetActiveWindow(),SetFocus ()
What I have tried:
I tried, BringWindowToTop(), SetActiveWindow(), SetFocus()
推荐答案
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
PROCESS_INFORMATION pi;
STARTUPINFO si;
BOOL ret = FALSE;
DWORD flags = CREATE_NO_WINDOW;
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags |= STARTF_USESTDHANDLES;
si.hStdInput = NULL;
si.hStdError = h;
si.hStdOutput = h;
CString cmd = _T("cmd /c ") + _T("Update.exe");
BOOL inherits = FALSE;
ret = CreateProcess(NULL,
cmd.GetBuffer(),
NULL,
NULL,
inherits,
flags,
NULL,
NULL,
&si,
&pi);
DWORD dwExitCode = 0;
if (ret)
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return TRUE;
}
void CMainFrame::OnBtnUpdateApp() {
PROCESS_INFORMATION processInfo;
DWORD dwExitCode;
HANDLE hProcess = 0;
BOOL bResult;
CString strCmd;
CUtils util;
CString strPathAndApp;
strCmd = _T("");
MONITORINFO mi = { sizeof(mi) };
::GetWindowPlacement(GetSafeHwnd(), &m_g_wpPrevFrameSize) && ::GetMonitorInfo(MonitorFromWindow(GetSafeHwnd(),MONITOR_DEFAULTTOPRIMARY), &mi);
strPathAndApp = _T("\"") + util.GetApplicationPath() + _T("\\")+_T(UPDATE_EXE_FILE) + _T("\"") + strCmd;
//******************************************************************************************
//Pass the File + Parameters to cmdLine because otherwise it wont run under Winsows XP
//******************************************************************************************
bResult = StartupApplicationWithProcess (NULL, strPathAndApp.GetBuffer(), &processInfo); //CreateProcess goes here
strPathAndApp.ReleaseBuffer();
if(bResult) { //(UINT)result > HINSTANCE_ERROR)
AMLOGINFO(_T("LiveUpdate dialog box opened successfully."));
DWORD dwRet;
do {
dwRet = ::MsgWaitForMultipleObjects(1, &processInfo.hProcess, FALSE, INFINITE, QS_ALLINPUT);
if (dwRet != WAIT_OBJECT_0) {
PeekMessageLoop();
}
} while ((dwRet != WAIT_OBJECT_0) && (dwRet != WAIT_FAILED));
if (!GetExitCodeProcess(processInfo.hProcess, &dwExitCode)) {
AMLOGINFO(_T("LiveUpdate is not terminated normally."));
}
CloseHandle( processInfo.hProcess );
CloseHandle( processInfo.hThread );
AMLOGINFO(_T("LiveUpdate is terminated without any errors."));
} else {
CString ErrorDescr = FormatErrorMessage(GetLastError());
AfxMessageBox("Error !");
}
SetForegroundWindow();
SetActiveWindow();
BringWindowToTop();
UpdateWindow();
这篇关于使用shellexecuteex和waitforsingleobject父窗口返回时会失去焦点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!