c# messagebox topmost

c# - ¿Por qué no es MessageBox TopMost?



(5)

Al mostrar MessageBox proporcione su propietario como primer argumento. Por ejemplo, al invocar desde una llamada a instancia de Form :

MessageBox.Show(this, "Message");

Proporcione una referencia a la ventana que lo posee como primer argumento.

Los cuadros de mensajes (y los formularios modales en general) no aparecen en la parte superior de todas las ventanas de su aplicación. Solo aparecen encima de su dueño . Si desea que su buzón de mensajes (u otros formularios modales) estén en la parte superior de su pantalla de inicio, establezca su propietario en la instancia de formulario de bienvenida.

Recientemente descubrí que, de manera predeterminada, los cuadros de mensajes no eran los que más se mostraban cuando se mostraban de manera predeterminada y me preguntaba si alguien conocía alguna circunstancia en la que no quisiera que el mensaje se mostrara sobre otras ventanas.

Encontré el problema cuando comencé a mostrar pantallas emergentes mientras cargaba una aplicación, y parecía que mi programa aún se estaba ejecutando, pero había un MessageBox detrás de la pantalla de bienvenida que estaba esperando la entrada .. La pantalla de presentación se mostró en un hilo diferente al hilo que llamó al messagebox así que me imagino que es por eso que no apareció por encima del splash; pero esto todavía no explica por qué MessageBox no tiene el indicador MB_TOPMOST de forma predeterminada?

Editar

Para aclarar mejor: al final tuve que hacer algo similar a esto al final para hacer un cuadro de mensaje, el código no es exactamente correcto, como escribió desde la memoria)

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


Intento pegar un código más completo, definitivamente funciona

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


La respuesta dada anteriormente es obviamente correcta menos el hecho de que necesita llamar a System.iDisposable.Dispose en el objeto new Form.

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 }

Para más:

Ejemplos de Top-Most-MessageBox


Las soluciones propuestas funcionan si puede obtener un identificador o una referencia a la ventana sobre la que se supone que debe aparecer el diálogo. Sin embargo, esto no siempre es posible o fácil de lograr:

  • la ventana es una pantalla de bienvenida y no debe estar estrechamente unida a su lógica comercial
  • la ventana es creada por otra clase o biblioteca que la actual
  • la ventana está fuera de su control, es decir, de una biblioteca de terceros (nativa)

En tales escenarios, puede usar la API Win232 MessageBox desde User32.dll , pero también está disponible una solución administrada más simple:

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

El código new Form { TopMost = true } creará un formulario oculto con la propiedad MB_TOPMOST , que se hereda mediante la ventana de diálogo del cuadro de mensaje. Como resultado, aparecerá en la parte superior de todas sus otras ventanas. Usar el new Form() línea no tiene efectos secundarios, no tiene apariencia visual y se destruirá normalmente a través del recolector de basura.

Nota: si todavía no está dentro de un formulario, no olvide el espacio de nombres, esto es System.Windows.Forms.MessageBox , no System.Windows.MessageBox ! (gracias, user1 ).


Para mostrar el MessageBox en la parte superior de la aplicación

Código

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

Motivo de no ser MB_TOPMOST por defecto

Si MB_TOPMOST será el predeterminado, el MessageBox aparecerá en modo ''sistema modal'' y estará exactamente en la parte superior de ese formulario y los efectos secundarios son que el modo ''sistema modal'' hará que el MessageBox bloquee las ventanas hasta que aparezca el mensaje se descarta normalmente será el modo ''aplicación modal''.

Enlaces de referencia

  1. Foro de MSDN: cómo mostrar un cuadro de mensaje como ventana superior
  2. SO - C # MessageBox al frente cuando la aplicación se minimiza a la bandeja