C++ WindowsAPI 教程:MessageBox函数详解

 

Hello大家好,我又回来了!今天,小编想要给大家带来的内容时C++API非常常用的函数之一——MesssageBox
说到MB,相信大多数追求用户界面的,用过几年(不一定要)C++的,应该都会用(仅是作者本人猜测)
本文为EricNTH的原创博客,转载请注明出处!

好了,废话不多说,我们开始!

MessageBox所在头文件:<windows.h>。在<bits/stdc++.h>里没有!没有!没有!

函数原型

//winuser.h 3010-3016行
#define MessageBox __MINGW_NAME_AW(MessageBox)
#define MessageBoxEx __MINGW_NAME_AW(MessageBoxEx)

  WINUSERAPI int WINAPI MessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType);
  WINUSERAPI int WINAPI MessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType);
  WINUSERAPI int WINAPI MessageBoxExA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType,WORD wLanguageId);
  WINUSERAPI int WINAPI MessageBoxExW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType,WORD wLanguageId);

这里就只讲MessageBox,不讲MessageBoxEx了,MessageBoxEx可以参见这篇博客

以后要记住,后缀带Ex的意思是Extension,是扩展的意思。MessageBoxEx扩展的是有关按钮语言的功能。

有关原型,我和大家一行行解释。

#define MessageBox __MINGW_NAME_AW(MessageBox)

//__MINGW_NAME_AW是一个很常见的宏,其定义是:
#if defined(UNICODE)
# define __MINGW_NAME_AW(func) func##W
#else
# define __MINGW_NAME_AW(func) func##A
#endif
//哦,原来,他是决定了是用函数的A形式还是W形式啊!
//那,这两种形式有什么区别呢?
//#if defined(UNICODE)
//说明,定义了UNICODE宏,就用W形式。
//W形式是宽字符(wide)形式,可以包含UNICODE字符。
//而从函数原型中也可以看出,因为一个用的是LPCSTR,另一个用的是LPCWSTR。

##是字符串拼接运算符,仅能用于宏。

你可以通过#ifdef UNICODE来检测是否使用了W版本。
接下来我们就根据A版本讲解。(W版本是类似的)
WINUSERAPI int WINAPI MessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType);

第一个参数(HWND hwnd)

HWND是窗口句柄,决定了对话框所属的窗口。
如果是NULL,则作为一个独立的窗口弹出。
此参数不是很常用,所以一般写NULL就可以了。

第二个参数(LPCSTR lpText)

这个参数是对话框中显示的内容(如:An error happens!),A版本不能有UNICODE字符。

第三个参数(LPCSTR lpCaption)

这个参数是对话框的标题(如:Hint),A版本不能有UNICODE字符。

第四个参数(UINT uType)

此参数极其重要!功能极其强大!
下面小编和大家好好讲讲。

//winuser.h,2972-3008行
#define MB_OK __MSABI_LONG(0x00000000)
#define MB_OKCANCEL __MSABI_LONG(0x00000001)
#define MB_ABORTRETRYIGNORE __MSABI_LONG(0x00000002)
#define MB_YESNOCANCEL __MSABI_LONG(0x00000003)
#define MB_YESNO __MSABI_LONG(0x00000004)
#define MB_RETRYCANCEL __MSABI_LONG(0x00000005)
#define MB_CANCELTRYCONTINUE __MSABI_LONG(0x00000006)
#define MB_ICONHAND __MSABI_LONG(0x00000010)
#define MB_ICONQUESTION __MSABI_LONG(0x00000020)
#define MB_ICONEXCLAMATION __MSABI_LONG(0x00000030)
#define MB_ICONASTERISK __MSABI_LONG(0x00000040)
#define MB_USERICON __MSABI_LONG(0x00000080)
#define MB_ICONWARNING MB_ICONEXCLAMATION
#define MB_ICONERROR MB_ICONHAND
#define MB_ICONINFORMATION MB_ICONASTERISK
#define MB_ICONSTOP MB_ICONHAND
#define MB_DEFBUTTON1 __MSABI_LONG(0x00000000)
#define MB_DEFBUTTON2 __MSABI_LONG(0x00000100)
#define MB_DEFBUTTON3 __MSABI_LONG(0x00000200)
#define MB_DEFBUTTON4 __MSABI_LONG(0x00000300)
#define MB_APPLMODAL __MSABI_LONG(0x00000000)
#define MB_SYSTEMMODAL __MSABI_LONG(0x00001000)
#define MB_TASKMODAL __MSABI_LONG(0x00002000)
#define MB_HELP __MSABI_LONG(0x00004000)
#define MB_NOFOCUS __MSABI_LONG(0x00008000)
#define MB_SETFOREGROUND __MSABI_LONG(0x00010000)
#define MB_DEFAULT_DESKTOP_ONLY __MSABI_LONG(0x00020000)
#define MB_TOPMOST __MSABI_LONG(0x00040000)
#define MB_RIGHT __MSABI_LONG(0x00080000)
#define MB_RTLREADING __MSABI_LONG(0x00100000)
#define MB_SERVICE_NOTIFICATION __MSABI_LONG(0x00200000)
#define MB_SERVICE_NOTIFICATION_NT3X __MSABI_LONG(0x00040000)
#define MB_TYPEMASK __MSABI_LONG(0x0000000F)
#define MB_ICONMASK __MSABI_LONG(0x000000F0)
#define MB_DEFMASK __MSABI_LONG(0x00000F00)
#define MB_MODEMASK __MSABI_LONG(0x00003000)
#define MB_MISCMASK __MSABI_LONG(0x0000C000)

