C# 为什么不是 MessageBox TopMost?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16105097/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 00:01:48  来源:igfitidea点击:

Why isn't MessageBox TopMost?

c#messageboxtopmost

提问by Sayse

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?

我最近发现默认情况下 MessageBoxes 不是默认显示的最上面的表单,我想知道是否有人知道您不希望消息框显示在其他窗口顶部的任何情况?

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 MessageBoxbehind 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_TOPMOSTflag by default?

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

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

采纳答案by Harsh Baid

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

在应用程序的最顶部显示 MessageBox

Code

代码

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

Reason for not being MB_TOPMOSTby default

MB_TOPMOST默认的原因

If MB_TOPMOST will be default then the MessageBoxwill 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 MessageBoxto Blockthe windows until the message is dismissed normally it will be 'application modal' mode.

如果MB_TOPMOST将默认那么MessageBox将在“系统模式”的模式出现了,这将是完全对这种形式和副作用顶部是在“系统模式”模式将导致MessageBox阻止该窗口,直到该消息被驳回通常它将是“应用程序模式”模式。

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
  1. MSDN 论坛 - 如何将 MessageBox 显示为最顶层窗口
  2. SO - 当应用程序最小化到托盘时,C# MessageBox 位于前端

回答by Sina Iravanian

When showing MessageBoxprovide its owner as the first argument. For example when invoking from a Forminstance call:

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

MessageBox.Show(this, "Message");

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

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

Message boxes (and modal forms in general) do notappear 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.

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

回答by 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 coulduse the Win232 MessageBoxAPI from User32.dll, but a simpler, managed solution is also available:

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

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_TOPMOSTproperty, 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.

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

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

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

回答by 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.

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

For more:

更多信息:

Top-Most-MessageBox Examples

Top-Most-MessageBox 示例

回答by Alen Wesker

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