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