The pure WinAPI-only code is
#include <Windows.h> /* Shows MessageBox with the last-error text. * Default caption is "error". */ void show_system_error(const wchar_t* caption = NULL) { const size_t BUF_SIZE = 1024; wchar_t errorMsgBuf[BUF_SIZE]; FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), NULL, errorMsgBuf, BUF_SIZE, NULL); MessageBoxW(0, errorMsgBuf, caption, MB_ICONERROR); } int main() { SetLastError(ERROR_FILE_NOT_FOUND); show_system_error(); }
If we use boost, we got smaller code:
#include <iostream> #include <string> #include <locale> #include <boost/system/error_code.hpp> #include <Windows.h> int main() { setlocale(LC_ALL, ""); SetLastError(ERROR_FILE_NOT_FOUND); auto text = boost::system::system_category()( GetLastError(), boost::system::system_category()).message(); // or, just text = boost::system::system_category().message(GetLastError()); std::cout << text << '\n'; }
Also we can throw an exception, using boost::system::system_error instead of error_code:
#include <iostream> #include <locale> #include <boost/system/system_error.hpp> #include <boost/preprocessor/stringize.hpp> #include <Windows.h> int main() { setlocale(LC_ALL, ""); try { SetLastError(ERROR_FILE_NOT_FOUND); throw boost::system::system_error( GetLastError(), boost::system::system_category(), __FUNCTION__ " #" BOOST_PP_STRINGIZE(__LINE__)); } catch(std::exception& e) { std::cerr << e.what() << '\n'; } }
Update:
C++0x standard library contains <system_error> header file, with same classes as in boost.system library.
#include <iostream> #include <string> #include <system_error> #include <Windows.h> int main() { SetLastError(ERROR_FILE_NOT_FOUND); auto text = std::system_category().message(GetLastError()); std::cout << text << '\n'; }In MSVC2010, it differs from boost's version - message isn't localized, so we don't have to use setlocale().
#include <iostream> #include <string> #include <system_error> #include <Windows.h> int main() { try { SetLastError(ERROR_FILE_NOT_FOUND); throw std::system_error(GetLastError(), std::system_category(), "test"); } catch(std::system_error& e) { std::cerr << e.what() << ": " << e.code().message() << '\n'; } }MSVC2010's std::system_error is broken. It's what() method doesn't concatenate error code and message parameters, so we should do it manually. It will be fixed in VC11 (link).
No comments:
Post a Comment