winform 关于Messagebox自动定时关闭和自定义提示框总按钮下文本的有关问题的整理
winform 关于Messagebox自动定时关闭和自定义提示框总按钮上文本的问题的整理
如果要改变Messagebox上按钮的文本和自动关闭Messagebox提示框,一种方法是自定义一个winform窗口模仿替代Messagebox,变通的实现效果,另一种方法是通过调用系统的API来实现,因为C#没有对Messagebox提供相关的关闭方法。
第一种方法(自定义winform窗口实现):
[DllImport("user32.dll", CharSet = CharSet.Auto)] private extern static bool MessageBeep(uint type); [DllImport("Shell32.dll")] public extern static int ExtractIconEx(string libName, int iconIndex, IntPtr[] largeIcon, IntPtr[] smallIcon, int nIcons); private IntPtr[] largeIcon; private IntPtr[] smallIcon; private MyMsgBox newMessageBox; private Label frmTitle; private Label frmMessage; private PictureBox pIcon; private FlowLayoutPanel flpButtons; private Icon frmIcon; private Button btnOK; private Button btnAbort; private Button btnRetry; private Button btnIgnore; private Button btnCancel; private Button btnYes; private Button btnNo; private DialogResult CYReturnButton; /// <summary> /// 对话框图标 /// </summary> public enum MyIcon { Error, Explorer, Find, Information, Mail, Media, Print, Question, RecycleBinEmpty, RecycleBinFull, Stop, User, Warning } /// <summary> /// 对话框上的按钮 /// </summary> public enum MyButtons { AbortRetryIgnore, OK, OKCancel, RetryCancel, YesNo, YesNoCancel } /// <summary> /// 绘制对话框 /// </summary> /// <param name="title">对话框标题</param> private void BuildMessageBox(string title) { newMessageBox = new MyMsgBox(); newMessageBox.Text = title; newMessageBox.Size = new System.Drawing.Size(400, 200); newMessageBox.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; newMessageBox.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; newMessageBox.Paint += new PaintEventHandler(newMessageBox_Paint); newMessageBox.BackColor = System.Drawing.Color.White; TableLayoutPanel tlp = new TableLayoutPanel(); tlp.RowCount = 3; tlp.ColumnCount = 0; tlp.Dock = System.Windows.Forms.DockStyle.Fill; tlp.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 22)); tlp.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); tlp.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50)); tlp.BackColor = System.Drawing.Color.Transparent; tlp.Padding = new Padding(2, 5, 2, 2); frmTitle = new Label(); frmTitle.Dock = System.Windows.Forms.DockStyle.Fill; frmTitle.BackColor = System.Drawing.Color.Transparent; frmTitle.ForeColor = System.Drawing.Color.White; frmTitle.Font = new Font("Tahoma", 9, FontStyle.Bold); frmMessage = new Label(); frmMessage.Dock = System.Windows.Forms.DockStyle.Fill; frmMessage.BackColor = System.Drawing.Color.White; frmMessage.Font = new Font("Tahoma", 9, FontStyle.Regular); frmMessage.Text = "hiii"; largeIcon = new IntPtr[250]; smallIcon = new IntPtr[250]; pIcon = new PictureBox(); ExtractIconEx("shell32.dll", 0, largeIcon, smallIcon, 250); flpButtons = new FlowLayoutPanel(); flpButtons.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft; flpButtons.Padding = new Padding(0, 5, 5, 0); flpButtons.Dock = System.Windows.Forms.DockStyle.Fill; flpButtons.BackColor = System.Drawing.Color.FromArgb(240, 240, 240); TableLayoutPanel tlpMessagePanel = new TableLayoutPanel(); tlpMessagePanel.BackColor = System.Drawing.Color.White; tlpMessagePanel.Dock = System.Windows.Forms.DockStyle.Fill; tlpMessagePanel.ColumnCount = 2; tlpMessagePanel.RowCount = 0; tlpMessagePanel.Padding = new Padding(4, 5, 4, 4); tlpMessagePanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50)); tlpMessagePanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); tlpMessagePanel.Controls.Add(pIcon); tlpMessagePanel.Controls.Add(frmMessage); tlp.Controls.Add(frmTitle); tlp.Controls.Add(tlpMessagePanel); tlp.Controls.Add(flpButtons); newMessageBox.Controls.Add(tlp); } /// <summary> /// 显现对话框 /// </summary> /// <param name="timeout">自动关闭时间,以毫秒为单位,如果设置为0则不自动关闭</param> /// <param name="Message">对话框中显示的提示内容</param> /// <returns></returns> public DialogResult ShowMsg(int timeout, string Message) { if (timeout > 0) { StartTimer(timeout); } BuildMessageBox(""); frmMessage.Text = Message; ShowOKButton(); newMessageBox.ShowDialog(); return CYReturnButton; } /// <summary> /// 显示对话框 /// </summary> /// <param name="timeout">自动关闭时间,以毫秒为单位,如果设置为0则不自动关闭</param> /// <param name="Message">对话框中显示的提示内容</param> /// <param name="Title">对话框的标题</param> /// <returns></returns> public DialogResult ShowMsg(int timeout, string Message, string Title) { if (timeout > 0) { StartTimer(timeout); } BuildMessageBox(Title); frmTitle.Text = Title; frmMessage.Text = Message; ShowOKButton(); newMessageBox.ShowDialog(); return CYReturnButton; } /// <summary> /// 显示对话框 /// </summary> /// <param name="timeout">自动关闭时间,以毫秒为单位,如果设置为0则不自动关闭</param> /// <param name="Message">对话框中显示的提示内容</param> /// <param name="Title">对话框的标题</param> /// <param name="MButtons">对话框中的按钮</param> /// <returns></returns> public DialogResult ShowMsg(int timeout, string Message, string Title, MyButtons MButtons) { if (timeout > 0) { StartTimer(timeout); } BuildMessageBox(Title);
frmTitle.Text = Title;frmMessage.Text = Message;ButtonStatements(MButtons);newMessageBox.ShowDialog();return CYReturnButton;
} /// <summary> /// 显示对话框 /// </summary> /// <param name="timeout">自动关闭时间,以毫秒为单位,如果设置为0则不自动关闭</param> /// <param name="Message">对话框中显示的提示内容</param> /// <param name="Title">对话框的标题</param> /// <param name="MButtons">对话框中的按钮</param> /// <param name="MIcon">对话框中显示的图标</param> /// <returns></returns> public DialogResult ShowMsg(int timeout, string Message, string Title, MyButtons MButtons, MyIcon MIcon) { if (timeout > 0) { StartTimer(timeout); } BuildMessageBox(Title); frmTitle.Text = Title; frmMessage.Text = Message; ButtonStatements(MButtons); IconStatements(MIcon); Image imageIcon = new Bitmap(frmIcon.ToBitmap(), 38, 38); pIcon.Image = imageIcon; newMessageBox.ShowDialog(); return CYReturnButton; } /// <summary> /// OK按钮单击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void btnOK_Click(object sender, EventArgs e) { CYReturnButton = DialogResult.OK; newMessageBox.Dispose(); } /// <summary> /// Abort按钮单击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void btnAbort_Click(object sender, EventArgs e) { CYReturnButton = DialogResult.Abort; newMessageBox.Dispose(); } /// <summary> /// Retry按钮单击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void btnRetry_Click(object sender, EventArgs e) { CYReturnButton = DialogResult.Retry; newMessageBox.Dispose(); } /// <summary> /// Ignore按钮单击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void btnIgnore_Click(object sender, EventArgs e) { CYReturnButton = DialogResult.Ignore; newMessageBox.Dispose(); } /// <summary> /// Cancel按钮单击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void btnCancel_Click(object sender, EventArgs e) { CYReturnButton = DialogResult.Cancel; newMessageBox.Dispose(); } /// <summary> /// YSE按钮单击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void btnYes_Click(object sender, EventArgs e) { CYReturnButton = DialogResult.Yes; newMessageBox.Dispose(); } /// <summary> /// NO按钮单击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void btnNo_Click(object sender, EventArgs e) { CYReturnButton = DialogResult.No; newMessageBox.Dispose(); } /// <summary> /// OK按钮样式 /// </summary> private void ShowOKButton() { btnOK = new Button(); btnOK.Text = "确定"; btnOK.Size = new System.Drawing.Size(80, 25); btnOK.BackColor = System.Drawing.Color.FromArgb(255, 255, 255); btnOK.Font = new Font("Tahoma", 8, FontStyle.Regular); btnOK.Click += new EventHandler(btnOK_Click); flpButtons.Controls.Add(btnOK); } /// <summary> /// Abort按钮样式 /// </summary> private void ShowAbortButton() { btnAbort = new Button(); btnAbort.Text = "中止"; btnAbort.Size = new System.Drawing.Size(80, 25); btnAbort.BackColor = System.Drawing.Color.FromArgb(255, 255, 255); btnAbort.Font = new Font("Tahoma", 8, FontStyle.Regular); btnAbort.Click += new EventHandler(btnAbort_Click); flpButtons.Controls.Add(btnAbort); } /// <summary> /// Retry按钮样式 /// </summary> private void ShowRetryButton() { btnRetry = new Button(); btnRetry.Text = "重试"; btnRetry.Size = new System.Drawing.Size(80, 25); btnRetry.BackColor = System.Drawing.Color.FromArgb(255, 255, 255); btnRetry.Font = new Font("Tahoma", 8, FontStyle.Regular); btnRetry.Click += new EventHandler(btnRetry_Click); flpButtons.Controls.Add(btnRetry); } /// <summary> /// Ignore按钮样式 /// </summary> private void ShowIgnoreButton() { btnIgnore = new Button(); btnIgnore.Text = "忽略"; btnIgnore.Size = new System.Drawing.Size(80, 25); btnIgnore.BackColor = System.Drawing.Color.FromArgb(255, 255, 255); btnIgnore.Font = new Font("Tahoma", 8, FontStyle.Regular); btnIgnore.Click += new EventHandler(btnIgnore_Click); flpButtons.Controls.Add(btnIgnore); } /// <summary> /// Cancel按钮样式 /// </summary> private void ShowCancelButton() { btnCancel = new Button(); btnCancel.Text = "取消"; btnCancel.Size = new System.Drawing.Size(80, 25); btnCancel.BackColor = System.Drawing.Color.FromArgb(255, 255, 255); btnCancel.Font = new Font("Tahoma", 8, FontStyle.Regular); btnCancel.Click += new EventHandler(btnCancel_Click); flpButtons.Controls.Add(btnCancel); } /// <summary> /// Yes按钮样式 /// </summary> private void ShowYesButton() { btnYes = new Button(); btnYes.Text = "是"; btnYes.Size = new System.Drawing.Size(80, 25); btnYes.BackColor = System.Drawing.Color.FromArgb(255, 255, 255); btnYes.Font = new Font("Tahoma", 8, FontStyle.Regular); btnYes.Click += new EventHandler(btnYes_Click); flpButtons.Controls.Add(btnYes); } /// <summary> /// No按钮样式 /// </summary> private void ShowNoButton() { btnNo = new Button(); btnNo.Text = "否"; btnNo.Size = new System.Drawing.Size(80, 25); btnNo.BackColor = System.Drawing.Color.FromArgb(255, 255, 255); btnNo.Font = new Font("Tahoma", 8, FontStyle.Regular); btnNo.Click += new EventHandler(btnNo_Click); flpButtons.Controls.Add(btnNo); } /// <summary> /// 对话框中添加按钮 /// </summary> /// <param name="MButtons">要添加的按钮(MyButtons枚举)</param> private void ButtonStatements(MyButtons MButtons) { if (MButtons == MyButtons.AbortRetryIgnore) { ShowIgnoreButton(); ShowRetryButton(); ShowAbortButton(); } if (MButtons == MyButtons.OK) { ShowOKButton(); } if (MButtons == MyButtons.OKCancel) { ShowCancelButton(); ShowOKButton(); } if (MButtons == MyButtons.RetryCancel) { ShowCancelButton(); ShowRetryButton(); } if (MButtons == MyButtons.YesNo) { ShowNoButton(); ShowYesButton(); } if (MButtons == MyButtons.YesNoCancel) { ShowCancelButton(); ShowNoButton(); ShowYesButton(); } } /// <summary> /// 对话框中添加图标 /// </summary> /// <param name="MIcon">要添加的图标(MyIcon枚举)</param> private void IconStatements(MyIcon MIcon) { if (MIcon == MyIcon.Error) { MessageBeep(30); frmIcon = Icon.FromHandle(largeIcon[109]); } if (MIcon == MyIcon.Explorer) { MessageBeep(0); frmIcon = Icon.FromHandle(largeIcon[220]); } if (MIcon == MyIcon.Find) { MessageBeep(0); frmIcon = Icon.FromHandle(largeIcon[22]); } if (MIcon == MyIcon.Information) { MessageBeep(0); frmIcon = Icon.FromHandle(largeIcon[221]); } if (MIcon == MyIcon.Mail) { MessageBeep(0); frmIcon = Icon.FromHandle(largeIcon[156]); } if (MIcon == MyIcon.Media) { MessageBeep(0); frmIcon = Icon.FromHandle(largeIcon[116]); } if (MIcon == MyIcon.Print) { MessageBeep(0); frmIcon = Icon.FromHandle(largeIcon[136]); } if (MIcon == MyIcon.Question) { MessageBeep(0); frmIcon = Icon.FromHandle(largeIcon[23]); } if (MIcon == MyIcon.RecycleBinEmpty) { MessageBeep(0); frmIcon = Icon.FromHandle(largeIcon[31]); } if (MIcon == MyIcon.RecycleBinFull) { MessageBeep(0); frmIcon = Icon.FromHandle(largeIcon[32]); } if (MIcon == MyIcon.Stop) { MessageBeep(0); frmIcon = Icon.FromHandle(largeIcon[27]); } if (MIcon == MyIcon.User) { MessageBeep(0); frmIcon = Icon.FromHandle(largeIcon[170]); } if (MIcon == MyIcon.Warning) { MessageBeep(30); frmIcon = Icon.FromHandle(largeIcon[217]); } } void newMessageBox_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; Rectangle frmTitleL = new Rectangle(0, 0, (newMessageBox.Width / 2), 22); Rectangle frmTitleR = new Rectangle((newMessageBox.Width / 2), 0, (newMessageBox.Width / 2), 22); Rectangle frmMessageBox = new Rectangle(0, 0, (newMessageBox.Width - 1), (newMessageBox.Height - 1)); LinearGradientBrush frmLGBL = new LinearGradientBrush(frmTitleL, Color.FromArgb(87, 148, 160), Color.FromArgb(209, 230, 243), LinearGradientMode.Horizontal); LinearGradientBrush frmLGBR = new LinearGradientBrush(frmTitleR, Color.FromArgb(209, 230, 243), Color.FromArgb(87, 148, 160), LinearGradientMode.Horizontal); Pen frmPen = new Pen(Color.FromArgb(63, 119, 143), 1); g.FillRectangle(frmLGBL, frmTitleL); g.FillRectangle(frmLGBR, frmTitleR); g.DrawRectangle(frmPen, frmMessageBox); } private void StartTimer(int interval) { Timer timer = new Timer(); timer.Interval = interval; timer.Tick += new EventHandler(Timer_Tick); timer.Enabled = true; } private void Timer_Tick(object sender, EventArgs e) { newMessageBox.Close(); //停止计时器 ((Timer)sender).Enabled = false; }
第二种方法(调用API实现):
1、实现定时关闭Messagebox,通过Messagebox对话框的标题查找相应的句柄来进行关闭操作
public class MessageBoxTimeOut { private string _caption; private string username; private string pwd; public DialogResult Show(int timeout, string text, string caption, MessageBoxButtons buttons) { this._caption = caption; StartTimer(timeout); DialogResult dr = MessageBox.Show(text, caption, buttons, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1); return dr; } private void StartTimer(int interval) { Timer timer = new Timer(); timer.Interval = interval; timer.Tick += new EventHandler(Timer_Tick); timer.Enabled = true; } private void Timer_Tick(object sender, EventArgs e) { KillMessageBox(); //停止计时器 ((Timer)sender).Enabled = false; } [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; public void KillMessageBox() { //查找MessageBox的弹出窗口,注意对应标题 IntPtr ptr = FindWindow(null, this._caption); if (ptr != IntPtr.Zero) { //查找到窗口则关闭 PostMessage(ptr, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); } } }
2、关闭Messagebox对话框中按钮的文本文字
public class MessageBoxManager { private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam); private delegate bool EnumChildProc(IntPtr hWnd, IntPtr lParam); private const int WH_CALLWNDPROCRET = 12; private const int WM_DESTROY = 0x0002; private const int WM_INITDIALOG = 0x0110; private const int WM_TIMER = 0x0113; private const int WM_USER = 0x400; private const int DM_GETDEFID = WM_USER + 0; private const int MBOK = 1; private const int MBCancel = 2; private const int MBAbort = 3; private const int MBRetry = 4; private const int MBIgnore = 5; private const int MBYes = 6; private const int MBNo = 7; [DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll")] private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); [DllImport("user32.dll")] private static extern int UnhookWindowsHookEx(IntPtr idHook); [DllImport("user32.dll")] private static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", EntryPoint = "GetWindowTextLengthW", CharSet = CharSet.Unicode)] private static extern int GetWindowTextLength(IntPtr hWnd); [DllImport("user32.dll", EntryPoint = "GetWindowTextW", CharSet = CharSet.Unicode)] private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int maxLength); [DllImport("user32.dll")] private static extern int EndDialog(IntPtr hDlg, IntPtr nResult); [DllImport("user32.dll")] private static extern bool EnumChildWindows(IntPtr hWndParent, EnumChildProc lpEnumFunc, IntPtr lParam); [DllImport("user32.dll", EntryPoint = "GetClassNameW", CharSet = CharSet.Unicode)] private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); [DllImport("user32.dll")] private static extern int GetDlgCtrlID(IntPtr hwndCtl); [DllImport("user32.dll")] private static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem); [DllImport("user32.dll", EntryPoint = "SetWindowTextW", CharSet = CharSet.Unicode)] private static extern bool SetWindowText(IntPtr hWnd, string lpString); [StructLayout(LayoutKind.Sequential)] public struct CWPRETSTRUCT { public IntPtr lResult; public IntPtr lParam; public IntPtr wParam; public uint message; public IntPtr hwnd; }; private static HookProc hookProc; private static EnumChildProc enumProc; [ThreadStatic] private static IntPtr hHook; [ThreadStatic] private static int nButton; /// <summary> /// OK text /// </summary> public static string OK = "&OK"; /// <summary> /// Cancel text /// </summary> public static string Cancel = "&Cancel"; /// <summary> /// Abort text /// </summary> public static string Abort = "&Abort"; /// <summary> /// Retry text /// </summary> public static string Retry = "&Retry"; /// <summary> /// Ignore text /// </summary> public static string Ignore = "&Ignore"; /// <summary> /// Yes text /// </summary> public static string Yes = "&Yes"; /// <summary> /// No text /// </summary> public static string No = "&No"; static MessageBoxManager() { hookProc = new HookProc(MessageBoxHookProc); enumProc = new EnumChildProc(MessageBoxEnumProc); hHook = IntPtr.Zero; } public static void Register() { if (hHook != IntPtr.Zero) throw new NotSupportedException("One hook per thread allowed."); hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, hookProc, IntPtr.Zero, AppDomain.GetCurrentThreadId()); } public static void Unregister() { if (hHook != IntPtr.Zero) { UnhookWindowsHookEx(hHook); hHook = IntPtr.Zero; } } private static IntPtr MessageBoxHookProc(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode < 0) return CallNextHookEx(hHook, nCode, wParam, lParam); CWPRETSTRUCT msg = (CWPRETSTRUCT)Marshal.PtrToStructure(lParam, typeof(CWPRETSTRUCT)); IntPtr hook = hHook; if (msg.message == WM_INITDIALOG) { int nLength = GetWindowTextLength(msg.hwnd); StringBuilder className = new StringBuilder(10); GetClassName(msg.hwnd, className, className.Capacity); if (className.ToString() == "#32770") { nButton = 0; EnumChildWindows(msg.hwnd, enumProc, IntPtr.Zero); if (nButton == 1) { IntPtr hButton = GetDlgItem(msg.hwnd, MBCancel); if (hButton != IntPtr.Zero) SetWindowText(hButton, OK); } } } return CallNextHookEx(hook, nCode, wParam, lParam); } private static bool MessageBoxEnumProc(IntPtr hWnd, IntPtr lParam) { StringBuilder className = new StringBuilder(10); GetClassName(hWnd, className, className.Capacity); if (className.ToString() == "Button") { int ctlId = GetDlgCtrlID(hWnd); switch (ctlId) { case MBOK: SetWindowText(hWnd, OK); break; case MBCancel: SetWindowText(hWnd, Cancel); break; case MBAbort: SetWindowText(hWnd, Abort); break; case MBRetry: SetWindowText(hWnd, Retry); break; case MBIgnore: SetWindowText(hWnd, Ignore); break; case MBYes: SetWindowText(hWnd, Yes); break; case MBNo: SetWindowText(hWnd, No); break; } nButton++; } return true; } }