public class MessageBoxAutoClose { [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] static extern bool EndDialog(IntPtr hDlg, out IntPtr nResult); string _caption; int _timeout; Timer _timer = new Timer(); IntPtr _dlg; private void ShowMessageBoxTimeout(string text, string caption, int timeout) { _caption = caption; _timeout = timeout; _timer.Interval = 1000; _timer.Enabled = true; _timer.Tick += Timer_Tick; ThreadPool.QueueUserWorkItem(new WaitCallback(CloseMessageBox), new CloseState(caption, timeout * 1000)); //这里线程挂起20ms,也可以循环每次挂起10ms new Task(() => { while (_dlg == IntPtr.Zero) { Thread.Sleep(10); _dlg = FindWindow(null, _caption); } ChangeMessageBoxButtonText(_dlg, _timeout); }).Start(); //new Task(() => { Thread.Sleep(20); ChangeMessageBoxButtonText(_dlg, _timeout); }).Start(); DialogResult dialogResult = MessageBox.Show(text, caption, MessageBoxButtons.OK, MessageBoxIcon.Information); if(dialogResult==DialogResult.OK || dialogResult == DialogResult.Cancel) { if (_timer.Enabled) { _timer.Enabled = false; _timer.Dispose(); } } } private void Timer_Tick(object sender, EventArgs e) { ChangeMessageBoxButtonText(_dlg, --_timeout); } private class CloseState { private int _timeout; /// <summary> /// In millisecond /// </summary> public int Timeout { get { return _timeout; } } private string _caption; /// <summary> /// Caption of dialog /// </summary> public string Caption { get { return _caption; } } public CloseState(string caption, int timeout) { _timeout = timeout; _caption = caption; } } private void CloseMessageBox(object state) { CloseState closeState = state as CloseState; Thread.Sleep(closeState.Timeout); if (_timer.Enabled) //如果定时器还在开,说明窗体没有被手动关闭 { IntPtr dlg = FindWindow(null, closeState.Caption); if (dlg != IntPtr.Zero) { IntPtr result; EndDialog(dlg, out result); } _timer.Enabled = false; _timer.Dispose(); } } private void ChangeMessageBoxButtonText(IntPtr dlg, int time) { //IntPtr dlg = FindWindow(null, _caption); IntPtr h = NativeWin32API.GetWindow(dlg, NativeWin32API.GW_CHILD); if (h != IntPtr.Zero) { if (NativeWin32API.GetWindowClassName(h).Equals("Button")) { NativeWin32API.SetWindowText(h, string.Format("关闭({0})", time)); } } } public static void Show(string text, string caption, int timeout) { MessageBoxAutoClose messageBoxAutoClose = new MessageBoxAutoClose(); messageBoxAutoClose.ShowMessageBoxTimeout(text, caption, timeout); } } public class NativeWin32API { public const int GW_CHILD = 5; public const int GW_HWNDNEXT = 2; [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int Width, int Height, int flags); [DllImport("user32.dll")] public static extern IntPtr GetWindow(IntPtr hWnd, int wCmd); [DllImport("user32.dll")] public static extern bool SetWindowText(IntPtr hWnd, string lpString); [DllImport("user32.dll")] public static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount); public static string GetWindowClassName(IntPtr handle) { StringBuilder sb = new StringBuilder(256); GetClassNameW(handle, sb, sb.Capacity); //得到窗口类名并保存在strClass中 return sb.ToString(); } }
效果图: