在Windows的C++编程环境中,处理API出错时的错误代码是一种常见操作。通常API函数出错时会设置Last-Error,及时调用GetLastError()函数可获得其数值,而要获取每个错误代码的具体含义,可将该错误代码传递给FormatMessage()函数,由它为我们查询系统定义的权威说明。
一、FormatMessage()函数
FormatMessage()是一个功能强大的可以定制输出格式的消息处理函数。它可以和scanf()函数一样识别输入字符串中的格式定义字符序列(逃逸序列,Escape Sequence),并按要求格式化输出字符串,使输出字符串满足我们的格式要求,或包含我们给出的参数值。
FormatMessage()的原型如下:
DWORD FormatMessage(
[in] DWORD dwFlags,
[in,optional] LPVOID lpSource,
[in] DWORD dwMessageId,
[in] DWORD dwLanguageId,
[out] LPTSTR lpBuffer,
[in] DWORD nSize,
[in,optional] va_list *Arguments
);
现在介绍一下FormatMessage()函数的用法。直观地来看,它的功能是在某消息定义(由lpSource参数提供,具体含义由dwFlags指定)按消息ID(dwMessageId)和语言ID(dwLanguageId)检索消息,将检索结果放入输出缓冲区(lpBuffer)中,而这个输出缓冲区所使用的存储空间可以由调用者选择是自己提供还是让函数提供,如果是由函数提供,调用者有义务在使用完后将其释放。
如果函数运行成功,返回值为输出缓冲区中TCHAR字符的个数(不含尾部空字符),如果失败则返回0,并设置Last-Error。
1.入口参数
该函数需要一个消息定义作为输入,其中就会包含格式定义字符串序列。该消息定义可以有三种来源,由lpSource入口参数提供,具体是哪一种要看dwFlags的值。它可以是调用者提供的一个包含消息定义的缓冲区,此时lpSource是一个指向该缓冲区的指针,也可以是一个已经被加载的模块(比如DLL)中的消息表资源,此时lpSource是该模块的句柄,还可以是系统提供的消息表资源,此时lpSource被忽略。我们说用FormatMessage()来解释GetLastError()返回的错误代码,就是使用系统提供的消息表资源。lpSource用LPVOID类型可确保灵活性。
dwFlags参数提供了可供使用的选项,还用来规定如何使用lpSource参数。该参数是DWORD类型,它的低位字节用于函数如何处理输出消息中的换行,也可以规定输出消息的最大行宽(每行字符数)。
可以将低位字节设为0,表示不限制行宽,函数会将消息定义中的换行符原样复制到输出消息中;也可以将其设为FORMAT_MESSAGE_MAX_WIDTH_MASK,这时消息定义中的换行符会被忽略,只是将其中明确定义的换行符(以逃逸序列定义的)复制到输出消息。这两种设置均不会产生新的换行符。如果该字节为其他的非零值,则被解释为调用者显式定义的行宽,这时函数会以该行宽为标准在输出缓冲区放置换行符