Можно ли отправлять сообщения WM_QUERYENDSESSION в окно в другом процессе? - PullRequest
4 голосов
/ 17 сентября 2008

Я хочу отладить приложение Windows C ++, которое я написал, чтобы понять, почему оно не отвечает на WM_QUERYENDSESSION так, как я ожидаю. Очевидно, что это немного сложно сделать, просто выключив систему. Есть ли какая-либо утилита или код, который я могу использовать для отправки фальшивого WM_QUERYENDSESSION в мои окна приложений самостоятельно?

Ответы [ 4 ]

1 голос
/ 17 сентября 2008

Да, конечно, это возможно. Несколько месяцев назад я столкнулся с подобной проблемой, когда какое-то (неизвестное, но, вероятно, моё) приложение препятствовало завершению работы, поэтому я написал быстрый код, использующий EnumWindows для перечисления всех окон верхнего уровня, отправив каждому сообщение WM_QUERYENDSESSION, отметив, что возвращаемое значение Значение из SendMessage было и остановило перечисление, если кто-нибудь вернул FALSE. Заняло около десяти минут в C ++ / MFC. Это было мужество этого:

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);  
      if (csTitle.GetLength() == 0)  
      {  
         GetWindowThreadProcessId (hTarget, &dwPID);  
         csTitle.Format ("<PID=%d>", dwPID);  
      }  

      if (pWnd->SendMessage (WM_QUERYENDSESSION, 0, ENDSESSION_LOGOFF))  
      {  
         csMsg.Format ("window 0x%X (%s) returned TRUE", hTarget, csTitle);  
      }  
      else   
      {    
         csMsg.Format ("window 0x%X (%s) returned FALSE", hTarget, csTitle);  
         bRetVal = FALSE;  
      }  

      mg_pThis->m_ctrl_ListMsgs.AddString (csMsg);
   }
   else  
   {  
      csMsg.Format ("Unable to resolve HWND 0x%X to a CWnd", hTarget);  
      mg_pThis->m_ctrl_ListMsgs.AddString (csMsg);  
   }  
   return bRetVal;  
}

mg_pЭто была просто локальная копия указателя this диалога, поэтому вспомогательный обратный вызов мог получить к нему доступ. Я сказал вам, это было быстро и грязно: -)

1 голос
/ 17 сентября 2008

Я использовал Perl-модуль Win32 :: GuiTest , чтобы делать подобные вещи в прошлом.

1 голос
/ 17 сентября 2008

Для этого можно использовать Windows API SendMessage. http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx

Возможно, он не отвечает, потому что какой-то другой запущенный процесс ответил нулем (заставляя систему ждать его).

0 голосов
/ 17 сентября 2008

Да. Если вы можете получить дескриптор окна (возможно, используя FindWindow ()), вы можете отправлять / публиковать любое сообщение, если WPARAM и LPARAM не являются указателями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...