Realize an automatic closing MessageBox under WinForm
Author: eaglet
Under WinForm, we can call MessageBox.Show to display a message dialog box, prompting the user to confirm and other operations. In some applications, we need to automatically close the message dialog box through the program instead of the user clicking the confirmation button to close it. However. Net framework does not provide us with a method to automatically close the MessageBox, to achieve this function, we need to use the Window API to complete.
First of all, we need to find the window handle of the message dialog box. A relatively simple method is to use the FindWindow API to find the corresponding window handle.
[DllImport(
“
user32.dll
“
, SetLastError
=
true
)]
static
extern
IntPtr FindWindow(
string
lpClassName,
string
lpWindowName);
This API call can find the window handle by the class name of the window or the name of the window title.
Next we need to find an API to close the dialog box, here I use EndDialog
[DllImport(
“
user32.dll
“
)]
static
extern
bool
EndDialog(IntPtr hDlg,
out
IntPtr nResult);
With these two API functions, we can close the message dialog box. The idea is to start a background worker thread before calling MessageBox.Show. This worker thread waits for a certain period of time and starts to search for the window handle of the message dialog box. After finding it, call the EndDialog API function to close the message dialog box. However, there is a problem with this method, that is, if there are multiple message dialog boxes with the same name at the same time (maybe not necessarily for this application), doing so may close the wrong window. How to solve this problem, I have not yet come up with a better way , If you have a better way to solve this problem, you may wish to discuss it together.
I wrote a function to delay closing the message dialog box based on this idea
public
void
ShowMessageBoxTimeout(
string
text,
string
caption,
MessageBoxButtons buttons,
int
timeout)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(CloseMessageBox),
new CloseState(caption, timeout));
MessageBox.Show(text, caption,buttons);
}
The unit of the timeout parameter in this function is milliseconds, and the other parameters have the same meaning as the parameters of MessageBox.Show, and will not be described in detail here.
In this function, first use the thread pool to call a worker thread CloseMessageBox, and pass the title and delay time of the dialog box to the CloseMessageBox function through the CloseState class.
CloseState is defined as follows:
private
class
CloseState
{
privateint _Timeout;
if (dlg != IntPtr.Zero)
{
IntPtr result;
EndDialog(dlg, out result);
}
}
Complete available code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
> using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace _7.messagebox closes automatically
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport(“user32.dll”, SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpW windowName);
[DllImport(“user32.dll”)]
static extern bool EndDialog(IntPtr hDlg, out IntPtr nResult);
public void ShowMessageBoxTimeout(string text, string caption,
> MessageBoxButtons buttons, int timeout)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(CloseMessageBox),
new CloseState(caption, timeout));
MessageBox.Show(text, caption, buttons);
}
private class CloseState
{
private int _Timeout;
/**/
///
///
public int Timeout
{
get
{
return _Timeout;
}
}
private string _Caption;
/**/
///
///
public string Caption
{
get
{
return _Caption;
}
}
public CloseState(string caption, int timeout)
{
_Timeout = timeout;
_Caption = caption;
}
}
private void CloseMessageBox(object st ate)
{
CloseState closeState = state as CloseState;
Thread.Sleep(closeState.Timeout);
IntPtr dlg = FindWindow(null, closeState.Caption);
if (dlg != IntPtr.Zero)
{
IntPtr result;
EndDialog(dlg, out result);
}
}
private void button1_Cl ick(object sender, EventArgs e)
{
ShowMessageBoxTimeout(“text”,”caption”,MessageBoxButtons.OK,1000);
}
}
}
–>
return _Timeout;
}
/**/
///
///
public string Caption
{
get
{
return _Caption;
}
}
public CloseState(string caption, int timeout)
{
_Timeout = timeout;
_Caption = caption;
}
}
private void CloseMessageBox(object st ate)
{
CloseState closeState = state as CloseState;
Thread.Sleep(closeState.Timeout);
IntPtr dlg = FindWindow(null, closeState.Caption);
if (dlg != IntPtr.Zero)
{
IntPtr result;
EndDialog(dlg, out result);
}
}
private void button1_Cl ick(object sender, EventArgs e)
{
ShowMessageBoxTimeout(“text”,”caption”,MessageBoxButtons.OK,1000);
}
}
}
12px; background-color: rgb(255,255,255)”>