I have an application that calls some other utility application to set some settings for a particular device. That utility application is called using ShellExecuteEx.
So as not to confuse the user, it would be better to made the window of the utility application modal to my main window. How does one do this?
Things I've tried:
You have two things to simulate: ownership and modality.
To simulate ownership: You need to set the owner of your new child process window to your window. This should alleviate any z ordering issues. Though I don't know if this works from another process. If not then you might have to attach your thread input queues and then call it. Or use some other code injection technique.
SetWindowLong <target window handle>, GWL_HWNDPARENT, <new owner handle>
To simulate modality, I think you are on the right track with EnableWindow and the WaitForSingleObjectEx.
The short answer is that there is no way to seamlessly make a window in thread B modal for a window in thread A, even if the threads are in the same process. If you own the code for both windows, you may be able to come close, but in that case you will achieve much better results for the effort by putting all of your UI in one thread.
If you try to suggest to the user that thread B's window is modal for thread A's, there are a lot of subtle Z-order and activation behaviors you have to get right (as you have noticed) lest you suffer an uncanny-valley effect of sorts, where it's clear to the user that thread B's window is trying to be something it's not and therefore seems broken.
To avoid that, I would take this approach:
This way, if everything proceeds normally and quickly, the interaction may well be seamless, but if something goes wrong with the child process or the Z-order gets changed, etc. it will be clear why the parent process is waiting and what the user needs to do to either cancel or go on with the task he started.
EnableWindow is correct, this is generally how message boxes and other "modal" windows do it. As for zorder changing, you can intercept the WM_WINDOWPOSCHANGING message and set the SWP_NOZORDER flag to prevent the zorder change. Make sure you only do this while you are setting EnableWindow(false).
Just logical suggestion,
Maybe you can create invisible modal form, and from him use the method #1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With