TrayIcon.cpp
上传用户:jstlsd
上传日期:2007-01-13
资源大小:186k
文件大小:5k
源码类别:

钩子与API截获

开发平台:

Visual C++

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