1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
//
// Includes
//
#include <sdkddkver.h>
#include <Windows.h>
#include <cstring> // std::strrchr
#include <string> // std::string std::wstring
#include <comdef.h> // _com_error
#include <codecvt> // string conversion std::wstring_convert and std::codecvt_utf8
//
// helper macros
//
#ifdef UNICODE
typedef std::wstring string;
#else
typedef std::string string;
#endif // UNICODE
// conditionaly use string or wide string
#ifdef UNICODE
// converto to wide string
#define to_string std::to_wstring
#else
// convert to ANSI string
#define to_string std::to_string
#endif // UNICODE
// Show only file name instead of full path
#define __FILENAME__ (std::strrchr(__FILE__, '\\') ? std::strrchr(__FILE__, '\\') + 1 : __FILE__)
//
// converts string or const char* to wstring
//
std::wstring stringToWstring(const std::string& t_str)
{
//setup converter
typedef std::codecvt_utf8<wchar_t> convert_type;
std::wstring_convert<convert_type, wchar_t> converter;
//use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
return converter.from_bytes(t_str);
}
//
// Format error code into a string and show message box
// COM and System errors
//
void ShowError(const char* file, int line, HRESULT hr = S_OK)
{
string error_type = TEXT("Rutime Error");
string error_message = TEXT("File:\t");
#ifdef UNICODE
error_message.append(stringToWstring(file));
#else
error_message.append(file);
#endif // UNICODE
error_message.append(TEXT("\r\nLine:\t"));
error_message.append(to_string(line));
error_message.append(TEXT("\r\nError:\t"));
// If HRESULT is omited or S_OK
// format last error code message
if (hr == S_OK)
{
PVOID lpBuff = nullptr;
DWORD dwChars = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
nullptr,
GetLastError(),
0,
reinterpret_cast<PTSTR>(&lpBuff),
0,
nullptr);
// If the function succeeds, the return value is
// the number of TCHARs stored in the output buffer
if (dwChars)
{
error_message.append(reinterpret_cast<PCTSTR>(lpBuff));
}
else // If the function fails, the return value is zero
{
error_message.append(TEXT("Unknown Error\t"));
error_message.append(to_string(GetLastError()));
}
// Free the buffer allocated by FormatMessage
LocalFree(lpBuff);
}
else // Format com error code into a message
{
_com_error err(hr);
error_message.append(err.ErrorMessage());
}
// Play the sound and show error message
// TODO: pass global handle to main window to MessageBox
// to make modal message box (instead of nullptr)
MessageBox(nullptr,
error_message.c_str(),
error_type.c_str(), MB_OK | MB_ICONERROR);
}
| |