FormatMessage函數的使用方法


使用FormatMessage時假設對一些參數不細致研究。那么就會出錯誤。首先說下這個函數
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進制,僅僅要其相應的值相等那么錯誤描寫敘述就一樣。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM