
3.5 显示消息对话框
上面所讲的对话框可以添加各种各样的控件,本节介绍一种消息对话框,通常用于向用户显示一段文本字符串信息,上面只有简单的几个按钮,比如“确定”“取消”等。这种对话框的显示非常简单,只需要调用系统API函数:AfxMessageBox或MessageBox,两者功能差不多。但前者只能用在MFC程序中,后者既可用在MFC程序又可以用于Win32 SDK程序。所谓MFC程序,就是要MFC(微软基础类库)这个微软类库支持的程序,它是一种C++程序。Win32 SDK程序指的是仅用SDK(软件开发包)开发出来的Windows程序,它是一种C语言程序。
3.5.1 MessageBox的常见应用
MessageBox是一个Win32 API函数,Win32 API就是Win32 SDK这个开发包中的系统API,用来显示消息的对话框,在不同的场合,它有各种不同的按钮和图标风格可以加以应用,使得界面显得更加人性化。比如,询问用户是否保存,可以让MessageBox带有一个“问号”的图标;如果某用户进行了非法操作,可以用一个“感叹号”来提醒用户。MessageBox的函数原型是:
int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType );
该函数显示一个信息框。其中,hWnd表示拥有该消息框的窗口句柄;lpText表示消息框显示的内容;lpCaption表示消息框显示的标题;uType是图标和按钮的风格组合,常见的uType取值有:
● MB_OK:消息框显示“确定”按钮。
● MB_ABORTRETRYIGNORE:消息框显示“终止”“重试”“忽略”按钮。
● MB_YESNOCANCEL:消息框显示“是”、“否”和“取消”按钮。
● MB_ICONEXCLAMATION:消息框显示感叹号图标。
● MB_ICONQUESTION:消息框显示问号图标。
函数的返回值可以是下列各值:
● IDABORT:用户选择了退出按钮。
● IDCANCEL:用户选择了取消按钮。
● IDCONTINUE:用户选择了继续按钮。
● IDIGNORE:用户选择了忽略按钮。
● IDNO:用户选择了否按钮。
● IDOK:用户选择了OK按钮。
● IDRETRY:用户选择了重试按钮。
● IDTRYAGAIN:用户选择了Try Again按钮。
● IDYES:用户选择了是按钮。
【例3.4】 用MessageBox显示信息框
(1)打开Visual C++ 2013,新建一个对话框工程,工程名是Test。
(2)切换到资源视图,打开对话框编辑器,然后去掉对话框上所有控件,并放置三个按钮,放置按钮后的设计界面如图3-28所示。

