1 函數描寫敘述
DWORD WINAPI FormatMessage( _In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _Out_ LPTSTR lpBuffer, _In_ DWORD nSize, _In_opt_ va_list *Arguments );
<1>dwFlags
格式化選項。這個參數主要用來影響lpSource以及lpBuffer。須要注意的是FORMAT_MESSAGE_ALLOCATE_BUFFER,當指定它的時候。是系統為你分配內存。這個時候的lpBuffer參數須要做一些處理,假設傳遞的是LPSTR buf的話,則傳遞的參數應該是&buf(這里涉及到了函數棧的銷毀問題,在《C++高質量編程中有過》解釋)。假設沒有指定FORMAT_MESSAGE_ALLOCATE_BUFFER的話,那么傳遞的就是一個字符數組。
<2>lpSource
消息定義的位置。依賴於dwFlags的設置,有兩種情況
FORMAT_MESSAGE_FROM_HMODULE:
0x00000800 A handle to the module that contains the message table to search.
FORMAT_MESSAGE_FROM_STRING:
0x00000400 Pointer to a string that consists of unformatted message text. It will be scanned for inserts and formatted accordingly.
假設這兩個都沒有指定的話,那么lpSource參數就會被忽略
<3>dwMessageId
錯誤ID。假設dwFlags中指定了FORMAT_MESSAGE_FROM_STRING,那么該值就會被忽略
<4>dwLanguageId
語言ID,假設假設dwFlags中指定了FORMAT_MESSAGE_FROM_STRING,那么該值就會被忽略。
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) //設置為本地默認語言 MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US) //設置為美語 MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED) //簡體中文
全部的語言宏定義都是在WinNT.h中能夠看到。
<5>lpBuffer
輸出的緩沖區,注意事項在dwFlags中說了,主要是根據FORMAT_MESSAGE_ALLOCATE_BUFFER來對應變化
<6>nSize
輸出緩沖區的大小,假設沒有指定FORMAT_MESSAGE_ALLOCATE_BUFFER,則是緩沖區自身的大小,假設指定了
FORMAT_MESSAGE_ALLOCATE_BUFFER,能夠任意設置,設置為0也沒事。
<7>Arguments
這個參數第一次是用的時候感覺是尤其復雜。這個參數跟dwFlags,lpSource都有關系。所以才是有點復雜。參數類型是va_list*,首先假設參數不是一個va_list*的指針,那么就得在dwFlags中使用FORMAT_MESSAGE_ARGUMENT_ARRAY ,而且傳遞一個DWORD_PTR類型的數組作為參數。
%n!string!的使用方法:
當中n是1-99的整數,假設不加后面的!string!的話就直接表示第一個,第二個參數。以此類推。當加上!string!時,要注意中間的string是有一個*還是有兩個*,在指定FORMAT_MESSAGE_ARGUMENT_ARRAY的時候。一個*則下一個元素是n+2,兩個*的話就是n+3。在沒有指定FORMAT_MESSAGE_ARGUMENT_ARRAY 的情況下,一個*就是n+1,兩個星就是n+2.
比如:
LPWSTR pMessage = L"%1!*.*s! %4 %5!*s!"; DWORD_PTR pArgs[] = { (DWORD_PTR)4, (DWORD_PTR)1, (DWORD_PTR)L"Bill", (DWORD_PTR)L"Bob", (DWORD_PTR)5, (DWORD_PTR)L"Bill" }; const DWORD size = 100+1; WCHAR buffer[size]; if (!FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, pMessage, 0, 0, buffer, size, (va_list*)pArgs)) { wprintf(L"Format message failed with 0x%x\n", GetLastError()); return; }
這里面pArgs的4代表第一個插入元素的寬度,1代表精度(即Bill中的一個元素B)。6代表元素的寬度,每個字符串之間都是以空格為間隔。上面的程序執行得到的buffer就是“ B Bob Bill”
7 再看兩個樣例區分下
<1>
LPSTR buf; LONG x1 = RegCreateKey(HKEY_LOCAL_MACHINE,TEXT("sofware\\VC++MFC\\adminss"),&hKey); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL , x1, MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), (LPTSTR)&buf, 3, NULL); LocalFree(buf);
注意這里buf以及參數dwFlags
<2>
TCHAR buf[100] = {0}; LONG x1 = RegCreateKey(HKEY_LOCAL_MACHINE,TEXT("sofware\\VC++MFC\\adminss"),&hKey); FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL , x1, MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), (LPTSTR)buf, 100, NULL);
注意這里的buf以及參數dwFlags
8 VS提供的查看錯誤的工具
VS,工具-》錯誤查找,就能夠打開錯誤對話框,然后在Key中輸入值就能夠查找錯誤ID相應的文字描寫敘述了。這里的錯誤ID是能夠是10進制,也能夠是16進制,可是無論10進制還是16進制,僅僅要其相應的值相等那么錯誤描寫敘述就一樣。