我们都知道,MessageBox弹出的窗口是模式窗口,模式窗口会自动阻塞父线程的。所以如果有以下代码:
MessageBox.Show("内容',"标题");
则只有关闭了MessageBox的窗口后才会运行后续的代码。
而在某些场合下,我们又需要在一定时间内如果在用户还没有关闭窗口时能自动关闭掉窗口而避免程序一直停留不前。这样的话我们怎么做呢?
上面也说了,MessageBox弹出的模式窗口会先阻塞掉它的父级线程。所以我们可以考虑在MessageBox前先增加一个用于“杀”掉MessageBox窗口的线程。
因为需要在规定时间内“杀”掉窗口,所以我们可以直接考虑使用Timer类,然后调用系统API关闭窗口。
核心代码如下
[DllImport("user32.dll", EntryPoint = "FindWindow", CharSet=CharSet.Auto)]
private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern int PostMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
public const int WM_CLOSE = 0x10;
/// 标题
private string Title;
///定时器启动
private void StartKiller(int timeout)
{
Timer timer = new Timer();
timer.Interval = timeout; //X秒后运行事件
timer.Tick += new EventHandler(Timer_Tick);
timer.Start();
}
///定时执行的事件
private void Timer_Tick(object sender, EventArgs e)
{
KillMessageBox();
//停止计时器
((Timer)sender).Stop();
}
///杀 掉窗口进程的方法
private void KillMessageBox()
{
//查找MessageBox的弹出窗口,注意MessageBox对应的标题Title
IntPtr ptr = FindWindow(null,"Title");
if(ptr != IntPtr.Zero)
{
//查找到窗口则关闭
PostMessage(ptr,WM_CLOSE,IntPtr.Zero,IntPtr.Zero);
}
}
在需要的地方先调用 StartKiller 方法再使用Messagebox.Show()方法即可达到自动关闭 MessageBox 的效果。
Title=megtitle;
StartTimer(timeout);
MessageBox.Show(text, megtitle);
以上是基础的调用,如果需要用到弹窗的其它属性,需要再单独封装方法:
/// <summary>
/// 显示消息框
/// </summary>
/// <param name="text">消息内容</param>
/// <param name="caption">标题</param>
/// <param name="timeout">超时时间,单位:毫秒</param>
/// <param name="buttons">消息框上的按钮</param>
/// <param name="icon">消息框上的图标</param>
public static void Show(string text, string caption, int timeout, MessageBoxButtons buttons, MessageBoxIcon icon)
{
Title = caption;
StartTimer(timeout);
MessageBox.Show(text, caption, buttons, icon);
}