TrayIcon.cpp
上传用户:jstlsd
上传日期:2007-01-13
资源大小:186k
文件大小:5k
- //---------------------------------------------------------------------------
- //
- // TrayIcon.cpp
- //
- // SUBSYSTEM: Hook system
- //
- // MODULE: Hook server
- //
- // DESCRIPTION: This code has been based on the Paul DiLascia's sample
- // Copyright 1996 Microsoft Systems Journal.
- //
- //
- // AUTHOR: Ivo Ivanov (ivopi@hotmail.com)
- // DATE: 2001 December v1.00
- //
- //---------------------------------------------------------------------------
- #include "stdafx.h"
- #include "trayicon.h"
- #include <afxpriv.h> // for AfxLoadString
- IMPLEMENT_DYNAMIC(CTrayIcon, CCmdTarget)
- CTrayIcon::CTrayIcon(UINT uID)
- {
- // Initialize NOTIFYICONDATA
- memset(&m_nid, 0 , sizeof(m_nid));
- m_nid.cbSize = sizeof(m_nid);
- m_nid.uID = uID; // never changes after construction
- // Use resource string as tip if there is one
- AfxLoadString(uID, m_nid.szTip, sizeof(m_nid.szTip));
- }
- CTrayIcon::~CTrayIcon()
- {
- SetIcon(0); // remove icon from system tray
- }
- //---------------------------------------------------------------------------
- // SetNotificationWnd
- //
- // Set notification window. It must been created already.
- //---------------------------------------------------------------------------
- void CTrayIcon::SetNotificationWnd(CWnd* pNotifyWnd, UINT uCbMsg)
- {
- // If the following assert fails, you're probably
- // calling me before you created your window. Oops.
- ASSERT(pNotifyWnd==NULL || ::IsWindow(pNotifyWnd->GetSafeHwnd()));
- m_nid.hWnd = pNotifyWnd->GetSafeHwnd();
- ASSERT(uCbMsg==0 || uCbMsg>=WM_USER);
- m_nid.uCallbackMessage = uCbMsg;
- }
- //---------------------------------------------------------------------------
- // SetIcon
- //
- // This is the main variant for setting the icon.
- // Sets both the icon and tooltip from resource ID
- // To remove the icon, call SetIcon(0)
- //---------------------------------------------------------------------------
- BOOL CTrayIcon::SetIcon(UINT uID)
- {
- HICON hicon=NULL;
- if (uID)
- {
- AfxLoadString(uID, m_nid.szTip, sizeof(m_nid.szTip));
- hicon = AfxGetApp()->LoadIcon(uID);
- }
- return SetIcon(hicon, NULL);
- }
- //---------------------------------------------------------------------------
- // SetIcon
- //
- // Common SetIcon for all overloads.
- //---------------------------------------------------------------------------
- BOOL CTrayIcon::SetIcon(HICON hicon, char* lpTip)
- {
- UINT msg;
- m_nid.uFlags = 0;
- // Set the icon
- if (hicon)
- {
- // Add or replace icon in system tray
- msg = m_nid.hIcon ? NIM_MODIFY : NIM_ADD;
- m_nid.hIcon = hicon;
- m_nid.uFlags |= NIF_ICON;
- }
- else
- { // remove icon from tray
- if (m_nid.hIcon==NULL)
- return TRUE; // already deleted
- msg = NIM_DELETE;
- }
- // Use the tip, if any
- if (lpTip)
- strncpy(m_nid.szTip, lpTip, sizeof(m_nid.szTip));
- if (m_nid.szTip[0])
- m_nid.uFlags |= NIF_TIP;
- // Use callback if any
- if (m_nid.uCallbackMessage && m_nid.hWnd)
- m_nid.uFlags |= NIF_MESSAGE;
- // Do it
- BOOL bRet = Shell_NotifyIcon(msg, &m_nid);
- if (msg==NIM_DELETE || !bRet)
- m_nid.hIcon = NULL; // failed
- return bRet;
- }
- //---------------------------------------------------------------------------
- // OnTrayNotification
- //
- // Default event handler handles right-menu and doubleclick.
- // Call this function from your own notification handler.
- //---------------------------------------------------------------------------
- LRESULT CTrayIcon::OnTrayNotification(WPARAM wID, LPARAM lEvent)
- {
- if (wID!=m_nid.uID ||
- (lEvent!=WM_RBUTTONUP && lEvent!=WM_LBUTTONDBLCLK))
- return 0;
- // If there's a resource menu with the same ID as the icon, use it as
- // the right-button popup menu. CTrayIcon will interprets the first
- // item in the menu as the default command for WM_LBUTTONDBLCLK
- //
- CMenu menu;
- if (!menu.LoadMenu(m_nid.uID))
- return 0;
- CMenu* pSubMenu = menu.GetSubMenu(0);
- if (!pSubMenu)
- return 0;
- if (lEvent == WM_RBUTTONUP)
- {
- //
- // Display the menu at the current mouse location. There's a "bug"
- // (Microsoft calls it a feature) in Windows 95 that requires calling
- // SetForegroundWindow. To find out more, search for Q135788 in MSDN.
- //
- CPoint mouse;
- GetCursorPos(&mouse);
- ::SetForegroundWindow(m_nid.hWnd);
- ::TrackPopupMenu(pSubMenu->m_hMenu, 0, mouse.x, mouse.y, 0,
- m_nid.hWnd, NULL);
- }
- else
- {
- // double click: execute first menu item
- ::SendMessage(m_nid.hWnd, WM_COMMAND, pSubMenu->GetMenuItemID(0), 0);
- }
- return 1; // handled
- }
- //----------------------------End of the file -------------------------------