这是一个类///////////////////////////////////////////////////////////////////////////// // TrayIcon.h : header file //#ifndef _INCLUDED_TRAYICON_H_ #define _INCLUDED_TRAYICON_H_///////////////////////////////////////////////////////////////////////////// // CTrayIcon windowclass CTrayIcon : public CObject { // Construction/destruction public: CTrayIcon(); CTrayIcon(CWnd* pWnd, UINT uCallbackMessage, LPCTSTR szTip, HICON icon, UINT uID); virtual ~CTrayIcon();// Operations public: BOOL Enabled() { return m_bEnabled; } BOOL Visible() { return !m_bHidden; } //Create the tray icon Create(CWnd* pWnd, 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 lpIconName); BOOL SetIcon(UINT nIDResource); BOOL SetStandardIcon(LPCTSTR lpIconName); BOOL SetStandardIcon(UINT nIDResource); HICON GetIcon() const; void HideIcon(); void ShowIcon(); void RemoveIcon(); void MoveToRight(); //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(CTrayIcon) //}}AFX_VIRTUAL// Implementation protected: BOOL m_bEnabled; // does O/S support tray icon? BOOL m_bHidden; // Has the icon been hidden? NOTIFYICONDATA m_tnd; DECLARE_DYNAMIC(CTrayIcon) }; #endif/////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////// // TrayIcon.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 "CTrayIconifyIcon" (http://indigo.ie/~pjn/ntray.html) // especially the "CTrayIcon::OnTrayNotification" member function. // // 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. // // CTrayIcon m_TrayIcon; // Member variable of some class // // ... // // in some member function maybe... // m_TrayIcon.Create(pParentWnd, WM_MY_NOTIFY, "Click here", // hIcon, nTrayIconID); // // Clobbered together by Chris Maunder. // // /////////////////////////////////////////////////////////////////////////////#include "stdafx.h" #include "TrayIcon.h"#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endifIMPLEMENT_DYNAMIC(CTrayIcon, CObject)///////////////////////////////////////////////////////////////////////////// // CTrayIcon construction/creation/destructionCTrayIcon::CTrayIcon() { memset(&m_tnd, 0, sizeof(m_tnd)); m_bEnabled = FALSE; m_bHidden = FALSE; }CTrayIcon::CTrayIcon(CWnd* pWnd, UINT uCallbackMessage, LPCTSTR szToolTip, HICON icon, UINT uID) { Create(pWnd, uCallbackMessage, szToolTip, icon, uID); m_bHidden = FALSE; }BOOL CTrayIcon::Create(CWnd* pWnd, 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 VERIFY(m_bEnabled = (pWnd && ::IsWindow(pWnd->GetSafeHwnd()))); if (!m_bEnabled) return FALSE;
HICON CTrayIcon::GetIcon() const { HICON hIcon = NULL; if (m_bEnabled) hIcon = m_tnd.hIcon; return hIcon; }///////////////////////////////////////////////////////////////////////////// // CTrayIcon tooltip text manipulationBOOL CTrayIcon::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 CTrayIcon::SetTooltipText(UINT nID) { CString strText; VERIFY(strText.LoadString(nID)); return SetTooltipText(strText); }CString CTrayIcon::GetTooltipText() const { CString strText; if (m_bEnabled) strText = m_tnd.szTip; return strText; }///////////////////////////////////////////////////////////////////////////// // CTrayIcon notification window stuffBOOL CTrayIcon::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* CTrayIcon::GetNotificationWnd() const { return CWnd::FromHandle(m_tnd.hWnd); }///////////////////////////////////////////////////////////////////////////// // CTrayIcon implentation of OnTrayNotificationLRESULT CTrayIcon::OnTrayNotification(UINT wParam, LONG lParam) { //Return quickly if its not for this tray icon if (wParam != m_tnd.uID) return 0L; CMenu menu, *pSubMenu; // 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 first menu item the default (bold font) ::SetMenuDefaultItem(pSubMenu->m_hMenu, 0, TRUE); //Display and track the popup menu CPoint pos; GetCursorPos(&pos); ::SetForegroundWindow(m_tnd.hWnd); ::TrackPopupMenu(pSubMenu->m_hMenu, 0, pos.x, pos.y, 0, m_tnd.hWnd, NULL); //pSubMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pos.x, pos.y, this, NULL); menu.DestroyMenu(); } else if (LOWORD(lParam) == WM_LBUTTONDBLCLK) { if (!menu.LoadMenu(m_tnd.uID)) return 0; if (!(pSubMenu = menu.GetSubMenu(0))) return 0; // double click received, the default action is to execute first menu item ::SetForegroundWindow(m_tnd.hWnd); ::SendMessage(m_tnd.hWnd, WM_COMMAND, pSubMenu->GetMenuItemID(0), 0); menu.DestroyMenu(); } return 1; } 下面是出处和用法,很好用的// 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 "CTrayIconifyIcon" (http://indigo.ie/~pjn/ntray.html) // especially the "CTrayIcon::OnTrayNotification" member function. // // 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. // // CTrayIcon m_TrayIcon; // Member variable of some class // // ... // // in some member function maybe... // m_TrayIcon.Create(pParentWnd, WM_MY_NOTIFY, "Click here", // hIcon, nTrayIconID); // // Clobbered together by Chris Maunder. // //
{
cs.style =WS_POPUP;//使主窗口不可见
cs.dwExStyle |=WS_EX_TOOLWINDOW;//不显示任务按钮
return CFrameWnd::PreCreateWindow(cs);
} 二、将表示程序运行的图标加入任务栏 在主框架窗口的CMainFrame::OnCreate()函数中调用上述函数,就可以在任务条上显示图标这一步是利用系统API函数Shell_NotifyIcon()将一个图标显示在任务栏的通告区中。该函数的原型为:在调用该函数之前,需要确定其参数的取值。其中Shell_NotifyIcon()函数的第一个参数是一个预定义的消息,可以取如下值之一:NIM_ADD、NIM_DELETE或NIM_MODIFY,分别表示添加图标、删除图标或修改图标。另一个参数为指向NOTIFYICONDATA类型的指针。其原型为: typedef struct _NOTIFYICONDATA {
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
charszTip[64]; }
NOTIFYICONDATA 在该结构的成员中,cbSize为该结构所占的字节数,hWnd为接受该图标所发出的消息的窗口的句柄(鼠标在任务栏上程序图标上动作时图标将发出消息,这个消息用户要自己定义),uID为被显示图标的ID,uFlags指明其余的几个成员(hIcon、uCallBackMessage和szTip)的值是否有效,uCallbackMessage为一个用户自定义的消息,当用户在该图标上作用一些鼠标动作时,图标将向应用程序的主框架窗口(hWnd成员中指定的窗口)发出该消息,。hIcon为将在任务栏上被显示图标的句柄,szTip鼠标停留在该图标上时显示的字符串。 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
NOTIFYICONDATA tnd;
tnd.cbSize=sizeof(NOTIFYICONDATA);
tnd.hWnd=this->m_hWnd;
tnd.uID=IDR_MAINFRAME;
tnd.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;
tnd.uCallbackMessage=WM_MYMESSAGE;
file://用户自定义的消息,即鼠标在任务栏上程序图标上动作时图标发送的消息
tnd.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
strcpy(tnd.szTip,"测试程序");//图标提示为"测试程序"
Shell_NotifyIcon(NIM_ADD,&tnd);//向任务栏添加图标
三、用户与程序交互的实现 用户进行交互,也就是当用户在该图标上单击或双击鼠标左键或右键时要执行相应的操作,至少也要响应用户终止该程序的意愿。上面已经提到,当用户在图标上进行鼠标动作时,将向hWnd成员中指定的窗口发出自定义的消息,该消息为uCallbackMessage成员所指定的WM_MYESSAGE,取值为WM_USER+101(如何自定义消息,我就不多说了)。我们要实现任务就是在hWnd窗口中响应该自定义消息: void CMainFrame::OnMYMESSAGE(WPARAM wParam,LPARAM lParam)
{
UINT uID;//发出该消息的图标的ID
UINT uMouseMsg;//鼠标动作
POINT pt;
uID=(UINT) wParam;
uMouseMsg=(UINT) lParam;
if(uMouseMsg==WM_RBUTTONDOWN)//如果是单击右键
{
switch(uID)
{
case IDR_MAINFRAME://如果是我们的图标
GetCursorPos(&pt);//取得鼠标位置
AfxGetApp( )-> m_pMainWnd->ShowWindow(SW_SHOWNORMAL);//显示程序窗口
break;
default:
}
}
return;
}
四、程序结束时删除程序图标 当程序结束时,需要删去通告区中的图标,这时还应该调用Shell_NotifyIcon函数,只不过第一个参数是表示删除图标的NIM_DELETE了: void CMainFrame::~CmainFrame()
{
NOTIFYICONDATA tnid;
tnid.cbSize=sizeof(NOTIFYICONDATA);
tnid.hWnd=this->m_hWnd;
tnid.uID=IDR_MAINFRAME;//保证删除的是我们的图标
Shell_NotifyIcon(NIM_DELETE,&tnid);
} 上述实现步骤可以实现托盘程序,笔者在开发的IC卡程序中就应用了以上技术,希望可以对朋友们有所帮助。
// TrayIcon.h : header file
//#ifndef _INCLUDED_TRAYICON_H_
#define _INCLUDED_TRAYICON_H_/////////////////////////////////////////////////////////////////////////////
// CTrayIcon windowclass CTrayIcon : public CObject
{
// Construction/destruction
public:
CTrayIcon();
CTrayIcon(CWnd* pWnd, UINT uCallbackMessage, LPCTSTR szTip, HICON icon, UINT uID);
virtual ~CTrayIcon();// Operations
public:
BOOL Enabled() { return m_bEnabled; }
BOOL Visible() { return !m_bHidden; } //Create the tray icon
Create(CWnd* pWnd, 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 lpIconName);
BOOL SetIcon(UINT nIDResource);
BOOL SetStandardIcon(LPCTSTR lpIconName);
BOOL SetStandardIcon(UINT nIDResource);
HICON GetIcon() const;
void HideIcon();
void ShowIcon();
void RemoveIcon();
void MoveToRight(); //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(CTrayIcon)
//}}AFX_VIRTUAL// Implementation
protected:
BOOL m_bEnabled; // does O/S support tray icon?
BOOL m_bHidden; // Has the icon been hidden?
NOTIFYICONDATA m_tnd; DECLARE_DYNAMIC(CTrayIcon)
};
#endif/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// TrayIcon.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 "CTrayIconifyIcon" (http://indigo.ie/~pjn/ntray.html)
// especially the "CTrayIcon::OnTrayNotification" member function.
//
// 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.
//
// CTrayIcon m_TrayIcon; // Member variable of some class
//
// ...
// // in some member function maybe...
// m_TrayIcon.Create(pParentWnd, WM_MY_NOTIFY, "Click here",
// hIcon, nTrayIconID);
//
// Clobbered together by Chris Maunder.
//
//
/////////////////////////////////////////////////////////////////////////////#include "stdafx.h"
#include "TrayIcon.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endifIMPLEMENT_DYNAMIC(CTrayIcon, CObject)/////////////////////////////////////////////////////////////////////////////
// CTrayIcon construction/creation/destructionCTrayIcon::CTrayIcon()
{
memset(&m_tnd, 0, sizeof(m_tnd));
m_bEnabled = FALSE;
m_bHidden = FALSE;
}CTrayIcon::CTrayIcon(CWnd* pWnd, UINT uCallbackMessage, LPCTSTR szToolTip,
HICON icon, UINT uID)
{
Create(pWnd, uCallbackMessage, szToolTip, icon, uID);
m_bHidden = FALSE;
}BOOL CTrayIcon::Create(CWnd* pWnd, 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
VERIFY(m_bEnabled = (pWnd && ::IsWindow(pWnd->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); // load up the NOTIFYICONDATA structure
m_tnd.cbSize = sizeof(NOTIFYICONDATA);
m_tnd.hWnd = pWnd->GetSafeHwnd();
m_tnd.uID = uID;
m_tnd.hIcon = icon;
m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
m_tnd.uCallbackMessage = uCallbackMessage;
strcpy (m_tnd.szTip, szToolTip); // Set the tray icon
VERIFY(m_bEnabled = Shell_NotifyIcon(NIM_ADD, &m_tnd));
return m_bEnabled;
}CTrayIcon::~CTrayIcon()
{
RemoveIcon();
}
/////////////////////////////////////////////////////////////////////////////
// CTrayIcon icon manipulationvoid CTrayIcon::MoveToRight()
{
HideIcon();
ShowIcon();
}void CTrayIcon::RemoveIcon()
{
if (!m_bEnabled) return; m_tnd.uFlags = 0;
Shell_NotifyIcon(NIM_DELETE, &m_tnd);
m_bEnabled = FALSE;
}void CTrayIcon::HideIcon()
{
if (m_bEnabled && !m_bHidden) {
m_tnd.uFlags = NIF_ICON;
Shell_NotifyIcon (NIM_DELETE, &m_tnd);
m_bHidden = TRUE;
}
}void CTrayIcon::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 CTrayIcon::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 CTrayIcon::SetIcon(LPCTSTR lpszIconName)
{
HICON hIcon = AfxGetApp()->LoadIcon(lpszIconName); return SetIcon(hIcon);
}BOOL CTrayIcon::SetIcon(UINT nIDResource)
{
HICON hIcon = AfxGetApp()->LoadIcon(nIDResource); return SetIcon(hIcon);
}BOOL CTrayIcon::SetStandardIcon(LPCTSTR lpIconName)
{
HICON hIcon = LoadIcon(NULL, lpIconName); return SetIcon(hIcon);
}BOOL CTrayIcon::SetStandardIcon(UINT nIDResource)
{
HICON hIcon = LoadIcon(NULL, MAKEINTRESOURCE(nIDResource)); return SetIcon(hIcon);
}
HICON CTrayIcon::GetIcon() const
{
HICON hIcon = NULL;
if (m_bEnabled)
hIcon = m_tnd.hIcon; return hIcon;
}/////////////////////////////////////////////////////////////////////////////
// CTrayIcon tooltip text manipulationBOOL CTrayIcon::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 CTrayIcon::SetTooltipText(UINT nID)
{
CString strText;
VERIFY(strText.LoadString(nID)); return SetTooltipText(strText);
}CString CTrayIcon::GetTooltipText() const
{
CString strText;
if (m_bEnabled)
strText = m_tnd.szTip; return strText;
}/////////////////////////////////////////////////////////////////////////////
// CTrayIcon notification window stuffBOOL CTrayIcon::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* CTrayIcon::GetNotificationWnd() const
{
return CWnd::FromHandle(m_tnd.hWnd);
}/////////////////////////////////////////////////////////////////////////////
// CTrayIcon implentation of OnTrayNotificationLRESULT CTrayIcon::OnTrayNotification(UINT wParam, LONG lParam)
{
//Return quickly if its not for this tray icon
if (wParam != m_tnd.uID)
return 0L; CMenu menu, *pSubMenu; // 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 first menu item the default (bold font)
::SetMenuDefaultItem(pSubMenu->m_hMenu, 0, TRUE); //Display and track the popup menu
CPoint pos;
GetCursorPos(&pos);
::SetForegroundWindow(m_tnd.hWnd);
::TrackPopupMenu(pSubMenu->m_hMenu, 0, pos.x, pos.y, 0, m_tnd.hWnd, NULL); //pSubMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pos.x, pos.y, this, NULL);
menu.DestroyMenu();
}
else if (LOWORD(lParam) == WM_LBUTTONDBLCLK)
{
if (!menu.LoadMenu(m_tnd.uID)) return 0;
if (!(pSubMenu = menu.GetSubMenu(0))) return 0; // double click received, the default action is to execute first menu item
::SetForegroundWindow(m_tnd.hWnd);
::SendMessage(m_tnd.hWnd, WM_COMMAND, pSubMenu->GetMenuItemID(0), 0);
menu.DestroyMenu();
} return 1;
}
下面是出处和用法,很好用的// 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 "CTrayIconifyIcon" (http://indigo.ie/~pjn/ntray.html)
// especially the "CTrayIcon::OnTrayNotification" member function.
//
// 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.
//
// CTrayIcon m_TrayIcon; // Member variable of some class
//
// ...
// // in some member function maybe...
// m_TrayIcon.Create(pParentWnd, WM_MY_NOTIFY, "Click here",
// hIcon, nTrayIconID);
//
// Clobbered together by Chris Maunder.
//
//