trayicon.cpp
上传用户:jinandeyu
上传日期:2007-01-05
资源大小:620k
文件大小:4k
源码类别:

远程控制编程

开发平台:

WINDOWS

  1. ////////////////////////////////////////////////////////////////
  2. // CTrayIcon Copyright 1996 Microsoft Systems Journal.
  3. //
  4. // If this code works, it was written by Paul DiLascia.
  5. // If not, I don't know who wrote it.
  6. #include "stdafx.h"
  7. #include "trayicon.h"
  8. #include <afxpriv.h>    // for AfxLoadString
  9. IMPLEMENT_DYNAMIC(CTrayIcon, CCmdTarget)
  10. CTrayIcon::CTrayIcon(UINT uID)
  11. {
  12. // Initialize NOTIFYICONDATA
  13. memset(&m_nid, 0 , sizeof(m_nid));
  14. m_nid.cbSize = sizeof(m_nid);
  15. m_nid.uID = uID;  // never changes after construction
  16. // Use resource string as tip if there is one
  17. AfxLoadString(uID, m_nid.szTip, sizeof(m_nid.szTip));
  18. }
  19. CTrayIcon::~CTrayIcon()
  20. {
  21. SetIcon(0); // remove icon from system tray
  22. }
  23. //////////////////
  24. // Set notification window. It must created already.
  25. //
  26. void CTrayIcon::SetNotificationWnd(CWnd* pNotifyWnd, UINT uCbMsg)
  27. {
  28. // If the following assert fails, you're probably
  29. // calling me before you created your window. Oops.
  30. ASSERT(pNotifyWnd==NULL || ::IsWindow(pNotifyWnd->GetSafeHwnd()));
  31. m_nid.hWnd = pNotifyWnd->GetSafeHwnd();
  32. ASSERT(uCbMsg==0 || uCbMsg>=WM_USER);
  33. m_nid.uCallbackMessage = uCbMsg;
  34. }
  35. //////////////////
  36. // This is the main variant for setting the icon.
  37. // Sets both the icon and tooltip from resource ID
  38. // To remove the icon, call SetIcon(0)
  39. //
  40. BOOL CTrayIcon::SetIcon(UINT uID)
  41. HICON hicon=NULL;
  42. if (uID) {
  43. AfxLoadString(uID, m_nid.szTip, sizeof(m_nid.szTip));
  44. hicon = AfxGetApp()->LoadIcon(uID);
  45. }
  46. return SetIcon(hicon, NULL);
  47. }
  48. //////////////////
  49. // Common SetIcon for all overloads. 
  50. //
  51. BOOL CTrayIcon::SetIcon(HICON hicon, LPCSTR lpTip) 
  52. {
  53. UINT msg;
  54. m_nid.uFlags = 0;
  55. // Set the icon
  56. if (hicon) {
  57. // Add or replace icon in system tray
  58. msg = m_nid.hIcon ? NIM_MODIFY : NIM_ADD;
  59. m_nid.hIcon = hicon;
  60. m_nid.uFlags |= NIF_ICON;
  61. } else { // remove icon from tray
  62. if (m_nid.hIcon==NULL)
  63. return TRUE;      // already deleted
  64. msg = NIM_DELETE;
  65. }
  66. // Use the tip, if any
  67. if (lpTip)
  68. strncpy(m_nid.szTip, lpTip, sizeof(m_nid.szTip));
  69. if (m_nid.szTip[0])
  70. m_nid.uFlags |= NIF_TIP;
  71. // Use callback if any
  72. if (m_nid.uCallbackMessage && m_nid.hWnd)
  73. m_nid.uFlags |= NIF_MESSAGE;
  74. // Do it
  75. BOOL bRet = Shell_NotifyIcon(msg, &m_nid);
  76. if (msg==NIM_DELETE || !bRet)
  77. m_nid.hIcon = NULL;  // failed
  78. return bRet;
  79. }
  80. /////////////////
  81. // Default event handler handles right-menu and doubleclick.
  82. // Call this function from your own notification handler.
  83. //
  84. LRESULT CTrayIcon::OnTrayNotification(WPARAM wID, LPARAM lEvent)
  85. {
  86. if (wID!=m_nid.uID ||
  87. (lEvent!=WM_RBUTTONUP && lEvent!=WM_LBUTTONDBLCLK))
  88. return 0;
  89. // If there's a resource menu with the same ID as the icon, use it as 
  90. // the right-button popup menu. CTrayIcon will interprets the first
  91. // item in the menu as the default command for WM_LBUTTONDBLCLK
  92. // 
  93. CMenu menu;
  94. if (!menu.LoadMenu(m_nid.uID))
  95. return 0;
  96. CMenu* pSubMenu = menu.GetSubMenu(0);
  97. if (!pSubMenu) 
  98. return 0;
  99. if (lEvent==WM_RBUTTONUP) {
  100. // Make first menu item the default (bold font)
  101. ::SetMenuDefaultItem(pSubMenu->m_hMenu, 0, TRUE);
  102. // Display the menu at the current mouse location. There's a "bug"
  103. // (Microsoft calls it a feature) in Windows 95 that requires calling
  104. // SetForegroundWindow. To find out more, search for Q135788 in MSDN.
  105. //
  106. CPoint mouse;
  107. GetCursorPos(&mouse);
  108. ::SetForegroundWindow(m_nid.hWnd);  
  109. ::TrackPopupMenu(pSubMenu->m_hMenu, 0, mouse.x, mouse.y, 0,
  110. m_nid.hWnd, NULL);
  111. } else  // double click: execute first menu item
  112. ::SendMessage(m_nid.hWnd, WM_COMMAND, pSubMenu->GetMenuItemID(0), 0);
  113. return 1; // handled
  114. }