原文链接 -> 传送门
函数功能:
FormatsMessate 函数用于格式化一个信息字符串。该函数需要一个消息定义作为输入。该消息定义可能来自能够进入该函数的缓冲区。也可能来自于已经被加载的模块的消息表资源。或者调用者可以调用该函数来搜索该系统消息表资源中的消息定义。该函数在基于消息标识符和语言标识符的消息表资源中查找消息定义。如果有请求,该函数会将格式化消息文本复制到输出缓冲区,并处理任何嵌入的插入序列。
API 函数原型:
注释:_In_ 说明该参数是输入的,_Out_说明该参数是输出的,_In_opt_ 说明该参数是输入同时是可选的。
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 );
参数解析:
|
参数 |
含义 |
||||||||||||||||||||
|
dwFlags |
1. 该参数指定用于格式化的选项、解释 lpsource 参数的方式
|
||||||||||||||||||||
|
lpSource |
1. 该参数表示消息定义的位置。这个参数的类型取决于在 dwFlags 参数中的设置:
|
||||||||||||||||||||
|
dwMessageId |
该参数表示被请求消息的消息标识符。如果 dwFlags 参数包含 FORMAT_MESSAGE_FROM_STRING 标识,那么该参数被忽略 |
||||||||||||||||||||
|
dwLanguageId |
1. 该参数表示被请求消息的语言标识符。如果 dwFlags 参数包含 FORMAT_MESSAGE_FROM_STRING 标识,那么该参数被忽略 1. 中性语言 2. 线程 LANGID,基于线程的区域值 3. 用户默认 LANGID,基于用户的默认区域值 4. 系统默认 LANGID,基于系统的默认区域值 5. 美式英语
|
||||||||||||||||||||
|
lpBuffer |
1. 该参数表示指向接收格式化消息的空终止字符串缓冲区的指针。如果 dwFlags 函数包含 FORMAT_MESSAGE_ALLOCATE_BUFFER 标识,那么该函数会用 LocalAlloc 函数分配一个缓冲区,并且将指针放到该缓冲区中 IpBuffer 函数指定的地址 |
||||||||||||||||||||
|
nSize |
1. 如果没有设置 FORMAT_MESSAGE_ALLOCATE_BUFFER 标识,那么该参数会在 TCHARS 里指定输出缓冲区的大小。如果设置了 FORMAT_MESSAGE_ALLOCATE_BUFFER 标识。该参数指定一个 TCHARs 最小数,用来分配给输出缓冲区 |
||||||||||||||||||||
|
Arguments |
1. 该参数表示用于在格式化消息中作为插入值的一组值。在格式化字符串中的 A%1 表示在 Arguments 字符串中的第一个值,a%2 表示第二个参数,以此类推 |
返回值:
1. 如果函数运行成功,该返回值为储存在输出缓冲区的 TCHARs 的数量,不包括终止空字符;
2. 如果函数运行失败,该返回值为 0。
想要调用更多错误信息,请访问 GetLastError 参数。
备注:
1. 在消息文本中,动态格式消息支持几个转义序列。这些转义序列和它们的含义被显示在下面的表里。所有的转义序列都以百分号(%)开始:
|
参数 |
含义 |
|
%0 |
1. 该转义序列用于终止一个末尾不带有新行字符的消息文本行 |
|
%n!format string! |
1. 该转义序列用于指定一个插入。n 的值可以在 1-99 的范围内。该格式字符串(必须被感叹号包围)是可选择的,并且如果未指定,默认是 !s!。更多信息,请参照 Format Specification Fields 函数 |
2. 任何其它的带有百分号的非数字字符会在输出消息中格式化为不带百分号的字符。以下就是一些例子:
|
格式化字符串 |
输出结果 |
|
%% |
该输出结果为一个单独的百分号 |
|
%space |
该输出结果为一个单独的空白。该格式字符串可以被用于保证一个消息文本行里一定数量的结尾空白 |
|
%. |
该输出结果为一个单独的句号。该格式字符串可以被用于让不带有终止消息文本定义的行开始的地方包含一个单独的句号 |
|
%! |
该输出结果为一个单独的感叹号。该格式字符串可以被用于在一个没有被误认为是一个格式字符串的开始的插入之后立即包括一个感叹号 |
|
%n |
该输出结果为当格式字符串出现在一行的结尾处时的一个硬换行符。当 FormatMessage 函数支持常规换行符时该格式字符串是有用的,这样,消息就符合了一定的宽度 |
|
%r |
该输出结果为一个不带有换行字符的硬回车 |
|
%t |
一个单独的制表键 |
安全备注:
如果该函数在不带有 FORMAT_MESSAGE_IGNORE_INSERTS 标识的情况下被调用,那么 Argument 参数必须包含足够的参数,以满足消息字符串中的所有插入序列。并且这些参数必须是正确的类型。因此不要使用不确定的或未知但可插入的消息字符串,因为它们可能包含比 Arguments 参数可提供的插入序列更多的插入序列。或者这些字符串可能是错误的类型。尤其是,当采用一个从 API 返回的系统错误代码和在不使用 FORMAT_MESSAGE_IGNORE_INSERTS 标识时使用 FORMAT_MESSAGE_FROM_SYSTEM 标识时是不安全的。
例子:
FormatMessage 函数能被用于获取 GetLastError 函数返回的系统错误代码的错误消息字符串。例子请参照 Retrieving the Last-Error Code。
下面的示例展示了如何使用一个参数数组以及如何使用一个宽度和精度说明符:
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
void main(void)
{
LPWSTR pMessage = L"%1!*.*s! %4 %5!*s!";
DWORD_PTR pArgs[] = { (DWORD_PTR)4, (DWORD_PTR)2, (DWORD_PTR)L"Bill", // %1!*.*s! refers back to the first insertion string in pMessage
(DWORD_PTR)L"Bob", // %4 refers back to the second insertion string in pMessage
(DWORD_PTR)6, (DWORD_PTR)L"Bill" }; // %5!*s! refers back to the third insertion string in pMessage
const DWORD size = 100+1;
WCHAR buffer[size];
if (!FormatMessage(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;
}
// Buffer contains " Bi Bob Bill".
wprintf(L"Formatted message: %s\n", buffer);
}
下面的示例展示如何使用 va_list 来实现前一个示例:
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
LPWSTR GetFormattedMessage(LPWSTR pMessage, ...);
void main(void)
{
LPWSTR pBuffer = NULL;
LPWSTR pMessage = L"%1!*.*s! %3 %4!*s!";
// The variable length arguments correspond directly to the format
// strings in pMessage.
pBuffer = GetFormattedMessage(pMessage, 4, 2, L"Bill", L"Bob", 6, L"Bill");
if (pBuffer)
{
// Buffer contains " Bi Bob Bill".
wprintf(L"Formatted message: %s\n", pBuffer);
LocalFree(pBuffer);
}
else
{
wprintf(L"Format message failed with 0x%x\n", GetLastError());
}
}
// Formats a message string using the specified message and variable
// list of arguments.
LPWSTR GetFormattedMessage(LPWSTR pMessage, ...)
{
LPWSTR pBuffer = NULL;
va_list args = NULL;
va_start(args, pMessage);
FormatMessage(FORMAT_MESSAGE_FROM_STRING |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
pMessage,
0,
0,
(LPWSTR)&pBuffer,
0,
&args);
va_end(args);
return pBuffer;
}
需求:
|
Minimum supported client |
Windows XP [桌面应用程序 | Windows 商店应用程序] |
|
Minimum supported server |
Windows 2003 服务器版 [桌面应用程序 | Windows 商店应用程序] |
|
Header |
WinBase.h (包含于 Windows.h) |
|
Library |
Kernel32.lib |
|
DLL |
Kernel32.dll |
|
Unicode and ANSI names |
FormatMessageW (Unicode) 和 FormatMessageA (ANSI) |