图3-28
(3)从上到下依次为3个按钮添加消息函数,第一个按钮的消息函数代码如下:
void CTestDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 MessageBox(_T(" 今天天气不错 , 没有雾霾 "), _T(" 提示 "), MB_OK | MB_ICONINFORMATION); }
其中,_T("")是一个宏,它的作用是让你的程序支持Unicode字符集,关于Unicode字符集的知识可见第1章。如果你编译一个程序使用的是多字节字符集,则_T不起任何作用;而如果编译一个程序使用的是Unicode字符集,则编译器会把程序中的字符串以Unicode方式保存。
第二个按钮的消息函数代码如下:
void CTestDlg::OnBnClickedButton2() { // TODO: 在此添加控件通知处理程序代码 if (MessageBox(_T("你是男孩吗?"), _T("询问"), MB_YESNO | MB_ICONQUESTION) == IDYES) MessageBox(_T("你好,男孩")); else MessageBox(_T("你好,女孩")); }
第三个按钮的消息函数代码如下:
void CTestDlg::OnBnClickedButton3() { // TODO: 在此添加控件通知处理程序代码 int res = MessageBox(_T("安装过程中发生了一个错误,怎么办?"), _T("注意"),MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION); if (res == IDABORT) MessageBox(_T("安装即将终止")); else if (res == IDIGNORE) MessageBox(_T("安装将忽略该错误,继续进行")); else if (res == IDRETRY) MessageBox(_T("安装将重试")); }
(4)保存工程并运行,运行结果如图3-29所示。

图3-29
3.5.2 AfxMessageBox的常见应用
通过上例我们基本了解了MessageBox的用法,但在MFC中,另外一个弹出消息框函数AfxMessageBox使用的更加广泛。
函数AfxMessageBox的2个原型:
int AfxMessageBox( LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0 );
其中,lpszText是要显示字符串的内容;nType是消息框上按钮的类型;nIDHelp表示帮助事件的ID,如果是0,表示使用当前程序的默认帮助。
int AFXAPI AfxMessageBox( UINT nIDPrompt, UINT nType = MB_OK, UINT nIDHelp = (UINT)-1 );
其中,nIDPrompt是当前程序字符串表中的字符串ID号;其他2个参数同上。
函数的返回值可以取下列值:
● IDABORT:用户单击了退出按钮。
● IDCANCEL:用户单击了取消按钮。
● IDIGNORE:用户单击了忽略按钮。
● IDNO:用户选择了否按钮。
● IDOK:用户选择了确定按钮。
● IDRETRY:用户选择了重试按钮。
● IDYES:用户选择了是按钮。
【例3.5】 用Afx MessageBox显示信息框
(1)打开Visual C++ 2013,新建一个对话框工程,工程名是Test。
(2)切换到资源视图,打开对话框编辑器,去掉上面所有按钮,并放置3个按钮,为每个按钮添加一些文字,见图3-30所示:
(3)从上到下,依次为按钮添加事件函数,第一个按钮的代码为:
void CtestDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 if(AfxMessageBox(_T("你是男人吗?"), MB_YESNO)==IDYES) AfxMessageBox(_T("你好,男人!")); else AfxMessageBox(_T("你好,女人!")); }
如果此时运行程序,消息框是带问号的,说明AfxMessageBox只要有MB_YESNO,消息框就会带有问号的,但MessageBox必须要有MB_ICONQUESTION才会出现问号,这也说明AfxMessageBox比MessageBox要设计的人性化一点。
(4)为第二个按钮添加事件函数,代码如下:
void CtestDlg::OnBnClickedButton2() { // TODO: 在此添加控件通知处理程序代码 AfxMessageBox(IDS_MYSTR); }
其中,IDS_MYSTR是在资源视图的字符串表中添加的字符串ID。添加方法为首先切换到资源视图,然后打开String Table,然后在右边空白处右击,选择“新建字符串”来添加2个字符串资源,如图3-31所示。

图3-30

图3-31
其中,IDS_MYSTR在第二个按钮中用到,IDS_MYSTR2在第三个按钮中用到。
(5)上面2个按钮都是静态地显示一个字符串,在第三个按钮中将通过参数的方式(类似printf)来显示字符串,而且参数是和字符串资源ID一起显示出来的,这将要用到AfxFormatString2这个库函数,原型为:
void AfxFormatString2( CString& rString, UINT nIDS, LPCTSTR lpsz1, LPCTSTR lpsz2 );
其中,rString为最终得到的结果;nIDS是在字符串资源中定义的ID,其中里面会有%1和%2用来表示这2个地方用lpsz1和lpsz2来代替;lpsz1和lpsz2是传入的字符串参数。
这样第三个按钮的事件函数代码如下:
void CtestDlg::OnBnClickedButton3() { // TODO: 在此添加控件通知处理程序代码 CString str; CTime t = CTime::GetCurrentTime(); CString str1 = t.Format(_T("%Y%m%d")); CString str2 = t.Format(_T("%H:%M:%S")); AfxFormatString2(str, IDS_MYSTR2, str1, str2); AfxMessageBox(str); }
其中,类CTime是MFC中表示时间和日期的类,函数GetCurrentTime是它的成员函数,表示获取当前日期和时间。
(6)保存工程并运行,运行结果如图3-32所示。

图3-32