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

StackOverflow https://stackoverflow.com/questions/77133

  •  09-06-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

Я использовал Win32::GuiTest Модуль Perl для выполнения подобных действий в прошлом.

Другие советы

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

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

Да, конечно, это возможно.Я столкнулся с подобной проблемой несколько месяцев назад, когда какое-то (неизвестное, но, вероятно, мое) приложение предотвращало завершение работы, поэтому я написал быстрый код, который использовал 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_pThis был просто локальной копией этого указателя диалогового окна, поэтому вспомогательный обратный вызов мог получить к нему доступ.Я же говорил тебе, что это было быстро и грязно :-)

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top