今のところ自分が作ったクラスの中で一番使ってるもの。
Windows APIのエラーコードをエラーメッセージに変換する例外クラス。
- GetLastError()で取れるエラーコードと、多分HRESULTのエラーも取れると思う。
#使用は自己責任で!!
では、おソース
Win32Exception.h
#if !defined( WINEXCEPTION_H_INCLUDE ) #define WINEXCEPTION_H_INCLUDE // MFC使用時用にはwindows.hはインクルードしない #if !defined( __AFXWIN_H__ ) #include <windows.h> #endif // !defined( __AFXWIN_H__ ) #include <string> #include <stdexcept> /// Win32ラッパークラス群 namespace win32 { /// Win32例外クラス class Win32Exception : public std::runtime_error { public: // コンストラクタ Win32Exception( DWORD errorCode ); Win32Exception( DWORD errorCode, const char *fileName, int lineNo ); // デストラクタ ~Win32Exception(); // エラーコードの取得 DWORD getErrorCode() const; // エラーメッセージの取得 const std::string& getErrorMessage() const; // エラーメッセージの取得 const char* what() const; // エラーコードからエラーメッセージの取得 static std::string getErrorMessage( DWORD errorCode ); private: DWORD errorCode_; ///< エラーコード std::string errorMessage_; ///< エラーメッセージ }; } // namespace win32 #endif // !defined( WINEXCEPTION_H_INCLUDE ) // EOF
次にWin32Exception.cpp
#include "Win32Exception.h" #include <sstream> /// Win32ラッパークラス群 namespace win32 { /** * コンストラクタ * * @param dwResult エラーコード */ Win32Exception::Win32Exception( DWORD errorCode ) : std::runtime_error( "" ) , errorCode_( errorCode ) , errorMessage_( getErrorMessage( errorCode ) ) { } Win32Exception::Win32Exception( DWORD errorCode, const char *fileName, int lineNo ) : std::runtime_error( "" ) , errorCode_( errorCode ) { std::stringstream str; str << fileName << "(" << lineNo << "):" << getErrorMessage( errorCode ); errorMessage_ = str.str(); } /** * デストラクタ */ Win32Exception::~Win32Exception() { } /** * エラーコードの取得 * * @return エラーコード */ DWORD Win32Exception::getErrorCode() const { return errorCode_; } /** * エラーメッセージの取得 * * @return エラーメッセージ */ const std::string& Win32Exception::getErrorMessage() const { return errorMessage_; } /** * エラーメッセージの取得 * * @return エラーメッセージ */ const char* Win32Exception::what() const { return errorMessage_.c_str(); } /** * エラーコードからエラーメッセージの取得(クラス関数) * * @param dwErrCode エラーコード * * @return エラーメッセージ */ std::string Win32Exception::getErrorMessage( DWORD errorCode ) { // エラーメッセージ用クラス class ErrorMessage { public: ErrorMessage() : message_(0) {} ~ErrorMessage(){ if( message_ != 0 ) ::LocalFree( message_ ); } char** operator & (){ return &message_; } char* get(){ return message_; } private: char* message_; }; ErrorMessage message; // メッセージバッファ // エラーメッセージの取得 BOOL ret = ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, errorCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPTSTR)&message, 0, 0 ); return ret ? message.get() : "未定義エラー"; } } // EOF
最後に使用例
#include <iostream> #include "Win32Exception.h" void main() { try { // "ハンドルが無効です。" BOOL ret = ::ReadFile( 0, 0, 0, 0, 0 ); if ( !ret ) { throw win32::Win32Exception( ::GetLastError() ); } } catch ( std::exception& ex ) { std::cout << ex.what(); } try { // "D:\win32exceptiontest\main.cpp(21):ハンドルが無効です。" BOOL ret = ::ReadFile( 0, 0, 0, 0, 0 ); if ( !ret ) { throw win32::Win32Exception( ::GetLastError(), __FILE__, __LINE__ ); } } catch ( std::exception& ex ) { std::cout << ex.what(); } } // EOF