NotificationHandler.cpp 3.1 KB

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