它们全是这个参数的取值。。。
而且还能叠加。。。
得,不说了,不然大家就没有信心了。

注:相同类型的不能叠加,如果不填该类型的任何一项,则默认取值为0x0000000的那一项。
叠加方法:用 位或运算符 | 连接。如:MB_OK|MB_ICONINFORMATION。基本所有API的属性都是这样叠加的。

我先给大家讲几个常用的吧!其它麻烦自行百度(不是作者懒,是我也不全认识啊)

按钮内容参数

如不填写,默认为MB_OK。
#define MB_OK __MSABI_LONG(0x00000000) //确定
#define MB_OKCANCEL __MSABI_LONG(0x00000001) //确定,取消
#define MB_ABORTRETRYIGNORE __MSABI_LONG(0x00000002) //中止,重试,忽略
#define MB_YESNOCANCEL __MSABI_LONG(0x00000003)//是,否,取消
#define MB_YESNO __MSABI_LONG(0x00000004)//是,否
#define MB_RETRYCANCEL __MSABI_LONG(0x00000005)//重试,取消
#define MB_CANCELTRYCONTINUE __MSABI_LONG(0x00000006)//取消,重试,继续

这些全部都是按钮文字的取值。(同一类型不能叠加!切记!)
老实讲,我也没搞懂为什么只有这几种组合

演示:
MessageBox(NULL, "这里是内容", "标题", MB_YESNOCANCEL);
结果如下:
MB_YESNOCANCEL演示

图标参数

如不填写,默认为无图标。

#define MB_ICONHAND __MSABI_LONG(0x00000010)//大叉图标
#define MB_ICONQUESTION __MSABI_LONG(0x00000020)//问号图标
#define MB_ICONEXCLAMATION __MSABI_LONG(0x00000030)//警告图标
#define MB_ICONASTERISK __MSABI_LONG(0x00000040)//倒!(i)图标
#define MB_USERICON __MSABI_LONG(0x00000080)//用户图标
#define MB_ICONWARNING MB_ICONEXCLAMATION//自行理解
#define MB_ICONERROR MB_ICONHAND//自行理解
#define MB_ICONINFORMATION MB_ICONASTERISK//自行理解
#define MB_ICONSTOP MB_ICONHAND//自行理解
以上是所有图标的取值(其实也就5个)

演示:
MessageBox(GetConsoleWindow(), "这里是提示!", "提示", MB_YESNOCANCEL|MB_ICONINFORMATION);
结果:
MB_YESNOCANCEL|MB_ICONINFORMATION演示
这里我还加了第一个参数:HWND hwnd;
值为:GetConsoleWindow()(返回值是当前控制台窗口的句柄)
我截图没截出来,但你可以自行测试,看看是不是该对话框没有作为单独的一个对话框弹出?NO!
还有几个获取窗口句柄的函数:
GetDesktopWindow();
FindWindow(LPCTSTR lpszClassName, LPCTSTRlpszWindowName);(有参数,详情可以参见这位博主的博客。)

其它参数和默认参数

#define MB_DEFBUTTON1 __MSABI_LONG(0x00000000)//默认按第一个按钮
#define MB_DEFBUTTON2 __MSABI_LONG(0x00000100)//默认按第二个按钮
#define MB_DEFBUTTON3 __MSABI_LONG(0x00000200)//默认按第三个按钮
#define MB_DEFBUTTON4 __MSABI_LONG(0x00000300)//默认按第四个按钮
#define MB_TOPMOST __MSABI_LONG(0x00040000)//保持对话框在最上方
提示:默认按按钮指的是,你按下Enter键的话是按哪一个按钮,不是直接帮你按下去【呵呵】
MB_TOPMOST这个参数,就算加上,但碰到某些抢风头的程序(如极域等),还是会被"打压"下去,毕竟,人家一直在设TOPMOST嘛!

返回值

嗨嗨,大家别急着走啊,别忘了,我们对话框不只是为了好看的,还要判断用户按下的是那个按钮啊~

#define IDOK 1
#define IDCANCEL 2
#define IDABORT 3
#define IDRETRY 4
#define IDIGNORE 5
#define IDYES 6
#define IDNO 7
#define IDCLOSE 8
#define IDHELP 9
#define IDTRYAGAIN 10
#define IDCONTINUE 11

#ifndef IDTIMEOUT
#define IDTIMEOUT 32000
#endif

按下的是哪个键,返回的就是ID+xx哦!
比如,我按下了“取消”键,返回的就是IDCANCEL。
至于TIMEOUT,一般是不会的哟~

The end

由于作者比较懒,而一个个截图再裁剪确实费工夫,所以只放了两张图片。不好意思啦~
对话框确实是个好玩的东西,大家没事可以上网搜搜,看看其它几个参数有什么用,可以在评论区里回复我哦!
MessageBox挺好用的,不用手动加载静态库就能用,而且易懂又方便!
还有要记住,第2个参数是内容,第3个参数是标题,别搞反了哟!
好了,今天就到这里,谢谢大家能有耐心看到这里【哈哈】

本文为EricNTH的原创博客,转载请注明出处!

大家再见!

 

posted @ 2020-02-29 10:02  EricNTH  阅读(4983)  评论(0编辑  收藏  举报