I\'m trying to open \"mspaint\" and find handle of it right after it has been initialized. But FindWindow
returns NULL
if I call WaitForInput
WaitForInputIdle works, but not the way you assume it does. This is largely, because the documentation is misleading (or at least not as explicit as it should be):
Waits until the specified process has finished processing its initial input and is waiting for user input with no input pending, or until the time-out interval has elapsed.
This is almost criminally inaccurate. While the Remarks section notes, that WaitForInputIdle
waits at most once per process, it never mentions significant details. Specifically:
WaitForInputIdle
returns, as soon as the initial startup has come to a point, where any thread in the process is ready to process messages. Those messages need not be user input.WaitForInputIdle
was invented to allow a process to communicate with a child process using a message-based protocol. The specific scenario addressed was DDE, which no one1) uses anymore.WaitForInputIdle
cannot be used as a reliable solution to your problem: Waiting for a child process' UI to show up. You really need to wait for the UI show up.
The system offers two solutions you can use:
HCBT_CREATEWND
callback. You can inspect the CREATESTRUCT's lpszClass and/or lpszName members to filter out the window you are interested in.EVENT_OBJECT_CREATE
event.The global CBT hook is called, whenever a window is about to be created. The kernel structures that the HWND
references have been fully populated, but the client calling CreateWindow[Ex]
may still terminate window creation. In contrast, the WinEvent is issued, after the window has been fully constructed, and is ready for interaction.
In general, a solution based on a CBT hook is used, when an application needs to update certain aspects of a window before the caller of CreateWindowEx
gets to see the HWND
for the first time. WinEvents, instead, are usually the tool of choice when implementing accessibility or UI automation solutions.