- /**
- * MtVerify.h
- *
- * Error handling for applications in
- * "Multitheading Applications in Win32"
- *
- * The function PrintError() is marked as __inline so that it can be
- * included from one or more C or C++ files without multiple definition
- * errors. For the examples in this book, this works fine.
- * To use the PrintError() in an application, it should be taken out,
- * placed in its own source file, and the "__inline" declaration removed
- * so the function will be globally available.
- */
- #pragma comment( lib, "USER32" )
- #include <stdlib.h>
- #include <crtdbg.h>
- #define MTASSERT(a) _ASSERTE(a)
- // 宏定義 __FILE__ 與__LINE__都是預處理符號提供錯誤信息的描述
- // 如果a返回FALSE就執行PrintError函數
- #define MTVERIFY(a) if (!(a)) PrintError(#a,__FILE__,__LINE__,GetLastError())
- __inline void PrintError(LPSTR linedesc, LPSTR filename, int lineno, DWORD errnum)
- {
- LPSTR lpBuffer;
- char errbuf[256];
- #ifdef _WINDOWS
- char modulename[MAX_PATH];
- #else // _WINDOWS
- DWORD numread;
- #endif // _WINDOWS
- // 把從GetLastError()返回的錯誤碼轉化爲錯誤信息
- FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
- | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- errnum,
- LANG_NEUTRAL,
- (LPTSTR)&lpBuffer,
- 0,
- NULL );
- wsprintf(errbuf, "/nThe following call failed at line %d in %s:/n/n"
- " %s/n/nReason: %s/n", lineno, filename, linedesc, lpBuffer);
- // 如果是console程序就輸出信息到控制檯上
- #ifndef _WINDOWS
- WriteFile(GetStdHandle(STD_ERROR_HANDLE), errbuf, strlen(errbuf), &numread, FALSE );
- // 等待3秒鐘是爲了使用者看到出錯信息
- Sleep(3000);
- // 如果是窗口程序就一彈出對話框的形式輸出錯誤信息
- #else
- // 當前exe文件的全路徑
- GetModuleFileName(NULL, modulename, MAX_PATH);
- // 置彈出窗口在最上層以免被忽略
- MessageBox(NULL, errbuf, modulename, MB_ICONWARNING|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
- #endif
- // 把結束代碼EXIT_FAILURE 交給操作系統
- exit(EXIT_FAILURE);
- }