4

Windows Vista とは異なり、Windows XP がシャットダウンするとき、どのプログラムがシャットダウンしないように要求しているかは通知されません。これにより、Windows が実行されたままになり、シャットダウンを妨げているプログラムが通知されません。

私が理解しているように、WindowsWM_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 に答える