WM_QUERYENDSESSION メッセージを別のプロセスのウィンドウに送信することはできますか?
質問
作成した Windows C++ アプリケーションをデバッグして、WM_QUERYENDSESSION に対して期待どおりに応答しない理由を確認したいと考えています。明らかに、システムをシャットダウンするだけでこれを行うのは少し難しいです。自分で偽の WM_QUERYENDSESSION をアプリケーション ウィンドウに送信するために使用できるユーティリティまたはコードはありますか?
解決
私が使用したのは、 Win32::GuiTest 過去にこのようなことを行うための Perl モジュール。
他のヒント
これを行うには、Windows API SendMessage を使用できます。http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx
他の実行中のプロセスがゼロで応答したため、応答していない可能性があります (システムを待機させています)。
はい、もちろん可能です。私は数か月前、いくつかの(未知だがおそらく私の)アプリがシャットダウンを妨げる同様の問題に直面したので、EnumWindows を使用してすべてのトップレベルウィンドウを列挙し、それぞれに WM_QUERYENDSESSION メッセージを送信し、戻り値を記録する簡単なコードを書きました。 SendMessage からの値が変更され、誰かが FALSE を返した場合は列挙が停止されました。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_pこれはダイアログの this ポインタの単なるローカル コピーであるため、ヘルパー コールバックはそれにアクセスできます。早くて汚いって言いましたね :-)
はい。ウィンドウ ハンドルを取得できれば (おそらく FindWindow() を使用して)、WPARAM と LPARAM がポインタでない限り、任意のメッセージをそれに送信/投稿できます。