views:

92

answers:

1

I am displaying a new Form from one process by passing the Show method the handle of a Form created in another process. I only want this new Form to display above the passed Form, like a MessageBox.

However, this newly launched Form appears above other application windows, despite:

  • Setting Process.WindowStyle.Hidden to the Form-displaying process
  • Overriding the ShowWithoutActivation and CreateParams properties of the Form.
  • Making sure Form.TopMost is not true

I have checked that the window handle is valid from the second process. Focus is not stolen, however.

Process A:
Pass (Form) window handle to a new Process B via the command line

Process B:
Display a new Form using Form.Show(anotherProcessWindowHandle)
+1  A: 

You are battling the rulez of SetForegroundWindow(). Note the long list of "it won't work" in the Remarks section. AllowSetForegroundWindow() is the solution.


To ensure that a window always overlaps another window, display it with the Show() or ShowDialog() override that takes the owner argument. For example:

 using (var dlg = new MyMessageBoxForm(ex.Message)) {
     dlg.ShowDialog(this);
 }

An owned window is always shown on the top of its owner and gets minimized and closed along with its owner.


Making the window of another process the owner of your window is expressly forbidden by the Windows SDK. Windows Forms won't let you do this. There is however an appcompat mode for Windows version 3 apps. Back then, there was no problem doing this, it didn't support threading. P/Invoke SetParent() on your window and pass the window handle of the window from the other process. It breaks the warranty, but tends to work well.

Hans Passant
I want the opposite behavior of SetForegroundWindow, though. Can you elaborate?
Cat
Doesn't compute. You want it in the background, always covered by other windows?
Hans Passant
I want this new Form to behave as a MessageBox of the window (handle) passed to the second process. If the first process/window is in the foreground, then the MessageBox should appear over the window, but if the window is not visible or the area where the MessageBox would appear is occluded, then the MessageBox should not display.
Cat
@Cat, ah, now I know what you mean. I updated my answer.
Hans Passant
I believe that I am doing this already, though. See the pseudo-code of my question.
Cat
@Cat: answer updated again.
Hans Passant
Thank you. I suppose I will have to query the visibility of the existing window before I show the new Form.
Cat