是否可以在其他过程中将WM_QUERYENDSESSION消息发送到窗口?

时间:2020-03-05 18:57:13  来源:igfitidea点击:

我想调试我编写的Windows C ++应用程序,以查看为什么它对WM_QUERYENDSESSION的响应没有达到我的期望。显然,仅通过关闭系统来执行此操作有点棘手。我是否可以使用任何实用程序或者代码向我的应用程序窗口发送伪造的WM_QUERYENDSESSION?

解决方案

回答

是的。如果可以获取窗口句柄(也许使用FindWindow()),则只要WPARAM和LPARAM不是指针,就可以向其发送/发布任何消息。

回答

我过去曾使用Win32 :: GuiTest Perl模块来做这种事情。

回答

Windows API SendMessage可用于执行此操作。
http://msdn.microsoft.com/zh-CN/library/ms644950(VS.85).aspx

这很可能没有响应,因为其他一些正在运行的进程的响应为零(使系统等待)。

回答

是的,当然可以。几个月前,我遇到了类似的问题,其中某个(未知但可能是我的)应用阻止了关机,因此我编写了一些快速代码,使用EnumWindows枚举了所有顶级窗口,并向每个窗口发送了WM_QUERYENDSESSION消息,并指出了返回的内容如果有人返回FALSE,则SendMessage的值是,并停止枚举。在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指针的本地副本,因此帮助程序回调可以访问它。我告诉过你那又快又脏:-)