为什么不是MessageBox TopMost?

问题描述 投票:39回答:5

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

当我开始在加载应用程序时显示启动画面时,我发现了问题,看起来我的程序仍在运行但是在启动画面后面有一个等待输入的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);
}
c# messagebox topmost
5个回答
27
投票

显示MessageBox最重要的应用程序

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

默认情况下不是MB_TOPMOST的原因

如果MB_TOPMOST将是默认值,则MessageBox将以“系统模态”模式显示,并且它将完全位于该表单的顶部,副作用是“系统模态”模式将导致MessageBox阻止窗口直到消息通常被解雇它将是“应用模式”模式。

参考链接

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

65
投票

如果您可以获得对话框应该出现在窗口上的句柄或引用,则建议的解决方案有效。但是,这可能并不总是可能或容易实现:

  • 窗口是一个闪屏,不应该与您的业务逻辑紧密结合
  • 该窗口由另一个类或库创建,而不是当前的类
  • 窗口不受您的控制,即来自第三方(本地)库

在这种情况下,您可以使用MessageBox的Win232 User32.dll API,但也可以使用更简单的托管解决方案:

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

代码new Form { TopMost = true }将使用MB_TOPMOST属性创建一个隐藏的表单,该属性由消息框对话框窗口继承。因此,它将显示在所有其他窗口的顶部。使用new Form()内联没有副作用,没有视觉外观,它将通过垃圾收集器正常销毁。

注意:如果你已经不在表单中,请不要忘记命名空间,这是System.Windows.Forms.MessageBox,而不是System.Windows.MessageBox! (谢谢,user1)。


3
投票

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

MessageBox.Show(this, "Message");

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

消息框(以及一般的模态形式)不会出现在应用程序的所有窗口的顶部。它们只出现在它们的主人之上。如果您希望将消息框(或其他模式窗体)放在启动屏幕的顶部,请将其所有者设置为启动窗体实例。


1
投票

上面给出的答案显然是正确的,因为它需要在对象new Form上调用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
}

更多:

Top-Most-MessageBox Examples


1
投票

我尝试粘贴更完整的代码片段,它肯定有用

    [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);
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.