Win32 API 将错误代码转换为消息字符串
示例
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值。只需将第一个参数从更改为DWORDdwErrorCode即可HRESULThResult。其余代码可以保持不变。