Est-il possible d'envoyer des messages WM_QUERYENDSESSION à une fenêtre dans un processus différent?

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

  •  09-06-2019
  •  | 
  •  

Question

Je souhaite déboguer une application Windows C ++ que j'ai écrite pour comprendre pourquoi elle ne répond pas à WM_QUERYENDSESSION comme je le souhaite. Clairement, il est un peu difficile de faire cela en fermant simplement le système. Existe-t-il un utilitaire ou un code que je peux utiliser pour envoyer moi-même un faux WM_QUERYENDSESSION à la fenêtre de mes applications?

Était-ce utile?

La solution

J'ai utilisé le module Win32 :: GuiTest pour faire ce genre de chose dans le passé.

Autres conseils

L’API Windows SendMessage peut être utilisé à cette fin. http://msdn.microsoft.com/en-us /library/ms644950(VS.85).aspx

Est-il possible qu'il ne réponde pas car un autre processus en cours d'exécution a répondu par un zéro (le système attend dessus).

Oui bien sûr, c'est possible. Il y a quelques mois, j'ai rencontré un problème similaire dans lequel une application (inconnue, mais probablement la mienne) empêchait l'arrêt, alors j'ai écrit un code rapide qui utilisait EnumWindows pour énumérer toutes les fenêtres de niveau supérieur, envoyait à chacune un message WM_QUERYENDSESSION, notait le retour La valeur de SendMessage était et arrêtait l'énumération si quelqu'un renvoyait FALSE. A pris environ dix minutes en C ++ / MFC. C'en était le courage:

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_pIl s'agissait simplement d'une copie locale du pointeur de la boîte de dialogue, afin que le rappel d'assistance puisse y accéder. Je vous ai dit que c'était rapide et sale: -)

Oui. Si vous pouvez obtenir le handle de fenêtre (peut-être en utilisant FindWindow ()), vous pouvez envoyer / poster n'importe quel message, aussi longtemps que WPARAM & amp; LPARAM ne sont pas des pointeurs.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top