By using CreateProcess, I can invoke a new application, and get the process id for the newly created process, but how can I get the handle of the application's main window?
Thanks!!!
Well that's really tricky if you're using C++.
You can use WaitForIdle but that sometimes returns when the splash screen of the launched app is shown, so this does not work in all cases.
A second way but also a much more complicated way is the following.
Use SetWindowsHookEx to create a hook for WH_SHELL.
In your ShellProc handle HSHELL_WINDOWCREATED.
After you've launched your app, start waiting.
For each new window created, your ShellProc will be called.
For each window call GetWindowThreadProcessId(hWnd, &dwProcessID);
Compare the dwProcessID of the newly created window with the processid you got from CreateProces.
If those two processids are equal you've found your window.
NOTE: Even this complicated way does not always work, so make sure you add some kind of timeout in your app, so that you do not keep waiting for your window.
NOTE 2: Try to do as little as possible in your ShellProc because it's called for each new shell-window that is created.
NOTE 3: I'm interested if anyone knows a better way.
Yes, the problem is that a process might create several windows, so you cannot map a processid to just one window, although deep deep down in Windows, there should be something that should make this possible I guess, because in C# you CAN ask for the window after launching an app IIRC.
If I haven't misunderstood the question, then calling "FindWindows", in the main app, would return windows handles of all loaded app/windows, including the caller. Of course you may need to worry about syn issue - the new app. windows spawn by CreateProcess must have been loaded fully.
I tried something similar a while back, but I'm not sure the exact problem we're trying to solve.
Re: How can I get the window handle from process id?
This thread is nearly 8 years old, but saying "EnumWindows is not guaranteed to work" is not the same thing as saying that it will never work. If the main window is the only window for the application, then there is no problem.
Last edited by Sam Hobbs; October 15th, 2011 at 01:46 PM.
Reason: Extraneous word
Re: How can I get the window handle from process id?
There are lots of situations when EnumWindows is "guaranteed not to work" even with a single window. For example, with the process created in foreign session EnumWindows is going to find nothing. The same to window created in current session but another desktop. Etc.
Re: How can I get the window handle from process id?
I guess that is why I stopped participating in CodeGuru. Members have a tendency to insist that something is true without regard for truth.
The truth is that it can work; just because it won't work with some applications does not mean it can never work with other applications.
I think it is misleading comments such as in this thread that caused CodeGuru to be less successful. CodeProject was started by a previous part-owner of CodeGuru (Chris Maunder); correct? And now CodeProject appears in MSDN results. In my oinion, this thread shows some of the reason why CodeProject became more successful.
Re: How can I get the window handle from process id?
Okay, you stopped participating, you decided CG is on its way down. Why be so emotional about the site you don't care of anymore? Or you still do care? Then just admit that your statement "If the main window is the only window for the application, then there is no problem" was not that accurate? Indeed, EnumWindows may work in some situations (as well as FindWindow may do with the same success, by the way) except special cases I mentioned ...with regard for truth.
Re: How can I get the window handle from process id?
I hope, this article can help the OP: Controlling Notepad From C++ Applications
Of course it contains just one approach, not the only one possible and it's not universally applicable.
Bookmarks