为什么没有消息框最顶层的?(Why isn't MessageBox TopMost?)

2019-08-31 13:28发布

我最近发现,在默认情况下,当消息框默认显示不是最顶端的形式,我想知道是否有人知道任何情况下,当你不希望在其他窗口的顶部显示的消息框?

我发现这个问题的时候,我开始显示启动画面,同时加载应用程序,它看起来像我的程序仍在运行,但有一个MessageBox是在等待输入..闪屏是在不同的线程显示启动画面背后对调用消息框,所以我想这线程就是为什么它没有出现飞溅以上; 但是这仍然不能解释为什么MessageBox中没有MB_TOPMOST默认标志?

编辑

为了更好地澄清:到底我不得不做一些类似的到底做出一个消息,代码是不完全正确的从内存中写道)

[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 1:

为了显示在最上方的所有应用程序的消息框

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

不之所以被MB_TOPMOST默认

如果MB_TOPMOST将默认则MessageBox将在“系统模式”的模式出现了,这将是完全对这种形式和副作用顶部是在“系统模式”模式会导致MessageBox ,以挡住窗户,直到消息通常驳回将是“应用模式”模式。

引用链接

  1. MSDN论坛-如何显示一个MessageBox作为最顶层窗口
  2. SO - C#MessageBox的要接待当应用程序最小化到托盘


Answer 2:

提出的解决方案的工作,如果你能得到一个手柄或参考对话应该出现在顶部的窗口。 然而,这可能并不总是可能或容易实现:

  • 窗外是一个闪屏,不应该紧密结合业务逻辑
  • 通过另一个类或库比当前创建的窗口
  • 窗口是在你的控制,从第三方(本机)库,即

在这种情况下,你可以使用Win232 MessageBox从API User32.dll ,但一个简单的,有管理的解决方案可供选择:

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

代码new Form { TopMost = true }将创建一个隐藏的形式与MB_TOPMOST属性,它是通过在MessageBox对话框窗口继承。 其结果是,它会出现在您的所有其他窗口的顶部。 使用new Form()内联已经没有副作用,没有视觉外观和它通常会通过垃圾收集器被破坏。

注意:如果你不是一个形式里面已经,不要忘了命名空间,这是System.Windows.Forms.MessageBox ,不System.Windows.MessageBox (感谢, USER1 )。



Answer 3:

当示出MessageBox提供其作为第一个参数的所有者。 从调用时,例如Form实例调用:

MessageBox.Show(this, "Message");

提供窗口拥有它作为第一个参数的参考。

消息框(和一般模式表单) 不会出现在您的应用程序的所有窗口的顶部。 他们只出现在其所有者的顶部。 如果你希望你的消息框(或其他模式表单)在你的闪屏的顶部,它们的主人设置为飞溅形式实例。



Answer 4:

上面给出的答案显然是正确减去它需要调用System.iDisposable.Dispose对象新表的事实。

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
}

欲了解更多:

最上面的,MessageBox的例子



Answer 5:

我尝试粘贴一个更完整的一段代码,它肯定工作

    [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);
        }
    }


文章来源: Why isn't MessageBox TopMost?