首页 > 代码库 > 详解MessageBox
详解MessageBox
首先,介绍一下MessageBox.Show()参数:
//提示框显示的按钮
public enum MessageBoxButtons { OK = 0x00000000, OKCancel = 0x00000001, AbortRetryIgnore = 0x00000002, YesNoCancel = 0x00000003, YesNo = 0x00000004, RetryCancel = 0x00000005 }
提示框提示的图标
public enum MessageBoxIcon { None = 0, Hand = 0x00000010, Question = 0x00000020, Exclamation = 0x00000030, Asterisk = 0x00000040, Stop = Hand, Error = Hand, Warning = Exclamation, Information = Asterisk, }
提示框默认焦点在第几个按钮上
public enum MessageBoxDefaultButton { Button1 = 0x00000000, Button2 = 0x00000100, Button3 = 0x00000200,
}
//按钮的显示方式
以上这几个枚举是MessageBox最终呈现的效果的设置项,这只是.NET平台提供的设置项,实际上MessageBox显示的样式设置有更多,具体的可以参考windowsAPI MessageBox方法。public enum MessageBoxOptions { ServiceNotification = 0x00200000, DefaultDesktopOnly = 0x00020000, RightAlign = 0x00080000, RtlReading = 0x00100000,}
具体每个枚举值的意义,在VS中都有说明,这里不在赘述。
接下来,我们要介绍MessageBox这个类里边所有的静态方法:
public static DialogResult Show(string text); public static DialogResult Show(IWin32Window owner, string text); public static DialogResult Show(string text, string caption); public static DialogResult Show(IWin32Window owner, string text, string caption); public static DialogResult Show(string text, string caption, MessageBoxButtons buttons); public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons); public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon); public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon); public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton); public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton); public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options); public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options); public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options, bool displayHelpButton); public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options, string helpFilePath); public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options, string helpFilePath); public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options, string helpFilePath, HelpNavigator navigator); public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options, string helpFilePath, string keyword); public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options, string helpFilePath, HelpNavigator navigator); public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options, string helpFilePath, string keyword); public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options, string helpFilePath, HelpNavigator navigator, object param); public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options, string helpFilePath, HelpNavigator navigator, object param);
虽然MessageBox的静态方法有20个之多,但是其实每个方法在内部调用的都是ShowCore方法:
private static DialogResult ShowCore(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options, bool showHelp) {
也就是说,其实这个方法是实现消息框的关键,为了更好的理解.NET实现的原理,我把这个方法基本用C#的格式重新写了一遍,代码如下:
using System;using System.ComponentModel;using System.Runtime.InteropServices;using System.Security;using System.Security.Permissions;using System.Windows.Forms;namespace WindowsFormsApplication1{ class MessageBoxTest { [DllImport("user32.dll")] public static extern IntPtr GetActiveWindow(); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetModuleHandle(string modName); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern IntPtr LoadLibrary(string libname); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, int lParam); private const int HELP_BUTTON = 0x00004000; private const int WM_SETFOCUS = 0x0007;
internal static DialogResult MessageBoxShow(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options, bool showHelp) { if (buttons < MessageBoxButtons.OK || buttons > MessageBoxButtons.RetryCancel) { throw new InvalidEnumArgumentException("buttons", (int)buttons, typeof(MessageBoxButtons)); } if (icon < 0 || icon > MessageBoxIcon.Asterisk) { throw new InvalidEnumArgumentException("icon", (int)icon, typeof(MessageBoxIcon)); } if (defaultButton < 0 || defaultButton > MessageBoxDefaultButton.Button3) { throw new InvalidEnumArgumentException("defaultButton", (int)defaultButton, typeof(MessageBoxDefaultButton)); } //options即不包含MessageBoxOptions.ServiceNotification也不包含MessageBoxOptions.DefaultDesktopOnly //或者当前进程在用户交互模式中运行 if ((options & (MessageBoxOptions.ServiceNotification | MessageBoxOptions.DefaultDesktopOnly)) == 0 && !SystemInformation.UserInteractive) { throw new InvalidOperationException(); } //options包含MessageBoxOptions.ServiceNotification或者包含MessageBoxOptions.DefaultDesktopOnly //但是owner不为空 if (owner != null && (options & (MessageBoxOptions.ServiceNotification | MessageBoxOptions.DefaultDesktopOnly)) != 0) { throw new ArgumentException("options"); } //options包含MessageBoxOptions.ServiceNotification或者包含MessageBoxOptions.DefaultDesktopOnly //但是showHelp位true if (showHelp && (options & (MessageBoxOptions.ServiceNotification | MessageBoxOptions.DefaultDesktopOnly)) != 0) { throw new ArgumentException("options"); } //options包含MessageBoxOptions.ServiceNotification或者包含MessageBoxOptions.DefaultDesktopOnly if ((options & ~(MessageBoxOptions.RightAlign | MessageBoxOptions.RtlReading)) != 0) { CodeAccessPermission permission = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode); permission.Demand(); } CodeAccessPermission safePermission = new UIPermission(UIPermissionWindow.SafeSubWindows); safePermission.Demand();uint style = (showHelp) ? (uint)HELP_BUTTON : 0; style |= (uint)buttons | (uint)icon | (uint)defaultButton | (uint
)options; IntPtr handle = IntPtr.Zero;if (owner == null) { handle = GetActiveWindow(); } else
{ Control control
= owner as Control; handle = control != null ?control.Handle : owner.Handle; } IntPtr userCookie = IntPtr.Zero; if (GetModuleHandle("shell32.dll") == IntPtr.Zero && LoadLibrary("shell32.dll") == IntPtr.Zero) { int lastWin32Error = Marshal.GetLastWin32Error(); throw new Win32Exception(lastWin32Error, "获取动态链接库shell32.dll失败"); } DialogResult result; try { result=
Win32ToDialogResult(MessageBox(handle, text, caption, style)); } finally { SendMessage(new HandleRef(owner, handle), WM_SETFOCUS, 0, 0); } return result; } private const int IDOK = 1; private const int IDCANCEL = 2; private const int IDABORT = 3; private const int IDRETRY = 4; private const int IDIGNORE = 5; private const int IDYES = 6; private const int IDNO = 7; private static DialogResult Win32ToDialogResult(int value) { switch (value) { case IDOK: return DialogResult.OK; case IDCANCEL: return DialogResult.Cancel; case IDABORT: return DialogResult.Abort; case IDRETRY: return DialogResult.Retry; case IDIGNORE: return DialogResult.Ignore; case IDYES: return DialogResult.Yes; case IDNO: return DialogResult.No; default: return DialogResult.No; } } }}
上面这些代码复制粘贴到一个类里边是可以直接编译通过的,我们现在在看上面的方法就简单多了,其实出去微软进行的判断,我们用到有用的就上面我用黄色标记的代码。
尤其是GetActiveWindow(); 这一步,很多人在自己模拟重写MessageBox窗体的时候(自己新建一个窗体,然后添加show重载方法)经常会漏掉这一步(我第一次写的时候就漏掉了).
详解MessageBox
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。