程序托盘

MFC 封装类

/////////////////////////////////////////////////////////////////////////////

// SystemTray.h : header file
//
// Written by Chris Maunder ([email protected])
// Copyright (c) 1998.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included. If 
// the source code in  this file is used in any commercial application 
// then acknowledgement must be made to the author of this file 
// (in whatever form you wish).
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to your
// computer, causes your pet cat to fall ill, increases baldness or
// makes you car start emitting strange noises when you start it up.
//
// Expect bugs.
// 
// Please use and enjoy. Please let me know of any bugs/mods/improvements 
// that you have found/implemented and I will fix/incorporate them into this
// file. 

#ifndef _INCLUDED_SYSTEMTRAY_H_

#define _INCLUDED_SYSTEMTRAY_H_

#include <afxtempl.h>
#include <afxwin.h>
#include <atlcomtime.h>

/////////////////////////////////////////////////////////////////////////////

// CSystemTray window

class CSystemTray : public CWnd
{

	// Construction/destruction

public:
	CSystemTray();
	CSystemTray(CWnd* pWnd, UINT uCallbackMessage, LPCTSTR szTip, HICON icon, UINT uID);
	virtual ~CSystemTray();

	DECLARE_DYNAMIC(CSystemTray)

	// Operations

public:
	BOOL Enabled() { return m_bEnabled; }
	BOOL Visible() { return !m_bHidden; }

	// Create the tray icon
	BOOL Create(CWnd* pParent, UINT uCallbackMessage, LPCTSTR szTip, HICON icon, UINT uID);

	// Change or retrieve the Tooltip text
	BOOL    SetTooltipText(LPCTSTR pszTooltipText);
	BOOL    SetTooltipText(UINT nID);
	CString GetTooltipText() const;

	// Change or retrieve the icon displayed
	BOOL  SetIcon(HICON hIcon);
	BOOL  SetIcon(LPCTSTR lpszIconName);
	BOOL  SetIcon(UINT nIDResource);
	BOOL  SetStandardIcon(LPCTSTR lpIconName);
	BOOL  SetStandardIcon(UINT nIDResource);
	HICON GetIcon() const;
	void  HideIcon();
	void  ShowIcon();
	void  RemoveIcon();
	void  MoveToRight();

	// For icon animation
	BOOL  SetIconList(UINT uFirstIconID, UINT uLastIconID); 
	BOOL  SetIconList(HICON* pHIconList, UINT nNumIcons); 
	BOOL  Animate(UINT nDelayMilliSeconds, int nNumSeconds = -1);
	BOOL  StepAnimation();
	BOOL  StopAnimation();

	// Change menu default item
	void GetMenuDefaultItem(UINT& uItem, BOOL& bByPos);
	BOOL SetMenuDefaultItem(UINT uItem, BOOL bByPos);

	// Change or retrieve the window to send notification messages to
	BOOL  SetNotificationWnd(CWnd* pNotifyWnd);
	CWnd* GetNotificationWnd() const;

	// Default handler for tray notification message
	virtual LRESULT OnTrayNotification(WPARAM uID, LPARAM lEvent);

	// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CSystemTray)

protected:
	virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
	//}}AFX_VIRTUAL

	// Implementation

protected:
	void Initialise();
	BOOL            m_bEnabled;   // does O/S support tray icon?
	BOOL            m_bHidden;    // Has the icon been hidden?
	NOTIFYICONDATA  m_tnd;
	CArray<HICON, HICON> m_IconList;
	static UINT  m_nIDEvent;
	UINT         m_uIDTimer;
	int          m_nCurrentIcon;
	COleDateTime m_StartTime;
	int          m_nAnimationPeriod;
	HICON        m_hSavedIcon;
	UINT         m_DefaultMenuItemID;
	BOOL         m_DefaultMenuItemByPos;

	// Generated message map functions
protected:
	//{{AFX_MSG(CSystemTray)
	afx_msg void OnTimer(UINT nIDEvent);

