WM_QUERYENDSESSION에 응답하지 않는 이유를 확인하기 위해 작성한 Windows C++ 응용 프로그램을 디버깅하고 싶습니다. 분명히 시스템을 종료하여이 작업을 수행하는 것은 약간 까다 롭습니다. 가짜 WM_QUERYENDSESSION을 내 응용 프로그램 창에 직접 보내는데 사용할 수있는 유틸리티 나 코드가 있습니까?WM_QUERYENDSESSION 메시지를 다른 프로세스의 창에 보낼 수 있습니까?
답변
나는이 종류의 일을하기 위해 과거에 Win32::GuiTest Perl 모듈을 사용 해왔다.
예. WPARAM & LPARAM이 포인터가 아닌 한 창 핸들 (FindWindow() 사용)을 얻을 수 있다면 WPARAM & 포인터가 아닌 한 메시지를 보내거나 게시 할 수 있습니다.
Windows API SendMessage를 사용하여이 작업을 수행 할 수 있습니다. http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx
는 다른 실행중인 프로세스가 0으로 대응하고 있기 때문에 가능한이 응답하지 않는 것 TI IS (시스템이 기다려야하고.)
예 물론, 그것은 가능합니다. 몇 달 전에 비슷한 문제가 발생하여 EnumWindows를 사용하여 모든 최상위 창을 열거하고 WM_QUERYENDSESSION 메시지를 하나씩 보낸 빠른 코드를 작성했습니다. 누군가가 FALSE를 반환하면 SendMessage의 값이 열거를 중지하고 중지했습니다. C++/MFC에서 약 10 분이 걸렸습니다. 이것은 그것의 배짱이었다 도우미 콜백이 액세스 할 수 있도록
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는 대화 상자의이 포인터의 단지 로컬 복사본이었다. 나는 그것이 빠르고 빠르다고 말했다 :-)
각 줄을 들여 쓰는 코드 샘플을 시도해보십시오. 4 칸. – ChrisN
rmtool.exe에 대한 링크가있는 중복 질문 http://stackoverflow.com/a/2673800/126229를 참조하십시오. – EricLaw