作成したWindowsC++アプリケーションをデバッグして、WM_QUERYENDSESSIONに期待どおりに応答しない理由を確認したいと思います。明らかに、システムをシャットダウンするだけでこれを行うのは少し注意が必要です。偽のWM_QUERYENDSESSIONを自分のアプリケーションウィンドウに送信するために使用できるユーティリティまたはコードはありますか?
4 に答える
これには、Windows API SendMessage を使用できます。 http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx
他の実行中のプロセスがゼロで応答したため、応答していない可能性があります (システムを待機させます)。
以前、このようなことを行うためにWin32::GuiTest Perl モジュールを使用したことがあります。
はい、もちろん可能です。数か月前、いくつかの (未知の、しかしおそらく私の) アプリがシャットダウンを妨げていた同様の問題に直面したので、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_pThis は、ダイアログの this ポインターの単なるローカル コピーであったため、ヘルパー コールバックはそれにアクセスできました。私はそれが速くて汚いと言った:-)
はい。ウィンドウ ハンドルを取得できる場合 (おそらく FindWindow() を使用)、WPARAM と LPARAM がポインターでない限り、任意のメッセージを送信/投稿できます。