¿Es posible enviar mensajes WM_QUERYENDSESSION a una ventana en un proceso diferente?

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

  •  09-06-2019
  •  | 
  •  

Pregunta

Quiero depurar una aplicación de Windows C++ que escribí para ver por qué no responde a WM_QUERYENDSESSION como esperaba.Claramente es un poco complicado hacer esto simplemente apagando el sistema.¿Existe alguna utilidad o código que pueda usar para enviar un WM_QUERYENDSESSION falso a las ventanas de mi aplicación?

¿Fue útil?

Solución

he usado el Win32::GuiTest Módulo Perl para hacer este tipo de cosas en el pasado.

Otros consejos

La API de Windows SendMessage se puede utilizar para hacer esto.http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx

¿Es posible que no responda porque algún otro proceso en ejecución respondió con un cero (haciendo que el sistema espere).

Sí, por supuesto, es posible.Me enfrenté a un problema similar hace algunos meses en el que alguna aplicación (desconocida, pero probablemente mía) impedía el cierre, así que escribí un código rápido que usaba EnumWindows para enumerar todas las ventanas de nivel superior, envié a cada una un mensaje WM_QUERYENDSESSION y anoté cuál era el resultado. El valor de SendMessage era y detenía la enumeración si alguien devolvía FALSO.Tomó unos diez minutos en C++/MFC.Este fue el meollo de la cuestión:

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_pEsto era solo una copia local del puntero this del cuadro de diálogo, por lo que la devolución de llamada del asistente podía acceder a él.Te dije que fue rápido y sucio :-)

Sí.Si puede obtener el identificador de la ventana (tal vez usando FindWindow()), puede enviarle/publicar cualquier mensaje siempre que WPARAM y LPARAM no sean punteros.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top