1.错误处理
1.$err,hr可以看到系统ERR的文字描绘
HANDLE hMutex = CreateMutex(NULL, false, L"1"); HANDLE hEvent = CreateMutex(NULL, false, L"1");
右键,添加监视:
第一步,调试到第一个互斥量,我们假定整个名字空间不存在重名,那么应该是成功的,看对应的监视:
$err,hr返回S_OK
第二步,调试到第二个互斥量
很明显,同名,同类型,应该返回ERROR_ALREADY_EXISTS
b7也就是183,我们去WinError.h中找183L,果然发现如下信息:
// // MessageId: ERROR_ALREADY_EXISTS // // MessageText: // // Cannot create a file when that file already exists. // #define ERROR_ALREADY_EXISTS 183L
我们发现,每一个错误代码都由消息ID,消息文本,和一个编号组成,
回到winerror.h的头,我们能发现这样一段注释:
// // Values are 32 bit values laid out as follows: // // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 // +---+-+-+-----------------------+-------------------------------+ // |Sev|C|R| Facility | Code | // +---+-+-+-----------------------+-------------------------------+ // // where // // Sev - is the severity code // // 00 - Success // 01 - Informational // 10 - Warning // 11 - Error // // C - is the Customer code flag // // R - is a reserved bit // // Facility - is the facility code // // Code - is the facility's status code // // // Define the facility codes //
再对比下核心编程,
位 | 31-30 | 29 | 28 | 27-16 | 15-0 |
内容 | 严重性 | Microsoft/客户 | 保留 | Facility代码 | 异常代码 |
含义 |
0:成功 1:信息 2:警告 3:错误 |
0 = 微软预定义的代码 1 = 客户定义的代码 |
必须为0 | 前256个值由Microsoft保留 | Microsoft/客户定义的代码 |
好吧,我表示核心编程写得详细,要点是29位,如果要创建我们自己的错误代码,就必须在此位放一个1,通过这种方法来保证和预定义的错误码绝不冲突,
随手写了个返回ERROR描绘的代码:
CString GetMyLastError() { DWORD dwError = ::GetLastError(); HLOCAL hlocal = NULL;
DWORD systemLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); BOOL fOk = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, dwError, systemLocale, (PTSTR) &hlocal, 0, NULL); CString szErr = _T(""); if (fOk) { szErr = (PCTSTR) LocalLock(hlocal); } LocalUnlock(hlocal); LocalFree(hlocal); return szErr; }
有人可能觉得FormatMessage有点复杂,那么打开MSDN,找到Example Code
#include <windows.h> #include <strsafe.h> void ErrorExit(LPTSTR lpszFunction) { // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); // Display the error message and exit the process lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf), TEXT("%s failed with error %d: %s"), lpszFunction, dw, lpMsgBuf); MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); ExitProcess(dw); } void main() { // Generate an error if(!GetProcessId(NULL)) ErrorExit(TEXT("GetProcessId")); }
照着抄吧。