为什么不是MessageBox TopMost?

时间:2013-04-19 12:53:45

标签: c# messagebox topmost

我最近发现默认情况下默认情况下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);
}

5 个答案:

答案 0 :(得分:66)

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

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

在这种情况下,您可以使用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)。

答案 1 :(得分:28)

显示MessageBox最重要的应用程序

<强>代码

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

默认情况下不是MB_TOPMOST的原因

  

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

参考链接

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

答案 2 :(得分:3)

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

MessageBox.Show(this, "Message");

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

消息框(以及一般的模态表单) not 出现在应用程序的所有窗口之上。它们只显示在所有者之上。如果您希望将消息框(或其他模式窗体)置于启动画面之上,请将其所有者设置为启动窗体实例。

答案 3 :(得分: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

答案 4 :(得分: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);
        }
    }