tags:

views:

207

answers:

2

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

+3  A: 

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.

sharptooth
A: 

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;
}
Bob Moore