GetLastError返回数字错误代码。要获取描述性错误消息(例如,显示给用户),可以调用FormatMessage:
// 此函数填充调用者定义的字符缓冲区(pBuffer)
// 最大长度(cchBufferLength)与人类可读的错误消息
// Win32错误代码(dwErrorCode)。
//
// 如果成功,则返回TRUE,否则返回FALSE。
// 如果成功,则保证pBuffer为NUL终止。
// 失败时,pBuffer的内容未定义。
BOOL GetErrorMessage(DWORD dwErrorCode, LPTSTR pBuffer, DWORD cchBufferLength)
{
if (cchBufferLength == 0)
{
return FALSE;
}
DWORD cchMsg = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, /* (not used with FORMAT_MESSAGE_FROM_SYSTEM) */
dwErrorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
pBuffer,
cchBufferLength,
NULL);
return (cchMsg > 0);
}在C ++中,可以通过使用std::string类来大大简化接口:
#include <Windows.h>
#include <exception>
#include <stdexcept>
#include <memory>
#include <string>
typedef std::basic_string<TCHAR> String;
String GetErrorMessage(DWORD dwErrorCode)
{
LPTSTR psz = NULL;
const DWORD cchMsg = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS
| FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, // (不适用于FORMAT_MESSAGE_FROM_SYSTEM)
dwErrorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPTSTR>(&psz),
0,
NULL);
if (cchMsg > 0)
{
// 使用自定义删除器将缓冲区分配给智能指针,以便释放内存
// 万一String的c'tor抛出异常。
auto deleter = [](void* p) { ::HeapFree(::GetProcessHeap(), 0, p); };
std::unique_ptr<TCHAR, decltype(deleter)> ptrBuffer(psz, deleter);
return String(ptrBuffer.get(), cchMsg);
}
else
{
throw std::runtime_error("检索错误消息字符串失败。");
}
}注意:这些功能也适用于HRESULT值。只需将第一个参数从更改为DWORD dwErrorCode即可HRESULT hResult。其余代码可以保持不变。