若 Windows API 函數返回了錯誤值 ( 如 NULL),則可以調用 API 函數 GetLastError 來獲取該錯誤的更多信息。該函數用 EAX 返回 32 位整數錯誤碼:
.datamessageId DWORD ?.codecall GetLastErrormov messageId,eax
MS-Windows 有大量的錯誤碼,因此,程序員可能希望得到一個消息字符串來對錯誤進行說明。要想達到這個目的,就調用函數 FormatMessage:
FormatMessage PROTO, ;格式化消息 dwFlags:DWORD, ;格式化選項 lpSource:DWORD, ;消息定義的位置 dwMsgID:DWORD, ;消息標識符 dwLanguageID:DWORD, ;語言標識符 lpBuffer:PTR BYTE, ;緩衝區接收字符串指針 nSize:DWORD, ;緩衝區大小 va_list: DWORD ;參數列表指針
該函數的參數有點複雜,程序員需要閱讀 SDK 文檔來了解全部信息。下面簡要列出了最常用的參數值。除了 lpBuffer 是輸出參數外,其他都是輸入參數:
1) dwFlags
保存格式化選項的雙字整數,包括如何解釋參數 lpSource。它規定怎樣處理換行,以及格式化輸出行的最大寬度。建議值爲
FORMAT_MESSAGE_ALLOCATE_BUFFER 和 FORMAT_MESSAGE_FROM_SYSTEM。
2) lpSource
消息定義位置的指針。若按照建議值設置 dwFlags,則 lpSource 設置爲 NULL(0)。
3) dwMsgID
調用 GetLastError 後返回的雙字整數。
4) dwLanguageID
語言標識符。若將其設置爲 0,則消息爲語言無關,否則將對應於用戶的默認語言環境。
5) lpBuffer( 輸出參數 )
接收空字節結束消息字符串的緩衝區指針。如果使用了
FORMAT_MESSAGE_ALLOCATE_BUFFER
選項,則會自動分配緩衝區。
6) nSize
用於指定一個緩衝區來保存消息字符串。如果 dwFlags 使用了上述建議選項,則該參數可以設置爲 0。
7) va_list
數組指針,該數組包含了可以插入到格式化消息的值。由於沒有格式化錯誤消息,這個參數可以爲 NULL(0)。
FormatMessage 的示例調用如下:
.datamessageId DWORD ?pErrorMsg DWORD ? ;指向錯誤消息.codecall GetLastErrormov messageId,eaxINVOKE FormatMessage, FORMAT_MESSAGE_ALLOCATE_BUFFER + \ FORMAT_MESSAGE_FROM_SYSTEM, NULL, messagelD, 0, ADDR pErrorMsg, 0, NULL
調用 FormatMessage 後,再調用 LocalFree 來釋放由 FormatMessage 分配的存儲空間:
INVOKE LocalFree, pErrorMsg
WriteWindowsMsg
Irvine32 鏈接庫有如下 WriteWindowsMsg 程,它封裝了消息處理的細節:
;----------------------------------------------------WriteWindowsMsg PROC USES eax edx;; 顯示包含 MS-Windows 最新生成的錯誤字符串; 接收: 無; 返回: 無;----------------------------------------------------.dataWriteWindowsMsg_1 BYTE "Error ",0WriteWindowsMsg_2 BYTE ": ",0pErrorMsg DWORD ? ; 指向錯誤消息messageId DWORD ?.code call GetLastError mov messageId,eax; 顯示錯誤號 mov edx,OFFSET WriteWindowsMsg_1 call WriteString call WriteDec ; show error number mov edx,OFFSET WriteWindowsMsg_2 call WriteString; 獲取相應的消息字符串 INVOKE FormatMessage, FORMAT_MESSAGE_ALLOCATE_BUFFER + \ FORMAT_MESSAGE_FROM_SYSTEM, NULL, messageID, NULL, ADDR pErrorMsg, NULL, NULL; 顯示 MS-Windows 生成的錯誤消息 mov edx,pErrorMsg call WriteString; 釋放錯誤消息字符串的空間 INVOKE LocalFree, pErrorMsg retWriteWindowsMsg ENDP