Minimizing the request form results in the modal form being closed, but not the MessageBox

If I programmatically minimize the application form while a modal dialog is open, that modal dialog is closed.

However, if I programmatically minimize the application form when the MessageBox is open, the MessageBox does not close (i.e. when I restore the application to its normal window state, the message box is still displayed).

Here's my sample code to demonstrate the difference:

    public partial class Form1 : Form
    {
        // ... 

        private void showMessageBoxBtn_Click(object sender, EventArgs e)
        {
            timer1.Start();

            // This MessageBox does *not* get closed when the WindowState of Form1 is set to minimized in timer1_Tick
            MessageBox.Show(this, "MessageBox");
        }

        private void formShowDialogBtn_Click(object sender, EventArgs e)
        {
            timer1.Start();

            // This form gets closed when the WindowState of Form1 is set to minimized in timer1_Tick
            Form2 form2 = new Form2();
            form2.ShowDialog(); 
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            WindowState = FormWindowState.Minimized;
            timer1.Stop();
        }
    }

      

Question:

Is there a way to make the form behave like a MessageBox?

+3


source to share


5 answers


What you see is a side effect of the countermeasures built into Winforms to address dialog usability issues, countermeasures that the MessageBox () function does not have. They were probably more important to Windows 98, originally an important operating system to Winforms, too long ago for me to remember for sure.

An important usability issue is what happens when you show dialogue and it gets minimized. The dialog box disables all other windows in the application so that you can no longer activate them. The dialog must have the ShowInTaskbar property equal to false. The user now has a problem, there is no easy way to return to the dialog. Do not press anything.

Winforms avoids this trap by automatically closing the dialog. As you can tell, MessageBox doesn't do this. It also can't do it like that, it doesn't have a good way to return the "dialog has been canceled" status code.



Remarkably, this trap still partially exists. On my Win8 machine, I can click the disabled form's taskbar button and force it back to the front. But this will activate the disabled form instead of the message box. The main UI blooper is there and is nasty if the message box is behind this form.

So, to answer your question: no. Feature, not a bug.

+6


source


First, declare the form variable Form2

outside of the method scope, so it can be accessed from the method timer1_tick

. Then when it Timer

ticks, hide the main form, but show the modal dialog and then hide it.

Try the following:



Form2 form2;

private void timer1_Tick(object sender, EventArgs e)
{
    WindowState = FormWindowState.Minimized;
    form2.Show();
    form2.WindowState = FormWindowState.Minimized;
    timer1.Stop();
}

      

+1


source


Matt,

Try to change:

form2.ShowDialog();

      

to

form2.Show(this);

      

Is this the behavior you are looking for?

0


source


You can try something like this:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication37
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
        public static extern IntPtr GetParent(IntPtr hWnd);

        Form2 form2 = null;
        IntPtr parent = IntPtr.Zero;

        public Form1()
        {
            InitializeComponent();
        }

        private void formShowDialogBtn_Click(object sender, EventArgs e)
        {
            timer1.Start();

            // This form gets closed when the WindowState of Form1 is set to minimized in timer1_Tick
            form2 = new Form2();
            form2.ShowDialog();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            WindowState = FormWindowState.Minimized;
            timer1.Stop();
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.parent = GetParent(form2.Handle);
                SetParent(form2.Handle, IntPtr.Zero);
                form2.Hide();
            }
            else
            {
                SetParent(form2.Handle, this.parent);
                form2.ShowDialog();
            }
        }
    }
}

      

Note that this is somewhat of a hack, I'm not entirely sure about the implications. Criticism is acceptable :)

0


source


If you installed

Visible = true;

      

in the modal form immediately after programmatically antialiasing the owner, the modal form will not be destroyed by the OS.

So,

ownerForm.WindowState = FormWindowState.Minimized;

      

will kill the modal form. But

ownerForm.WindowState = FormWindowState.Minimized;
modalForm.Visible = true;

      

will not kill him.

0


source







All Articles