4

与 Windows Vista 不同,当 Windows XP 关闭时,它不会告诉您哪个程序请求不要关闭。这使 Windows 仍在运行,并且不会告诉您阻止关机的程序。

据我了解,Windows 发送WM_QUERYENDSESSION到所有应用程序。如果任何应用程序向函数返回 0,则停止关闭。

我想知道是否有一种方法可以从程序中捕获返回值并确定 Windows XP 没有关闭的原因。

谢谢菲尔

4

2 回答 2

3

枚举所有顶级窗口(使用 EnumWindows())并向每个窗口发送 WM_QUERYENDSESSION。对于返回阻止值的窗口,检测它是哪个进程。要执行后者调用 GetWindowThreadProcessId(),请枚举所有进程并找到具有该 ID 的进程。

于 2009-10-06T04:53:45.307 回答
1

是的。我在这个问题中发布了代码,但这是代码的改进版本:

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这是一个指向对话框对象的模块全局指针,因此枚举器可以访问它的控制权。

于 2009-10-06T10:26:50.793 回答