使用场景:
程序中调用某进程:若进程未打开,调用打开此进程;若进程已打开,则使此进程最前显示;
方法步骤:
1.根据进程名称获取进程ID;
2.根据进程ID,获取窗口句柄;
3.根据窗口句柄,设置最前显示;
代码如下:
static HWND GetWindowHandleByPID(DWORD dwProcessID)//通过进程ID获取窗口句柄
{
HWND h = ::GetTopWindow(0);
while (h)
{
DWORD pid = 0;
DWORD dwTheardId = GetWindowThreadProcessId(h, &pid);
if (dwTheardId != 0)
{
if (pid == dwProcessID)
{
// here h is the handle to the window
while (::GetParent(h) != NULL)
h = ::GetParent(h);
return h;
}
}
h = ::GetNextWindow(h, GW_HWNDNEXT);
}
return NULL;
}
static void testFunc()
{
bool isFindExe = false;
std::wstring child_proc_name = L"chrome.exe";
// 获取进程列表快照
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
// 存储进程实体信息
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
// 获取进程列表快照中,第一个进程信息
if (FALSE == Process32First(hSnapShot, &pe))
{
isFindExe = false;
}
else
{
// 逐个获取进程列表快照中的进程
while (Process32Next(hSnapShot, &pe))
{
if (0 == child_proc_name.compare(pe.szExeFile))
{
isFindExe = true;
HWND w = NULL;
w = GetWindowHandleByPID(pe.th32ProcessID);//根据id获取窗口句柄
if (w != NULL)
{
ShowWindow(w, SW_SHOWNORMAL);
SendMessage(w, WM_ACTIVATE, WA_ACTIVE, 0);
SetForegroundWindow(w);
break;
}
}
}
}
if (!isFindExe)
{
//重新打开进程
}
}
备注:
在设置窗口最前显示的时候,由于测试用的是浏览器进程,当浏览器最小化之后,网上找了一些的方法很难再唤起;所以最后选择发送消息的方式唤起;重点代码:
ShowWindow(w, SW_SHOWNORMAL);
SendMessage(w, WM_ACTIVATE, WA_ACTIVE, 0);
SetForegroundWindow(w);
注意:
网上搜索的关于设置窗口最前显示的方法,大部分都是下面这几种:
ShowWindow(w, SW_SHOWNORMAL);
SetWindowPos(w, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
SetWindowPos(w, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
SetForegroundWindow(w);
AttachThreadInput(dwCurID, dwForeID, FALSE);
这些方式在遇到窗口最小化之后,就有很多无法唤起;或者窗口不是MFC的时候,也容易唤起失败;
以上,
原创,转载请注明出处;