NotificationHandler.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * NotificationHandler.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "NotificationHandler.h"
  12. #include <SDL_video.h>
  13. #include <SDL_events.h>
  14. #if defined(VCMI_WINDOWS)
  15. #include <SDL_syswm.h>
  16. #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
  17. // Windows Header Files:
  18. #include <windows.h>
  19. #include <shellapi.h>
  20. // C RunTime Header Files
  21. #define WM_USER_SHELLICON WM_USER + 1
  22. // Global Variables:
  23. struct NotificationState
  24. {
  25. HINSTANCE hInst; // current instance
  26. NOTIFYICONDATA niData; // notify icon data
  27. bool initialized = false;
  28. SDL_Window * window;
  29. };
  30. NotificationState state;
  31. void NotificationHandler::notify(std::string msg)
  32. {
  33. NOTIFYICONDATA niData;
  34. SDL_SysWMinfo info;
  35. SDL_VERSION(&info.version);
  36. if(!SDL_GetWindowWMInfo(state.window, &info))
  37. return;
  38. if(info.info.win.window == GetForegroundWindow())
  39. return;
  40. ZeroMemory(&niData, sizeof(NOTIFYICONDATA));
  41. niData.cbSize = sizeof(NOTIFYICONDATA);
  42. niData.hWnd = info.info.win.window;
  43. niData.uID = 1;
  44. niData.uFlags = NIF_INFO | NIF_MESSAGE;
  45. niData.uCallbackMessage = WM_USER_SHELLICON;
  46. niData.dwInfoFlags = NIIF_INFO;
  47. msg.copy(niData.szInfo, msg.length());
  48. Shell_NotifyIcon(NIM_MODIFY, &niData);
  49. }
  50. void NotificationHandler::init(SDL_Window * window)
  51. {
  52. state.window = window;
  53. if(state.initialized)
  54. return;
  55. SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
  56. NOTIFYICONDATA niData;
  57. SDL_SysWMinfo info;
  58. SDL_VERSION(&info.version);
  59. if(!SDL_GetWindowWMInfo(state.window, &info))
  60. return;
  61. ZeroMemory(&niData, sizeof(NOTIFYICONDATA));
  62. state.hInst = (HINSTANCE)GetModuleHandle("VCMI_client.exe");
  63. niData.cbSize = sizeof(NOTIFYICONDATA);
  64. niData.hWnd = info.info.win.window;
  65. niData.uID = 1;
  66. niData.uFlags = NIF_ICON | NIF_MESSAGE;
  67. niData.uCallbackMessage = WM_USER_SHELLICON;
  68. niData.hIcon = (HICON)LoadImage(
  69. state.hInst,
  70. "IDI_ICON1",
  71. IMAGE_ICON,
  72. GetSystemMetrics(SM_CXSMICON),
  73. GetSystemMetrics(SM_CYSMICON),
  74. LR_DEFAULTSIZE);
  75. Shell_NotifyIcon(NIM_ADD, &niData);
  76. state.initialized = true;
  77. }
  78. void NotificationHandler::destroy()
  79. {
  80. NOTIFYICONDATA niData;
  81. SDL_SysWMinfo info;
  82. SDL_VERSION(&info.version);
  83. if(!SDL_GetWindowWMInfo(state.window, &info))
  84. return;
  85. ZeroMemory(&niData, sizeof(NOTIFYICONDATA));
  86. niData.cbSize = sizeof(NOTIFYICONDATA);
  87. niData.hWnd = info.info.win.window;
  88. niData.uID = 1;
  89. Shell_NotifyIcon(NIM_DELETE, &niData);
  90. }
  91. bool NotificationHandler::handleSdlEvent(const SDL_Event & ev)
  92. {
  93. if(ev.syswm.msg->msg.win.msg == WM_USER_SHELLICON)
  94. {
  95. auto winMsg = LOWORD(ev.syswm.msg->msg.win.lParam);
  96. if(winMsg == WM_LBUTTONUP || winMsg == NIN_BALLOONUSERCLICK)
  97. {
  98. SDL_MinimizeWindow(state.window);
  99. SDL_RestoreWindow(state.window);
  100. SDL_RaiseWindow(state.window);
  101. return true;
  102. }
  103. }
  104. return false;
  105. }
  106. #else
  107. void NotificationHandler::notify(std::string msg)
  108. {
  109. }
  110. void NotificationHandler::init(SDL_Window * window)
  111. {
  112. }
  113. void NotificationHandler::destroy()
  114. {
  115. }
  116. bool NotificationHandler::handleSdlEvent(const SDL_Event & ev)
  117. {
  118. return false;
  119. }
  120. #endif