Why isn't MessageBox TopMost?

北城以北 提交于 2019-12-02 18:45:49
Harsh Baid

To show the MessageBox on top-most of all for the application

Code

//Should be MessageBox.Show() below
MessageBox.Show(this, "My top most message");

Reason for not being MB_TOPMOST by default

If MB_TOPMOST will be default then the MessageBox will show up in a 'system modal' mode and it will be exactly on top on that form and side effects are that the 'system modal' mode will cause the MessageBox to Block the windows until the message is dismissed normally it will be 'application modal' mode.

Reference links

  1. MSDN forum - How to display a MessageBox as topmost window
  2. SO - C# MessageBox To Front When App is Minimized To Tray
Abel

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).

When showing MessageBox provide its owner as the first argument. For example when invoking from a Form instance call:

MessageBox.Show(this, "Message");

Provide a reference to the window owning it as the first argument.

Message boxes (and modal forms in general) do not appear on top of all windows of your application. They only appear on top of their owner. If you want your message-box (or other modal forms) be on top of your splash screen, set their owner to the splash form instance.

Michael Hall

The answer given above is obviously correct minus the fact that it needs to call System.iDisposable.Dispose on the object new Form.

MessageBoxButtons buttons = MessageBoxButtons.YesNo;
MessageBoxIcon icon = MessageBoxIcon.Error;
string message = Resources.ResourceManager.GetString("MESSAGE");
string caption = Resources.ResourceManager.GetString("TITLE");
DialogResult result;
Form form;
using (form = new Form())
{
    form.TopMost = true;
    result = MessageBox.Show(form, caption, message, buttons, icon);
}
if (result == DialogResult.Yes)
{
    // do something with the result
}

For more:

Top-Most-MessageBox Examples

I try to paste a more complete code piece, it's definitely working

    [CLSCompliant(false)]
    [DllImport("user32.dll", EntryPoint = "MessageBox")]
    public static extern int MessageBoxUser32(int hWnd, String text, String caption, uint type);

    const uint MB_TOPMOST = 0x00040000;
    const uint MB_OK  = 0x00000000;
    const uint MB_OKCANCEL = 0x00000001;
    const uint MB_ABORTRETRYIGNORE = 0x00000002;
    const uint MB_YESNOCANCEL = 0x00000003;
    const uint MB_YESNO = 0x00000004;
    const uint MB_RETRYCANCEL = 0x00000005;

     public static void ShowMessageBox(string message, bool topMost = true
        , string title = null, MessageBoxButtons buttons = MessageBoxButtons.OK)
    {
        if(topMost)
        {
            uint mbv = MB_TOPMOST;

            if (buttons == MessageBoxButtons.OK)
                mbv |= MB_OK;
            if (buttons == MessageBoxButtons.OKCancel)
                mbv |= MB_OKCANCEL;
            if (buttons == MessageBoxButtons.AbortRetryIgnore)
                mbv |= MB_ABORTRETRYIGNORE;
            if (buttons == MessageBoxButtons.YesNoCancel)
                mbv |= MB_YESNOCANCEL;
            if (buttons == MessageBoxButtons.YesNo)
                mbv |= MB_YESNO;
            if (buttons == MessageBoxButtons.RetryCancel)
                mbv |= MB_RETRYCANCEL;

            MessageBoxUser32(0, message, title == null ? string.Empty : title, MB_TOPMOST);
        }
        else
        {
            MessageBox.Show(message, title == null ? string.Empty : title, buttons);
        }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!