TrayIcon.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /////////////////////////////////////////////////////////////////////////////
  2. // TrayIcon.cpp : implementation file
  3. //
  4. // This is a conglomeration of ideas from the MSJ "Webster" application,
  5. // sniffing round the online docs, and from other implementations such
  6. // as PJ Naughter's "CTrayIconifyIcon" (http://indigo.ie/~pjn/ntray.html)
  7. // especially the "CTrayIcon::OnTrayNotification" member function.
  8. //
  9. // This class is a light wrapper around the windows system tray stuff. It
  10. // adds an icon to the system tray with the specified ToolTip text and
  11. // callback notification value, which is sent back to the Parent window.
  12. //
  13. // The tray icon can be instantiated using either the constructor or by
  14. // declaring the object and creating (and displaying) it later on in the
  15. // program. eg.
  16. //
  17. // CTrayIcon m_TrayIcon; // Member variable of some class
  18. //
  19. // ...
  20. // // in some member function maybe...
  21. // m_TrayIcon.Create(pParentWnd, WM_MY_NOTIFY, "Click here",
  22. // hIcon, nTrayIconID);
  23. //
  24. // Clobbered together by Chris Maunder.
  25. //
  26. //
  27. /////////////////////////////////////////////////////////////////////////////
  28. #include "stdafx.h"
  29. #include "TrayIcon.h"
  30. #include "resource.h"
  31. #ifdef _DEBUG
  32. #define new DEBUG_NEW
  33. #undef THIS_FILE
  34. static char THIS_FILE[] = __FILE__;
  35. #endif
  36. extern BOOL g_bAutoRun;
  37. extern int g_bAutoCheckSvc; // 是否自动检查服务(次/小时)
  38. IMPLEMENT_DYNAMIC(CTrayIcon, CObject)
  39. /////////////////////////////////////////////////////////////////////////////
  40. // CTrayIcon construction/creation/destruction
  41. CTrayIcon::CTrayIcon()
  42. {
  43. memset(&m_tnd, 0, sizeof(m_tnd));
  44. m_bEnabled = FALSE;
  45. m_bHidden = FALSE;
  46. }
  47. CTrayIcon::CTrayIcon(CWnd* pWnd, UINT uCallbackMessage, LPCTSTR szToolTip,
  48. HICON icon, UINT uID)
  49. {
  50. Create(pWnd, uCallbackMessage, szToolTip, icon, uID);
  51. m_bHidden = FALSE;
  52. }
  53. BOOL CTrayIcon::Create(CWnd* pWnd, UINT uCallbackMessage, LPCTSTR szToolTip,
  54. HICON icon, UINT uID)
  55. {
  56. // this is only for Windows 95 (or higher)
  57. VERIFY(m_bEnabled = ( GetVersion() & 0xff ) >= 4);
  58. if (!m_bEnabled) return FALSE;
  59. //Make sure Notification window is valid
  60. VERIFY(m_bEnabled = (pWnd && ::IsWindow(pWnd->GetSafeHwnd())));
  61. if (!m_bEnabled) return FALSE;
  62. //Make sure we avoid conflict with other messages
  63. ASSERT(uCallbackMessage >= WM_USER);
  64. //Tray only supports tooltip text up to 64 characters
  65. ASSERT(_tcslen(szToolTip) <= 64);
  66. // load up the NOTIFYICONDATA structure
  67. m_tnd.cbSize = sizeof(NOTIFYICONDATA);
  68. m_tnd.hWnd = pWnd->GetSafeHwnd();
  69. m_tnd.uID = uID;
  70. m_tnd.hIcon = icon;
  71. m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
  72. m_tnd.uCallbackMessage = uCallbackMessage;
  73. lstrcpy (m_tnd.szTip, szToolTip);
  74. // Set the tray icon
  75. //
  76. (m_bEnabled = Shell_NotifyIcon(NIM_ADD, &m_tnd));
  77. return m_bEnabled;
  78. }
  79. CTrayIcon::~CTrayIcon()
  80. {
  81. RemoveIcon();
  82. }
  83. /////////////////////////////////////////////////////////////////////////////
  84. // CTrayIcon icon manipulation
  85. void CTrayIcon::MoveToRight()
  86. {
  87. HideIcon();
  88. ShowIcon();
  89. }
  90. void CTrayIcon::RemoveIcon()
  91. {
  92. if (!m_bEnabled) return;
  93. m_tnd.uFlags = 0;
  94. Shell_NotifyIcon(NIM_DELETE, &m_tnd);
  95. m_bEnabled = FALSE;
  96. }
  97. void CTrayIcon::HideIcon()
  98. {
  99. if (m_bEnabled && !m_bHidden) {
  100. m_tnd.uFlags = NIF_ICON;
  101. Shell_NotifyIcon (NIM_DELETE, &m_tnd);
  102. m_bHidden = TRUE;
  103. }
  104. }
  105. void CTrayIcon::ShowIcon()
  106. {
  107. if (m_bEnabled && m_bHidden) {
  108. m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
  109. Shell_NotifyIcon(NIM_ADD, &m_tnd);
  110. m_bHidden = FALSE;
  111. }
  112. }
  113. BOOL CTrayIcon::SetIcon(HICON hIcon)
  114. {
  115. if (!m_bEnabled) return FALSE;
  116. m_tnd.uFlags = NIF_ICON;
  117. m_tnd.hIcon = hIcon;
  118. return Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
  119. }
  120. BOOL CTrayIcon::SetIcon(LPCTSTR lpszIconName)
  121. {
  122. HICON hIcon = AfxGetApp()->LoadIcon(lpszIconName);
  123. return SetIcon(hIcon);
  124. }
  125. BOOL CTrayIcon::SetIcon(UINT nIDResource)
  126. {
  127. HICON hIcon = AfxGetApp()->LoadIcon(nIDResource);
  128. return SetIcon(hIcon);
  129. }
  130. BOOL CTrayIcon::SetStandardIcon(LPCTSTR lpIconName)
  131. {
  132. HICON hIcon = LoadIcon(NULL, lpIconName);
  133. return SetIcon(hIcon);
  134. }
  135. BOOL CTrayIcon::SetStandardIcon(UINT nIDResource)
  136. {
  137. HICON hIcon = LoadIcon(NULL, MAKEINTRESOURCE(nIDResource));
  138. return SetIcon(hIcon);
  139. }
  140. HICON CTrayIcon::GetIcon() const
  141. {
  142. HICON hIcon = NULL;
  143. if (m_bEnabled)
  144. hIcon = m_tnd.hIcon;
  145. return hIcon;
  146. }
  147. /////////////////////////////////////////////////////////////////////////////
  148. // CTrayIcon tooltip text manipulation
  149. BOOL CTrayIcon::SetTooltipText(LPCTSTR pszTip)
  150. {
  151. if (!m_bEnabled) return FALSE;
  152. m_tnd.uFlags = NIF_TIP;
  153. _tcscpy(m_tnd.szTip, pszTip);
  154. return Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
  155. }
  156. BOOL CTrayIcon::SetTooltipText(UINT nID)
  157. {
  158. CString strText;
  159. VERIFY(strText.LoadString(nID));
  160. return SetTooltipText(strText);
  161. }
  162. CString CTrayIcon::GetTooltipText() const
  163. {
  164. CString strText;
  165. if (m_bEnabled)
  166. strText = m_tnd.szTip;
  167. return strText;
  168. }
  169. /////////////////////////////////////////////////////////////////////////////
  170. // CTrayIcon notification window stuff
  171. BOOL CTrayIcon::SetNotificationWnd(CWnd* pWnd)
  172. {
  173. if (!m_bEnabled) return FALSE;
  174. //Make sure Notification window is valid
  175. ASSERT(pWnd && ::IsWindow(pWnd->GetSafeHwnd()));
  176. m_tnd.hWnd = pWnd->GetSafeHwnd();
  177. m_tnd.uFlags = 0;
  178. return Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
  179. }
  180. CWnd* CTrayIcon::GetNotificationWnd() const
  181. {
  182. return CWnd::FromHandle(m_tnd.hWnd);
  183. }
  184. /////////////////////////////////////////////////////////////////////////////
  185. // CTrayIcon implentation of OnTrayNotification
  186. LRESULT CTrayIcon::OnTrayNotification(UINT wParam, LONG lParam)
  187. {
  188. //Return quickly if its not for this tray icon
  189. if (wParam != m_tnd.uID)
  190. return 0L;
  191. CMenu menu, *pSubMenu;
  192. // Clicking with right button brings up a context menu
  193. if (LOWORD(lParam) == WM_RBUTTONUP)
  194. {
  195. if (!menu.LoadMenu(m_tnd.uID)) return 0;
  196. if (!(pSubMenu = menu.GetSubMenu(0))) return 0;
  197. // Make first menu item the default (bold font)
  198. ::SetMenuDefaultItem(pSubMenu->m_hMenu, 0, TRUE);
  199. if(g_bAutoRun)
  200. pSubMenu->CheckMenuItem(IDM_AUTORUN, MF_BYCOMMAND | MF_CHECKED);
  201. else
  202. pSubMenu->CheckMenuItem(IDM_AUTORUN, MF_BYCOMMAND | MF_UNCHECKED);
  203. if(g_bAutoCheckSvc)
  204. pSubMenu->CheckMenuItem(IDM_AUTOCHECKSVC, MF_BYCOMMAND | MF_CHECKED);
  205. else
  206. pSubMenu->CheckMenuItem(IDM_AUTOCHECKSVC, MF_BYCOMMAND | MF_UNCHECKED);
  207. //Display and track the popup menu
  208. CPoint pos;
  209. GetCursorPos(&pos);
  210. ::SetForegroundWindow(m_tnd.hWnd);
  211. ::TrackPopupMenu(pSubMenu->m_hMenu, 0, pos.x, pos.y, 0, m_tnd.hWnd, NULL);
  212. //pSubMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pos.x, pos.y, this, NULL);
  213. menu.DestroyMenu();
  214. }
  215. else if (LOWORD(lParam) == WM_LBUTTONDBLCLK || LOWORD(lParam) == WM_LBUTTONDOWN)
  216. {
  217. if (!menu.LoadMenu(m_tnd.uID)) return 0;
  218. if (!(pSubMenu = menu.GetSubMenu(0))) return 0;
  219. // double click received, the default action is to execute first menu item
  220. ::SetForegroundWindow(m_tnd.hWnd);
  221. ::SendMessage(m_tnd.hWnd, WM_COMMAND, pSubMenu->GetMenuItemID(0), 0);
  222. menu.DestroyMenu();
  223. }
  224. return 1;
  225. }