當使用一個WIN API函數時,它會檢驗參數的有效性,然後再設法去執行任務.如果傳遞了一個無效參數,或者是由於某種原因使程式無法正確執行,那作業系統就會返回一個值,指明該函數在某種程度上運行失敗了.WINDOWS中的函數有5種傳回值類型.
VOID 表示這種函數執行不可能失敗,或者不必關心其失不失敗. WINDOWS函數很少是這種類型. 而我們平時寫代碼中,也應該盡量寫有傳回值的函數,除非你真的確定它中途不會出意外.
BOOL 如果運行失敗它會返回0,如果成功則是非0. 因此,可以通過檢測它的傳回值是0還是非0來判斷一個函數有沒有執行成功. 注意,請不要寫出這樣的代碼 if( ret == TRUE). 這樣做是很不安全的,因為BOOL不僅只有0和1.它在windef.h中被定義, typedef int BOOL;
HANDLE 如果函數失敗,通常返回NULL,否則返回HANDLE值,用於標識你可以操作的一個對象. 但是,某些函數的傳回值則是INVALID_HANDLE_VALUE, 它被定義為 -1 . SDK文檔在介紹每個函數時都說明了其傳回值的含義.用的時候要小心. CreateFile就是這樣的一個函數.
LONG/DWORD 這個值比較難以處理,通常這是一種返回數量的函數.如果由於某種原因,函數無法對想要的進行計數,那反該函數通常返回0或-1 (這也是根據相關函數而定). 用的時候要格外小心.
另外,WINDOWS 中定義了一套錯誤碼列表,用由指明當前API執行後的錯誤資訊. 可以通過GetLastError函數來取得.像這樣.
#include <Windows.h><br />#include <stdio.h></p><p>int main()<br />{<br />//開啟檔案<br />HANDLE hFile = CreateFile("file.txt",0,0,NULL,OPEN_EXISTING,0,NULL);</p><p>DWORD er= GetLastError();</p><p>return 0;<br />}
傳回值 er中便存放了CreateFile調用後,系統記錄的錯誤碼. 並且可們可以看到,hFile的值為INVALID_HANDLE_VALUE。
注意:並不是每個API函數的調用都會更改這個錯誤碼.某些函數在執行成功時就不會修改. 這個要特別注意.
我們可以通過在VC環境下的"監視"視窗中輸入 @err,hr 斷行符號後右邊的資訊視窗中便會顯示出當前錯誤碼對應的資訊提示資訊.
像上面這個列子,我們將斷點設定在 return 0;這一行上,當執行到此後,我們按上面的方法去做. 你會發現監看式視窗中會出現如下提示
@err,hr 0x00000002 系統找不到指定的檔案。
當然,我們也可以通過錯誤碼輸出格式化字串,下面的函數可以做到這一點.
DWORD FormatMessage(
DWORD dwFlags,
LPVOID pSource,
DWORD dwMessageId,
DWROD dwLanguageId,
PTSTR pszBuffer,
DWORD nSize;
va_list *Arguments);
這個函數的功能非常強大,可以在多種語言中進行操作.
#include <Windows.h><br />#include <stdio.h></p><p>int main()<br />{<br />//開啟檔案<br />HANDLE hFile = CreateFile("file.txt",0,0,NULL,OPEN_EXISTING,0,NULL);</p><p>DWORD er= GetLastError();<br />HLOCAL local;<br />CHAR* buffer[256];<br />// FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,NULL,<br />// er,MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),(PTSTR)&local,0,NULL);</p><p>FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,NULL,<br />er,MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),(PTSTR)&local,0,NULL);<br />printf("%s",(PCTSTR)LocalLock(local));<br />getchar();<br />return 0;<br />}<br />
被注釋的部分是用英語輸出,而剛剛都說了,這個東西支援多國語言,於是下面就淙了支援中文的做法。 需要說明的是,這個函數的功能非常多。 剛剛僅是示範了從系統和本地BUFFER中取得錯誤資訊。
#define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100
#define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200
#define FORMAT_MESSAGE_FROM_STRING 0x00000400
#define FORMAT_MESSAGE_FROM_HMODULE 0x00000800
#define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000
#define FORMAT_MESSAGE_ARGUMENT_ARRAY 0x00002000
#define FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF
從它強大的定義可以看出來,支援的東西挺多的。 比如下面的組合:
FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM 則可 以用於網路相關的錯誤。。
同樣的,使用者也可以自己定義錯誤碼。 錯誤碼是一個32位的值。
31-30 位,標誌錯誤的嚴重性。 0 = 成功 1 = 供參考 2 = 警告 3 = 錯誤
29 位,則標誌著錯誤提供者, 0 表示由MS自己提供, 1 表示由使用者提供。所以,使用者自定的代碼,其29位必需為1。
28 位,保留,必須為0。
27-16 位, 由MS公司定義,標誌裝置代碼。
15-0 位,則是異常代碼,MS和客戶均要使用此位。