Home > Mobile >  How to close MessageBox automatically after a couple of seconds without using definition of the Auto
How to close MessageBox automatically after a couple of seconds without using definition of the Auto

Time:11-29

I've got stuck with automatical closing of the MessageBox after expiration of the timer. I use static variable of type Timer(not System.Windows.Forms.Timer) which is defined in the special class(definition of the class is not static).

Timer is calling with the help of the reference to name of the class because of static keyword. My class where this timer defined as static called Helper. So the calling I produce using next code

Helper.timer.Interval = 300000;
Helper.timer.Enable = true;

timer is the name of this variable

The task is to handle time when the MessageBox appeared and after the time expiry, close this MessageBox automatically if none of the buttons inside it weren't clicked. Is it possible to do this operation without using and defining AutoClosingMessageBox class like I've seen in the simular questions?

I've got tried some of methods including checking whether user clicked some of the buttons of MessageBox but it didn't give me a required result.

I would be grateful if someone could show me the realization :) If it's required I can fill up the question with the code template of my whole project. This all I need to create on the C# programming language.

Thanks in advance!

CodePudding user response:

Would this link help you?

This link imports and implements "User32.dll" for automatic closing of message boxes. User32.dll is a library that provides functions for controlling items such as windows or menus in the OS.

If the time is exceeded, you can obtain the handle of the message box through "FindWindow" and then close the message box through "SendMessage".

I wrote a simple example program referring to the contents of the link.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private Timer CloseTimer { get; } = new Timer();
    private string Caption { get; set; }

    private void Form1_Load(object sender, EventArgs e)
    {
        CloseTimer.Tick  = CloseTimerOnTick;
        CloseTimer.Interval = 100;
    }

    private void CloseTimerOnTick(object sender, EventArgs e)
    {
        // find window
        var mbWnd = FindWindow("#32770", Caption);
        // check window
        if (mbWnd == IntPtr.Zero)
        {
            // stop timer
            CloseTimer.Enabled = false;
        }
        else
        {
            // check timeout
            if ((DateTime.Now - Time).TotalMilliseconds < Timeout)
                return;
            // close
            SendMessage(mbWnd, 0x0010, IntPtr.Zero, IntPtr.Zero);
            // stop timer
            CloseTimer.Enabled = false;
        }
    }

    private void btMessage_Click(object sender, EventArgs e)
    {
        Show(@"Caption", @"Auto close message", 3000);
    }

    private void Show(string caption, string message, int timeout)
    {
        // start
        CloseTimer.Enabled = true;
        // set timeout
        Timeout = timeout;
        // set time
        Time = DateTime.Now;
        // set caption
        Caption = caption;
        // show 
        MessageBox.Show(message, Caption);
    }

    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
}

CodePudding user response:

One approach that has worked for me is to create a temporary (invisible) window to host the MessageBox. This temporary window is passed as the owner argument to the Show method. When the owner Form is disposed after awaiting the Task.Delay then the message box should dispose also.

public MainForm()
{
    InitializeComponent();
    buttonHelp.Click  = onHelp;
}

private async void onHelp(object sender, EventArgs e)
{
    var owner = new Form { Visible = false };
    // Force the creation of the window handle.
    // Otherwise the BeginInvoke will not work.
    var handle = owner.Handle;
    owner.BeginInvoke((MethodInvoker)delegate 
    {
        MessageBox.Show(owner, text: "Help message", "Timed Message");
    });
    await Task.Delay(TimeSpan.FromSeconds(2));
    owner.Dispose();
}
  • Related