I have two projects which run as separate processes, but belong to the same application:
TMasterMainForm
and TMasterModalForm
)TSlaveForm
)The typical way to use this application is like this:
TMasterMainForm
.TMasterMainForm
.TSlaveForm
.TForm.Handle
of TMasterMainForm
to Slave. (via IPC = WM_COPYDATA)Step 5 is done so that when Slave is closing it can set the foreground window back to TMasterMainForm
. This is done to improve the user experience.
This worked fine until we introduced TMasterModalForm
.
TMasterModalForm
can be started using another button in TMasterMainForm
. It is a separate window, but is shown modal and has the TMasterMainForm
as its explicit popup parent.
Now when the TSlaveForm
is closed the Slave application calls SetForegroundWindow
on the handle of the TMasterMainForm
, but this is not correct anymore since there is a modal form (TMasterModalForm
) on top of it.
So the question is:
How do I manage setting the foreground window in this non trivial situation?
PS: This is a simplified description, the real application is also doing this foreground window stuff the other way around.
You cannot set the foreground window to the master main form because it is disabled. It is disabled because you are showing a modal form whose owner is that main form.
The obvious solution is to set the foreground window to be the modal form rather than the main form. Since your slave app presumably cannot easily know which window is active, you should re-work your IPC to allow the slave app to ask the master app which window is active, and then make that the foreground window.
A more elegant solution would be to let the master app call SetForegroundWindow
. In fact it would probably be simpler just to call Application.BringToFront
from the master process. Of course, the slave process would still need to send a message to the master in order to invoke this. The final piece in the puzzle is dealing with the focus-stealing restrictions but you can do that using AllowSetForegroundWindow
. You need your slave process to call this passing the ID of the master process.