2008-09-16 2 views
4

Je veux déboguer une application Windows C++ que j'ai écrite pour voir pourquoi elle ne répond pas à WM_QUERYENDSESSION comme je le souhaite. Il est clair qu'il est un peu difficile de le faire en fermant simplement le système. Y at-il un utilitaire ou un code que je peux utiliser pour envoyer moi-même une fausse WM_QUERYENDSESSION à mes fenêtres d'application?Est-il possible d'envoyer des messages WM_QUERYENDSESSION à une fenêtre dans un processus différent?

+0

Voir la question en double http://stackoverflow.com/a/2673800/126229 qui a un lien vers rmtool.exe – EricLaw

Répondre

0

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

1

Oui, bien sûr, possible. J'ai rencontré un problème similaire il y a quelques mois où une application (inconnue, mais probablement la mienne) empêchait l'arrêt, donc j'ai écrit un code rapide qui utilisait EnumWindows pour énumérer toutes les fenêtres de haut niveau, envoyait un message WM_QUERYENDSESSION, notait le retour La valeur de SendMessage était et a arrêté l'énumération si quelqu'un retournait FALSE. A pris environ dix minutes en C++/MFC. Ce fut le courage de celui-ci:

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 était juste une copie locale de ce pointeur de la boîte de dialogue, de sorte que le rappel d'aide pourrait y accéder. Je vous ai dit que c'était rapide et sale :-)

+0

Veuillez essayer de formater votre code - indent chaque ligne avec 4 espaces. – ChrisN

Questions connexes