C++ WindowsAPI 教程:MessageBox函數詳解(原創)

本文已經搬家至https://ericnth.cn/c-plus-plus/2020/05/win32-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的原創博客,轉載請註明出處!

大家再見!

本文已經搬家至https://ericnth.cn/c-plus-plus/2020/05/win32-messagebox/,請前往查看獲取最新內容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章