	//}}AFX_MSG

	DECLARE_MESSAGE_MAP()

};
#endif

/////////////////////////////////////////////////////////////////////////////

// SystemTray.cpp : implementation file
//
// This is a conglomeration of ideas from the MSJ "Webster" application,
// sniffing round the online docs, and from other implementations such
// as PJ Naughter's "CTrayNotifyIcon" (http://indigo.ie/~pjn/ntray.html)
// especially the "CSystemTray::OnTrayNotification" member function.
// Joerg Koenig suggested the icon animation stuff
//
// This class is a light wrapper around the windows system tray stuff. It
// adds an icon to the system tray with the specified ToolTip text and 
// callback notification value, which is sent back to the Parent window.
//
// The tray icon can be instantiated using either the constructor or by
// declaring the object and creating (and displaying) it later on in the
// program. eg.
//
//        CSystemTray m_SystemTray;    // Member variable of some class
//        
//        ... 
//        // in some member function maybe...
//        m_SystemTray.Create(pParentWnd, WM_MY_NOTIFY, "Click here", 
//                          hIcon, nSystemTrayID);
//
// Written by Chris Maunder ([email protected])
// Copyright (c) 1998.
//
// Updated: 25 Jul 1998 - Added icon animation, and derived class
//                        from CWnd in order to handle messages. (CJM)
//                        (icon animation suggested by Joerg Koenig.
//                        Added API to set default menu item. Code provided
//                        by Enrico Lelina.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included. If 
// the source code in  this file is used in any commercial application 
// then acknowledgement must be made to the author of this file 
// (in whatever form you wish).
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to your
// computer, causes your pet cat to fall ill, increases baldness or
// makes you car start emitting strange noises when you start it up.
//
// Expect bugs.
// 
// Please use and enjoy. Please let me know of any bugs/mods/improvements 
// that you have found/implemented and I will fix/incorporate them into this
// file. 
//
/////////////////////////////////////////////////////////////////////////////
#include "SystemTray.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
	static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNAMIC(CSystemTray, CWnd)
UINT CSystemTray::m_nIDEvent = 4567;
/////////////////////////////////////////////////////////////////////////////

// CSystemTray construction/creation/destruction

CSystemTray::CSystemTray()
{
	Initialise();
}
CSystemTray::CSystemTray(CWnd* pParent, UINT uCallbackMessage, LPCTSTR szToolTip, 
	HICON icon, UINT uID)
{
	Initialise();
	Create(pParent, uCallbackMessage, szToolTip, icon, uID);
}

void CSystemTray::Initialise()
{
	memset(&m_tnd, 0, sizeof(m_tnd));
	m_bEnabled   = FALSE;
	m_bHidden    = FALSE;
	m_uIDTimer   = 0;
	m_hSavedIcon = NULL;
	m_DefaultMenuItemID = 0;
	m_DefaultMenuItemByPos = TRUE;
}
BOOL CSystemTray::Create(CWnd* pParent, UINT uCallbackMessage, LPCTSTR szToolTip, HICON icon, UINT uID)
{
	// this is only for Windows 95 (or higher)
	VERIFY(m_bEnabled = ( GetVersion() & 0xff ) >= 4);
	if (!m_bEnabled) return FALSE;
	// Make sure Notification window is valid (not needed - CJM)
	// VERIFY(m_bEnabled = (pParent && ::IsWindow(pParent->GetSafeHwnd())));
	// if (!m_bEnabled) return FALSE;
	// Make sure we avoid conflict with other messages
	ASSERT(uCallbackMessage >= WM_USER);
	// Tray only supports tooltip text up to 64 characters
	ASSERT(_tcslen(szToolTip) <= 64);
	// Create an invisible window
	CWnd::CreateEx(0, AfxRegisterWndClass(0), _T(""), WS_POPUP, 0,0,10,10, NULL, 0);
	// load up the NOTIFYICONDATA structure
	m_tnd.cbSize = sizeof(NOTIFYICONDATA);
	m_tnd.hWnd   = pParent->GetSafeHwnd()? pParent->GetSafeHwnd() : m_hWnd;
	m_tnd.uID    = uID;
	m_tnd.hIcon  = icon;
	m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
	m_tnd.uCallbackMessage = uCallbackMessage;
	_tcscpy(m_tnd.szTip, szToolTip);
	// Set the tray icon
	VERIFY(m_bEnabled = Shell_NotifyIcon(NIM_ADD, &m_tnd));
	return m_bEnabled;
}
CSystemTray::~CSystemTray()
{
	RemoveIcon();
	m_IconList.RemoveAll();
	DestroyWindow();
}

