我想调试我编写的 Windows C++ 应用程序,看看为什么它没有像我期望的那样响应 WM_QUERYENDSESSION。显然,仅通过关闭系统来做到这一点有点棘手。是否有任何实用程序或代码可用于将假的 WM_QUERYENDSESSION 发送到我的应用程序窗口?
Free Wildebeest
问问题
3434 次
4 回答
1
我过去曾使用Win32::GuiTest Perl 模块来做这种事情。
于 2008-09-16T21:15:46.460 回答
1
Windows API SendMessage 可用于执行此操作。 http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx
是否可能它没有响应,因为其他一些正在运行的进程已经响应为零(使系统等待它。)
于 2008-09-16T21:16:11.060 回答
1
是的,当然有可能。几个月前我遇到了一个类似的问题,其中一些(未知,但可能是我的)应用程序正在阻止关闭,所以我编写了一些快速代码,使用 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_pThis 只是对话框的 this 指针的本地副本,因此辅助回调可以访问它。我告诉过你它又快又脏:-)
于 2008-09-16T21:45:56.730 回答
0
是的。如果您可以获得窗口句柄(可能使用 FindWindow()),只要 WPARAM 和 LPARAM 不是指针,您就可以向它发送/发布任何消息。
于 2008-09-16T21:15:35.493 回答