与Windows Vista不同,Windows XP正在关闭时 - 它不会告诉您哪个程序请求不关闭。这使Windows仍在运行,并没有告诉您哪个程序阻止了关机。
据我了解,Windows将WM_QUERYENDSESSION
发送给所有应用程序。如果任何应用程序将0返回到该函数,则停止关闭。
我想知道是否有一种从程序中捕获返回值的方法,并确定Windows XP没有关闭的原因。
由于 菲尔
答案 0 :(得分:3)
枚举所有顶级窗口(使用EnumWindows())并向每个窗口发送WM_QUERYENDSESSION。对于返回阻止值的窗口,检测它是哪个进程。要做后者调用GetWindowThreadProcessId(),枚举所有进程并找到具有该id的进程。
答案 1 :(得分:1)
是。我在this question中发布了代码,但这是代码的改进版本:
void CQes_testDlg::OnBtnTest()
{
// enumerate all the top-level windows.
m_ctrl_ListMsgs.ResetContent();
EnumWindows (EnumProc, 0);
}
BOOL CALLBACK EnumProc (HWND hTarget, LPARAM lParam)
{
CString csTitle;
CString csMsg;
CWnd * pWnd = CWnd::FromHandle (hTarget);
BOOL bRetVal = TRUE;
DWORD dwPID;
if (pWnd)
pWnd->GetWindowText (csTitle);
else
csTitle = TEXT("<unknown>");
GetWindowThreadProcessId (hTarget, &dwPID);
if (pWnd->SendMessage (WM_QUERYENDSESSION, 0, ENDSESSION_LOGOFF))
{
csMsg.Format ("window 0x%X (PID=%d, Title='%s') returned TRUE",
hTarget, dwPID, csTitle);
}
else
{
csMsg.Format ("window 0x%X (PID=%d, Title='%s') returned FALSE *******",
hTarget, dwPID, csTitle);
bRetVal = FALSE;
}
mg_pThis->m_ctrl_ListMsgs.AddString (csMsg);
return bRetVal;
}
mg_p这是一个指向对话框对象的模块全局指针,因此枚举器可以访问它的控件。