/////////////////////////////////////////////////////////////////////////////
// CSystemTray icon manipulation
void CSystemTray::MoveToRight()
{
	HideIcon();
	ShowIcon();
}
void CSystemTray::RemoveIcon()
{
	if (!m_bEnabled) return;
	m_tnd.uFlags = 0;
	Shell_NotifyIcon(NIM_DELETE, &m_tnd);
	m_bEnabled = FALSE;
}

void CSystemTray::HideIcon()
{
	if (m_bEnabled && !m_bHidden) {
		m_tnd.uFlags = NIF_ICON;
		Shell_NotifyIcon (NIM_DELETE, &m_tnd);
		m_bHidden = TRUE;
	}
}

void CSystemTray::ShowIcon()
{
	if (m_bEnabled && m_bHidden) {
		m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
		Shell_NotifyIcon(NIM_ADD, &m_tnd);
		m_bHidden = FALSE;
	}
}

BOOL CSystemTray::SetIcon(HICON hIcon)
{
	if (!m_bEnabled) return FALSE;
	m_tnd.uFlags = NIF_ICON;
	m_tnd.hIcon = hIcon;
	return Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
}

BOOL CSystemTray::SetIcon(LPCTSTR lpszIconName)
{
	HICON hIcon = AfxGetApp()->LoadIcon(lpszIconName);
	return SetIcon(hIcon);
}
BOOL CSystemTray::SetIcon(UINT nIDResource)
{
	HICON hIcon = AfxGetApp()->LoadIcon(nIDResource);
	return SetIcon(hIcon);
}
BOOL CSystemTray::SetStandardIcon(LPCTSTR lpIconName)
{
	HICON hIcon = LoadIcon(NULL, lpIconName);
	return SetIcon(hIcon);
}

