WinApp.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #if _MSC_VER > 1000
  2. #pragma once
  3. #endif // _MSC_VER > 1000
  4. #ifndef __WinApp_h__
  5. #define __WinApp_h__
  6. /////////////////////////////////////////////////////////////////////////////
  7. // WinApp.h | Declaration of the TCWinApp class.
  8. //
  9. #include <TCLib.h>
  10. extern Win32App* g_papp;
  11. #ifdef _DEBUG
  12. ///////////////////////////////////////////////////////////////////////////
  13. //
  14. class TCWinApp : public Win32App
  15. {
  16. // Construction
  17. public:
  18. TCWinApp()
  19. {
  20. const int modeWarn = _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE;
  21. const int modeError = _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE;
  22. const int modeAssert = _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE;
  23. // Report WARNINGS to Debugger and stdout
  24. _CrtSetReportMode(_CRT_WARN , modeWarn);
  25. _CrtSetReportFile(_CRT_WARN , _CRTDBG_FILE_STDOUT);
  26. // Report ERRORS to Debugger and stdout
  27. _CrtSetReportMode(_CRT_ERROR , modeError);
  28. _CrtSetReportFile(_CRT_ERROR , _CRTDBG_FILE_STDOUT);
  29. // Report ASSERTS to Debugger and stdout
  30. _CrtSetReportMode(_CRT_ASSERT, modeAssert);
  31. _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);
  32. // Set a hook function
  33. AccessPrevHook() = _CrtSetReportHook(ReportHook);
  34. // Get the module filename of the current process
  35. char szModule[_MAX_PATH];
  36. GetModuleFileNameA(NULL, szModule, sizeofArray(szModule));
  37. // Break out just the file name part
  38. _splitpath(szModule, NULL, NULL, m_szModuleName, NULL);
  39. // Add a colon and a space
  40. strcat(m_szModuleName, ": ");
  41. // Compute the address of the terminating null
  42. m_cchModuleName = strlen(m_szModuleName);
  43. m_pszModuleNameEnd = m_szModuleName + m_cchModuleName;
  44. }
  45. /////////////////////////////////////////////////////////////////////////
  46. ~TCWinApp()
  47. {
  48. // Restore the previous hook function, if any
  49. _CrtSetReportHook(AccessPrevHook());
  50. }
  51. // Overrides
  52. public:
  53. /////////////////////////////////////////////////////////////////////////
  54. virtual void DebugOutput(const char *psz)
  55. {
  56. int cch = strlen(psz);
  57. if (cch < (sizeof(m_szModuleName) - (m_cchModuleName + 1)))
  58. {
  59. strcpy(m_pszModuleNameEnd, psz);
  60. _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, m_szModuleName);
  61. }
  62. else
  63. {
  64. char* pszCopy = (char*)_alloca(cch + m_cchModuleName + 1);
  65. strncpy(pszCopy, m_szModuleName, m_cchModuleName);
  66. strcpy(pszCopy + m_cchModuleName, psz);
  67. _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, pszCopy);
  68. }
  69. }
  70. /////////////////////////////////////////////////////////////////////////
  71. virtual bool OnAssert(const char* psz, const char* pszFile, int line,
  72. const char* pszModule)
  73. {
  74. // Save the current _CRT_ASSERT report mode, if we are interactive
  75. int nReportModePrev;
  76. bool bInteractive = IsInteractiveDesktop();
  77. if (bInteractive)
  78. {
  79. nReportModePrev = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_REPORT_MODE);
  80. _CrtSetReportMode(_CRT_ASSERT, nReportModePrev | _CRTDBG_MODE_WNDW);
  81. }
  82. // Report the assertion
  83. int n = _CrtDbgReport(_CRT_ASSERT, pszFile, line, NULL, psz);
  84. // Restore the previous report mode, if interactive
  85. if (bInteractive)
  86. _CrtSetReportMode(_CRT_ASSERT, nReportModePrev);
  87. // Perform the necessary break
  88. if (1 == n || !bInteractive)
  89. DebugBreak();
  90. // Return false, since we already took care of the break
  91. return false;
  92. }
  93. // Implementation
  94. protected:
  95. /////////////////////////////////////////////////////////////////////////
  96. static _CRT_REPORT_HOOK& AccessPrevHook()
  97. {
  98. static _CRT_REPORT_HOOK s_pfnPrevHook = NULL;
  99. return s_pfnPrevHook;
  100. }
  101. /////////////////////////////////////////////////////////////////////////
  102. static bool IsNoise(const char* pszText)
  103. {
  104. if ('\0' != pszText[1])
  105. return false;
  106. if ('.' == pszText[0])
  107. return true;
  108. if ('{' == pszText[0])
  109. return true;
  110. if ('}' == pszText[0])
  111. return true;
  112. if ('+' == pszText[0])
  113. return true;
  114. if ('-' == pszText[0])
  115. return true;
  116. if ('[' == pszText[0])
  117. return true;
  118. if (']' == pszText[0])
  119. return true;
  120. if ('<' == pszText[0])
  121. return true;
  122. if ('>' == pszText[0])
  123. return true;
  124. return false;
  125. }
  126. /////////////////////////////////////////////////////////////////////////
  127. static int ReportHook(int reportType, char* message, int* returnValue)
  128. {
  129. static bool s_bInHook = false;
  130. if (s_bInHook)
  131. return false;
  132. static bool s_bIsNoise = false;
  133. bool bWasNoise = s_bIsNoise;
  134. s_bIsNoise = IsNoise(message);
  135. if (bWasNoise && !s_bIsNoise)
  136. {
  137. s_bInHook = true;
  138. int nReportModePrev = _CrtSetReportMode(reportType, _CRTDBG_REPORT_MODE);
  139. _CrtSetReportMode(reportType, nReportModePrev & ~_CRTDBG_MODE_WNDW);
  140. _CrtDbgReport(reportType, NULL, NULL, NULL, "\n");
  141. _CrtSetReportMode(reportType, nReportModePrev);
  142. s_bInHook = false;
  143. }
  144. // Perform default processing
  145. return false;
  146. }
  147. // Data Members
  148. protected:
  149. char m_szModuleName[_MAX_PATH * 4];
  150. char* m_pszModuleNameEnd;
  151. int m_cchModuleName;
  152. };
  153. class TCWinAppDLL : public TCWinApp
  154. {
  155. // Construction
  156. public:
  157. TCWinAppDLL()
  158. {
  159. // Do NOT report WARNINGS or ERRORS to stdout
  160. _CrtSetReportMode(_CRT_WARN , _CRTDBG_MODE_DEBUG);
  161. _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
  162. }
  163. };
  164. #else // _DEBUG
  165. ///////////////////////////////////////////////////////////////////////////
  166. //
  167. class TCWinApp : public Win32App
  168. {
  169. };
  170. typedef TCWinApp TCWinAppDLL;
  171. #endif // _DEBUG
  172. /////////////////////////////////////////////////////////////////////////////
  173. #endif // !__WinApp_h__