Windows错误代码转换为错误信息

王朝system·作者佚名  2006-11-13
窄屏简体版  字體: |||超大  

在调用一个API函数以后,如果函数失败,通常可以紧接着调用另一个API函数“GetLastError”来返回一个错误代码,下面这个类可以根据Windows定义的错误代码,查找到用文字表示的错误信息:

00001: #ifndef _YHB_SYSERROR_INCLUDED_

00002: #define _YHB_SYSERROR_INCLUDED_

00003:

00004: #include <stdexcept>

00005: #include <string>

00006:

00007: namespace yhb {

00008:

00009: class SysError

00010: : public std::runtime_error

00011: {

00012: public:

00013: SysError(int err=0)

00014: : runtime_error(makeMsgFromErrorNum(err))

00015: {}

00016: SysError(const char *customMsg, int err = 0)

00017: : runtime_error(makeMsgFromErrorNum(customMsg, err))

00018: {}

00019: static std::string makeMsgFromErrorNum(unsigned err = 0);

00020: static std::string makeMsgFromErrorNum(const char *customMsg, unsigned err = 0);

00021: };

00022:

00023: } // end of namespace

00024:

00025: #endif

SysError从std::runtime_error派生,因此可以被抛出并被作为std::exception捕获。

如果不想使用异常,也可以用它的两个静态方法来返回错误信息。

实现

00001: #include "StdAfx.h"

00002: #include "./SysError.h"

00003: #include <sstream>

00004: #include <LMErr.h>

00005:

00006: #define WIN32_LEAN_AND_MEAN

00007: #include <Windows.h>

00008:

00009: using namespace std;

00010:

00011: namespace yhb {

00012:

00013: /************************************************************************

00014: 管理用LoadLibrary()加载的模块句柄

00015: ************************************************************************/

00016: class Module {

00017: public:

00018: explicit Module(HMODULE handle=0)

00019: : handle_(handle)

00020: {}

00021: ~Module() {

00022: free();

00023: }

00024: Module & operator = (HMODULE handle) {

00025: free();

00026: handle_ = handle;

00027: return *this;

00028: }

00029: bool isValid() const { return 0!=handle_; }

00030: operator HMODULE() const { return handle_; }

00031: private:

00032: Module(const Module &);

00033: Module & operator = (const Module &);

00034: void free() {

00035: if (0!=handle_) {

00036: ::FreeLibrary(handle_);

00037: handle_ = 0;

00038: }

00039: }

00040: HMODULE handle_;

00041: };

00042:

00043: /************************************************************************

00044: SysError

00045: ************************************************************************/

00046: string SysError::makeMsgFromErrorNum(unsigned err/* =0 */) {

00047: if (0==err) {

00048: err = GetLastError();

00049: if (NOERROR==err)

00050: return "no error!";

00051: }

00052: Module module;

00053: DWORD flag = FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM;

00054: if (err >= NERR_BASE && err <= MAX_NERR) {

00055: module = LoadLibraryExA("netmsg.dll", 0, LOAD_LIBRARY_AS_DATAFILE);

00056: if (module.isValid())

00057: flag |= FORMAT_MESSAGE_FROM_HMODULE;

00058: }

00059: char buf[1024];

00060: if (FormatMessageA(flag, static_cast<HMODULE>(module),

00061: err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

00062: buf, sizeof(buf), 0))

00063: {

00064: return buf;

00065: } else {

00066: ostringstream os;

00067: os << "Unknown error: " << err << " (0x" << hex << err << ')';

00068: return os.str();

00069: }

00070: }

00071:

00072: string SysError::makeMsgFromErrorNum(const char *customMsg, unsigned err/* =0 */) {

00073: string result(customMsg);

00074: result += ' ';

00075: result += makeMsgFromErrorNum(err);

00076: return result;

00077: }

00078:

00079: } //end of namespace

C++里一种比较常用的方法,是将资源封装成一个类,在析构的时候释放该资源,比如上面的Module,析构的时候调用FreeLibrary。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有  導航