BOOL CSystemTray::SetStandardIcon(UINT nIDResource)
{
	HICON hIcon = LoadIcon(NULL, MAKEINTRESOURCE(nIDResource));
	return SetIcon(hIcon);
}
HICON CSystemTray::GetIcon() const
{
	return (m_bEnabled)? m_tnd.hIcon : NULL;
}
BOOL CSystemTray::SetIconList(UINT uFirstIconID, UINT uLastIconID) 
{
	if (uFirstIconID > uLastIconID)
		return FALSE;
	UINT uIconArraySize = uLastIconID - uFirstIconID + 1;
	const CWinApp * pApp = AfxGetApp();
	ASSERT(pApp != 0);
	m_IconList.RemoveAll();
	try {
		for (UINT i = uFirstIconID; i <= uLastIconID; i++)

			m_IconList.Add(pApp->LoadIcon(i));
	}
	catch (CMemoryException *e)
	{
		e->ReportError();
		e->Delete();
		m_IconList.RemoveAll();
		return FALSE;
	}
	return TRUE;
}
BOOL CSystemTray::SetIconList(HICON* pHIconList, UINT nNumIcons)
{
	m_IconList.RemoveAll();
	try {
		for (UINT i = 0; i <= nNumIcons; i++)
			m_IconList.Add(pHIconList[i]);

	}
	catch (CMemoryException *e)
	{
		e->ReportError();
		e->Delete();
		m_IconList.RemoveAll();
		return FALSE;
	}
	return TRUE;

}
BOOL CSystemTray::Animate(UINT nDelayMilliSeconds, int nNumSeconds /*=-1*/)
{
	StopAnimation();
	m_nCurrentIcon = 0;
	m_StartTime = COleDateTime::GetCurrentTime();
	m_nAnimationPeriod = nNumSeconds;
	m_hSavedIcon = GetIcon();
	// Setup a timer for the animation
	m_uIDTimer = SetTimer(m_nIDEvent, nDelayMilliSeconds, NULL);
	return (m_uIDTimer != 0);
}
//show next icon 
BOOL CSystemTray::StepAnimation()
{
	if (!m_IconList.GetSize())
		return FALSE;
	m_nCurrentIcon++;
	if (m_nCurrentIcon >= m_IconList.GetSize())
		m_nCurrentIcon = 0;
	return SetIcon(m_IconList[m_nCurrentIcon]);
}
BOOL CSystemTray::StopAnimation()
{
	BOOL bResult = FALSE;
	if (m_uIDTimer)
		bResult = KillTimer(m_uIDTimer);
	m_uIDTimer = 0;
	if (m_hSavedIcon)
		SetIcon(m_hSavedIcon);
	m_hSavedIcon = NULL;
	return bResult;
}
/////////////////////////////////////////////////////////////////////////////
// CSystemTray tooltip text manipulation
BOOL CSystemTray::SetTooltipText(LPCTSTR pszTip)
{
	if (!m_bEnabled) return FALSE;
	m_tnd.uFlags = NIF_TIP;
	_tcscpy(m_tnd.szTip, pszTip);
	return Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
}
BOOL CSystemTray::SetTooltipText(UINT nID)
{
	CString strText;
	VERIFY(strText.LoadString(nID));
	return SetTooltipText(strText);
}
CString CSystemTray::GetTooltipText() const
{
	CString strText;
	if (m_bEnabled)
		strText = m_tnd.szTip;
	return strText;
}
/////////////////////////////////////////////////////////////////////////////

// CSystemTray notification window stuff
BOOL CSystemTray::SetNotificationWnd(CWnd* pWnd)
{
	if (!m_bEnabled) return FALSE;
	// Make sure Notification window is valid
	ASSERT(pWnd && ::IsWindow(pWnd->GetSafeHwnd()));
	m_tnd.hWnd = pWnd->GetSafeHwnd();
	m_tnd.uFlags = 0;
	return Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
}
CWnd* CSystemTray::GetNotificationWnd() const
{
	return CWnd::FromHandle(m_tnd.hWnd);
}
/////////////////////////////////////////////////////////////////////////////

// CSystemTray menu manipulation
BOOL CSystemTray::SetMenuDefaultItem(UINT uItem, BOOL bByPos)
{

	if ((m_DefaultMenuItemID == uItem) && (m_DefaultMenuItemByPos == bByPos)) 
		return TRUE;
	m_DefaultMenuItemID = uItem;
	m_DefaultMenuItemByPos = bByPos;   
	CMenu menu, *pSubMenu;
	if (!menu.LoadMenu(m_tnd.uID)) return FALSE;
	if (!(pSubMenu = menu.GetSubMenu(0))) return FALSE;
	::SetMenuDefaultItem(pSubMenu->m_hMenu, m_DefaultMenuItemID, m_DefaultMenuItemByPos);
	return TRUE;

}
void CSystemTray::GetMenuDefaultItem(UINT& uItem, BOOL& bByPos)
{
	uItem  = m_DefaultMenuItemID;
	bByPos = m_DefaultMenuItemByPos;
}
/////////////////////////////////////////////////////////////////////////////
// CSystemTray message handlers
BEGIN_MESSAGE_MAP(CSystemTray, CWnd)
	//{{AFX_MSG_MAP(CSystemTray)
	ON_WM_TIMER()
	//}}AFX_MSG_MAP

END_MESSAGE_MAP()

