Why isn't MessageBox TopMost?

Sayse picture Sayse · Apr 19, 2013 · Viewed 58.4k times · Source

I recently found out that by default MessageBoxes were not the top most form when displayed by default and I was wondering if anyone knew any circumstances when you wouldn't want the messagebox to be shown on top of other windows?

I found the issue when I started to show splash screens whilst loading an application, and it looked like my program was still running but there was a MessageBox behind the splash screen that was waiting for input.. The splash screen was shown on a different thread to the thread that called the messagebox so I imagine this is why it didn't appear above the splash; but this still doesn't explain why MessageBox doesn't have the MB_TOPMOST flag by default?

Edit

To better clarify: in the end I had to do something similar to this in the end to make a messagebox, code isn't exactly correct as wrote from memory)

[DllImport("User32.dll")]
private int extern MessageBox(windowhandle, message, caption, flag);
public static void MessageBox(windowhandle, string message, string caption)
{
    MessageBox(windowhandle, message,caption, MB_TOPMOST);
}

Answer

Abel picture Abel · May 18, 2014

The proposed solutions work if you can get a handle or reference to the window the dialog is supposed to appear on top of. However, this may not always be possible or easy to achieve:

  • the window is a splash screen and should not tightly coupled with your business logic
  • the window is created by another class or library than the current one
  • the window is out of your control, i.e. from a third party (native) library

In such scenarios, you could use the Win232 MessageBox API from User32.dll, but a simpler, managed solution is also available:

MessageBox.Show(new Form { TopMost = true }, "Hello, I'm on top!");

The code new Form { TopMost = true } will create a hidden form with the MB_TOPMOST property, which is inherited by the messagebox dialog window. As a result, it will appear on top of all your other windows. Using new Form() inline has no side-effects, has no visual appearance and it will be destroyed normally via the garbage collector.

Note: if you are not inside a form already, don't forget the namespace, this is System.Windows.Forms.MessageBox, not System.Windows.MessageBox! (thanks, user1).