/include/error.c

http://altdrag.googlecode.com/ · C · 89 lines · 63 code · 10 blank · 16 comment · 7 complexity · bdd3df802a71d0d28d189afbbca57f2f MD5 · raw file

  1. /*
  2. Error message handler.
  3. Copyright (C) 2012 Stefan Sundin (recover89@gmail.com)
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. */
  9. #ifdef ERROR_WRITETOFILE
  10. #include <shlobj.h>
  11. #endif
  12. int showerror = 1;
  13. LRESULT CALLBACK ErrorMsgProc(INT nCode, WPARAM wParam, LPARAM lParam) {
  14. if (nCode == HCBT_ACTIVATE) {
  15. //Edit the caption of the buttons
  16. SetDlgItemText((HWND)wParam, IDYES, L"Copy error");
  17. SetDlgItemText((HWND)wParam, IDNO, L"OK");
  18. }
  19. return 0;
  20. }
  21. void Error(wchar_t *func, wchar_t *info, int errorcode, wchar_t *file, int line) {
  22. if (!showerror) {
  23. return;
  24. }
  25. //Format message
  26. wchar_t msg[1000], *errormsg;
  27. int length = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, errorcode, 0, (wchar_t*)&errormsg, 0, NULL);
  28. if (length != 0) {
  29. errormsg[length-2] = '\0'; //Remove that damn newline at the end of the formatted error message
  30. }
  31. swprintf(msg, L"%s failed in file %s, line %d.\nError: %s (%d)\n\n%s", func, file, line, errormsg, errorcode, info);
  32. LocalFree(errormsg);
  33. //Display message
  34. #ifdef ERROR_WRITETOFILE
  35. wchar_t _txt[1000];
  36. SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, _txt);
  37. wcscat(_txt, L"\\"APP_NAME"-errorlog.txt");
  38. FILE *f = _wfopen(_txt, L"ab");
  39. fputws(msg, f);
  40. fputws(L"\n\n", f);
  41. fclose(f);
  42. #else
  43. //Tip: You can also press Ctrl+C in a MessageBox window to copy the text
  44. HHOOK hhk = SetWindowsHookEx(WH_CBT, &ErrorMsgProc, 0, GetCurrentThreadId());
  45. int response = MessageBox(NULL, msg, APP_NAME" Error", MB_ICONERROR|MB_YESNO|MB_DEFBUTTON2);
  46. UnhookWindowsHookEx(hhk);
  47. if (response == IDYES) {
  48. //Copy message to clipboard
  49. int size = (wcslen(msg)+1)*sizeof(wchar_t);
  50. wchar_t *data = LocalAlloc(LMEM_FIXED, size);
  51. memcpy(data, msg, size);
  52. OpenClipboard(NULL);
  53. EmptyClipboard();
  54. SetClipboardData(CF_UNICODETEXT, data);
  55. CloseClipboard();
  56. LocalFree(data);
  57. }
  58. #endif
  59. }
  60. //DBG("%d", 5);
  61. //DBGA("%d", 5);
  62. #ifdef ERROR_WRITETOFILE
  63. #define DBG(fmt, ...) { \
  64. wchar_t _txt[1000]; \
  65. SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, _txt); \
  66. wcscat(_txt, L"\\"APP_NAME"-errorlog.txt"); \
  67. FILE *f = _wfopen(_txt, L"ab"); \
  68. fwprintf(f, TEXT(fmt), ##__VA_ARGS__); \
  69. fputws(L"\n\n", f); \
  70. fclose(f); \
  71. }
  72. #else
  73. #define DBG(fmt, ...) { \
  74. wchar_t _txt[1000]; \
  75. wsprintf(_txt, TEXT(fmt), ##__VA_ARGS__); \
  76. MessageBox(NULL, _txt, APP_NAME" Debug", MB_ICONINFORMATION|MB_OK); \
  77. }
  78. #endif