void CSystemTray::OnTimer(UINT nIDEvent) 
{
	ASSERT(nIDEvent == m_nIDEvent);
	COleDateTime CurrentTime = COleDateTime::GetCurrentTime();
	COleDateTimeSpan period = CurrentTime - m_StartTime;
	if (m_nAnimationPeriod > 0 && m_nAnimationPeriod < period.GetTotalSeconds())
	{
		StopAnimation();
		return;
	}
	StepAnimation();
}

LRESULT CSystemTray::OnTrayNotification(UINT wParam, LONG lParam) 
{
	//Return quickly if its not for this tray icon
	if (wParam != m_tnd.uID)
		return 0L;
	CMenu menu, *pSubMenu;
	CWnd* pTarget = AfxGetMainWnd();
	// Clicking with right button brings up a context menu
	if (LOWORD(lParam) == WM_RBUTTONUP)
	{    
		if (!menu.LoadMenu(m_tnd.uID)) return 0;
		if (!(pSubMenu = menu.GetSubMenu(0))) return 0;
		// Make chosen menu item the default (bold font)
		::SetMenuDefaultItem(pSubMenu->m_hMenu, m_DefaultMenuItemID, m_DefaultMenuItemByPos);
		// Display and track the popup menu
		CPoint pos;
		GetCursorPos(&pos);
		pTarget->SetForegroundWindow();  
		::TrackPopupMenu(pSubMenu->m_hMenu, 0, pos.x, pos.y, 0, 
			pTarget->GetSafeHwnd(), NULL);
		// BUGFIX: See "PRB: Menus for Notification Icons Don't Work Correctly"
		pTarget->PostMessage(WM_NULL, 0, 0);
		menu.DestroyMenu();
	} 
	else if (LOWORD(lParam) == WM_LBUTTONDBLCLK) 
	{
		// double click received, the default action is to execute default menu item
		pTarget->ShowWindow(SW_SHOW);
		pTarget->SetForegroundWindow();  
		UINT uItem;
		if (m_DefaultMenuItemByPos)
		{
			if (!menu.LoadMenu(m_tnd.uID)) return 0;
			if (!(pSubMenu = menu.GetSubMenu(0))) return 0;
			uItem = pSubMenu->GetMenuItemID(m_DefaultMenuItemID);
		}
		else
			uItem = m_DefaultMenuItemID;
		pTarget->SendMessage(WM_COMMAND, uItem, 0);
		menu.DestroyMenu();
	}
	return 1;
}
LRESULT CSystemTray::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	if (message == m_tnd.uCallbackMessage)
		return OnTrayNotification(wParam, lParam);
	return CWnd::WindowProc(message, wParam, lParam);
}



使用如下:

对话框头文件

CSystemTray m_trayicon;

对话框cpp文件

m_trayicon.Create(this->m_pParentWnd,WM_NOTIFY,"Test",AfxGetApp()->LoadIcon(IDR_MAINFRAME),IDR_MENU1);

函数声明: BOOL Create(CWnd* pParent, UINT uCallbackMessage, LPCTSTR szTip, HICON icon, UINT uID);

this->m_pParentWnd:注意这里传递的窗口句柄必须是主窗口的父句柄。

WM_NOTIFY         :为自定义消息 关联消息映射 ON_MESSAGE(WM_NOTIFY,on_notify) LRESULT  on_notify(WPARAM wpara,LPARAM lpara);

szTip       :为鼠标移上托管图标的提示

AfxGetApp()->LoadIcon(IDR_MAINFRAME):显示的托管图标

IDR_MENU1:为鼠标右键点击托管图标后显示的菜单。

需要做到的是,用户点击minisizebox 主窗口隐藏 转为托管,在主窗口的cpp文件处理消息

void CRegisterDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else if(nID == SC_MINIMIZE)
	{
		m_trayicon.HideIcon();
		m_trayicon.MoveToRight();
		this->ShowWindow(SW_HIDE);
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}
到此系统托管图标完成。

你可能感兴趣的:(shell,File,null,application,animation,menu)