当鼠标停留在图标上时,系统应显示提示信息tooltip;
当使用鼠标右键单击图标时,应用程序应显示快捷菜单;
当使用鼠标左键双击图标时,应用程序应执行快捷菜单的缺省菜单项。
在Microsoft Windows环境中,0x8000到0xBFFF的消息是保留的,应用程序可以定义自定义消息。
关于消息处理的详细内容,请参考下一部分。
源码及实现
在本文中关于任务栏图标的类叫做CTrayIcon,这个类由CCmdTarget(或CObject)类派生,它有如下的成员变量和成员函数:
// TrayIcon.h
// CTrayIcon command target
class CTrayIcon : public CCmdTarget
{
public:
NOTIFYICONDATA m_nid;//NOTIFYICONDATA结构,你的图标要用的啊
BOOL m_IconExist;//标志,看看图标是不是已经存在了
CWnd* m_NotificationWnd;//接受回调消息的窗口,有它就不必经常AfxGetMainWnd了
public:
CWnd* GetNotificationWnd() const;//得到m_NotificationWnd
BOOL SetNotificationWnd(CWnd* pNotifyWnd);//设置(更改)m_NotificationWnd
CTrayIcon();//构造函数
virtual ~CTrayIcon();//析构函数
BOOL CreateIcon(CWnd* pNotifyWnd, UINT uID, HICON hIcon,
LPSTR lpszTip, UINT CallBackMessage);//在任务栏上生成图标
BOOL DeleteIcon();//删除任务栏上的图标
virtual LRESULT OnNotify(WPARAM WParam, LPARAM LParam);//消息响应函数
BOOL SetTipText(UINT nID);//设置(更改)提示字串
BOOL SetTipText(LPCTSTR lpszTip);//设置(更改)提示字串
BOOL ChangeIcon(HICON hIcon);//更改图标
BOOL ChangeIcon(UINT nID);//更改图标
BOOL ChangeIcon(LPCTSTR lpszIconName);//更改图标
BOOL ChangeStandardIcon(LPCTSTR lpszIconName);//更改为标准图标
};
下面是成员函数的定义:
// TrayIcon.cpp
// CTrayIcon
CTrayIcon::CTrayIcon()
{//初始化参数
m_IconExist = FALSE;
m_NotificationWnd = NULL;
memset(&m_nid, 0, sizeof(m_nid));
m_nid.cbSize = sizeof(m_nid);//这个参数不会改变
}
CTrayIcon::~CTrayIcon()
{
if (m_IconExist)
DeleteIcon();//删除图标
}
BOOL CTrayIcon::CreateIcon(CWnd* pNotifyWnd, UINT uID, HICON hIcon,
LPSTR lpszTip, UINT CallBackMessage)
{
//确定接受回调消息的窗口是有效的
ASSERT(pNotifyWnd && ::IsWindow(pNotifyWnd->GetSafeHwnd()));
ASSERT(CallBackMessage >= WM_USER);//确定回调消息不发生冲突
ASSERT(_tcslen(lpszTip) <= 64);//提示字串不能超过64个字符
m_NotificationWnd = pNotifyWnd;//获得m_NotificationWnd
//设置NOTIFYICONDATA结构
m_nid.hWnd = pNotifyWnd->GetSafeHwnd();
m_nid.uID = uID;
m_nid.hIcon = hIcon;
m_nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
m_nid.uCallbackMessage = CallBackMessage;
//设置NOTIFYICONDATA结构的提示字串
if (lpszTip)
lstrcpyn(m_nid.szTip, lpszTip, sizeof(m_nid.szTip));
else
m_nid.szTip[0] = ''\0'';
//显示图标
m_IconExist = Shell_NotifyIcon(NIM_ADD, &m_nid);
return m_IconExist;
}
BOOL CTrayIcon::DeleteIcon()
{//删除图标
if (!m_IconExist)
return FALSE;
m_IconExist = FALSE;
return Shell_NotifyIcon(NIM_DELETE, &m_nid);
}
LRESULT CTrayIcon::OnNotify(WPARAM WParam, LPARAM LParam)
{//处理图标返回的消息
if (WParam != m_nid.uID)//如果不是该图标的消息则迅速返回
return 0L;
//准备快捷菜单
CMenu menu;
if (!menu.LoadMenu(IDR_POPUP))//你必须确定资源中有ID为IDR_POPUP的菜单
return 0;
CMenu* pSubMenu = menu.GetSubMenu(0);//获得IDR_POPUP的子菜