Reputation: 41
Unlike Windows Vista, when Windows XP is shutting down - it doesn't tell you which program is requesting not to be shutdown. This leaves Windows still running and not telling you what program is preventing shutdown.
As I understand it, Windows sends WM_QUERYENDSESSION
to all applications. If any of the applications return 0 to the function, shutdown is halted.
I am wondering is there a method to capture the return values from programs and determine why Windows XP is not shutting down.
Thanks Phil
Upvotes: 4
Views: 2149
Reputation: 6894
Yes. I posted code in this question, but this is an improved version of the code:
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_pThis is a module-global pointer to the dialog object, so the enumerator can get access to it's control.
Upvotes: 1
Reputation: 170489
Enumerate all top-level windows (use EnumWindows()) and send WM_QUERYENDSESSION to each. For the window that returns a preventing value detect which process it is. To do the latter call GetWindowThreadProcessId(), enumerate all processes and find the process with that id.
Upvotes: 3