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
Why isn't MessageBox TopMost?
提问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 theMessageBoxto Blockthe windows until the message is dismissed normally it will be 'application modal' mode.
如果MB_TOPMOST将默认那么
MessageBox将在“系统模式”的模式出现了,这将是完全对这种形式和副作用顶部是在“系统模式”模式将导致MessageBox以阻止该窗口,直到该消息被驳回通常它将是“应用程序模式”模式。
Reference links
参考链接
回答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:
更多信息:
回答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);
}
}

