www.gusucode.com > VC++写的APIHook实例源代码-源码程序 > VC++写的APIHook实例源代码-源码程序\code\HookSrv\TrayIcon.cpp
//Download by http://www.NewXing.com //--------------------------------------------------------------------------- // // 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 -------------------------------