I'm trying to open "mspaint" and find handle of it right after it has been initialized. But FindWindow
returns NULL
if I call WaitForInputIdle
. If I try to use the function Sleep(1000)
it works. But I don't think it's a right way to wait for the program to be ready. Is there a solution for this code?
CString strWindowDirectory;
GetSystemDirectory(strWindowDirectory.GetBuffer(MAX_PATH), MAX_PATH);
SHELLEXECUTEINFO sei = { 0 };
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.lpVerb = L"open";
sei.lpFile = L"mspaint";
sei.lpDirectory = strWindowDirectory;
sei.nShow = SW_SHOWNORMAL;
HWND hPaint = NULL;
if(ShellExecuteEx(&sei))
{
int r = ::WaitForInputIdle(sei.hProcess, INFINITE);
ATLTRACE(L"WaitForInputIdle %d\n", r);
if (sei.hProcess == NULL) return;
hPaint = ::FindWindow(L"MSPaintApp", NULL);
ATLTRACE(L"Handle %d\n", hPaint);
if (!hPaint) return;
}
else
{
MessageBox(L"Couldn't find mspaint program");
return;
}
::FindWindow
doesn't return null and::Sleep(100);
on each iteration. – Nightjar::WaitForInputIdle
is not working. It's what I've always used without failure. – NightjarSEE_MASK_NOASYNC
and/orSEE_MASK_WAITFORINPUTIDLE
– NightjarShellExecuteEx
msdn.microsoft.com/en-us/library/windows/desktop/… – Nightjar::WaitForInputIdle
is not working. It's what I've always used without failure." - I would strongly suggest that you revisit your code then.WaitForInputIdle
works, as designed. But that is in the majority of the cases not how you'd expect it to work. Unless you are using it for DDE, you are doing it wrong. And using DDE is wrong, too. Details in the answer. – TactWaitForInputIdle
works as documented. It's just hard to read the contract right. It waits for at most one thread for every process, and since you don't control threads the system launches in your process, there's really no way to for you to correlate it's return with a visible UI. If you need to wait for UI being up and running, use the right tool (e.g. WinEvents). – Tact