欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Windows API 教程:MessageBox函数详解(原创)

程序员文章站 2022-07-05 14:55:06
...

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);
结果如下:
Windows API 教程:MessageBox函数详解(原创)

图标参数

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

#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);
结果:
Windows API 教程:MessageBox函数详解(原创)
这里我还加了第一个参数: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的原创博客,转载请注明出处!

大家再见!