有关的数据由NOTIFYICONDATA结构描述:
| typedef struct _NOTIFYICONDATA { DWORD cbSize; //结构的大小,必须设置 HWND hWnd; //接受回调消息的窗口的句柄 UINT uID; //应用程序定义的图标标志 UINT uFlags; //标志,可以是NIF_ICON、NIF_MESSAGE、NIF_TIP或其组合 UINT uCallbackMessage;//应用程序定义的回调消息标志 HICON hIcon; //图标句柄 char szTip[64]; //提示字串 } NOTIFYICONDATA, *PNOTIFYICONDATA; |
函数说明
由Shell_NotifyIcon()函数向系统发送添加、删除、更改图标的消息。
| WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(DWORD dwMessage,PNOTIFYICONDATA pnid); |
DwMessage为所发送消息的标志:
NIM_ADD 添加图标到任务栏通知区;
NIM_DELETE 删除任务栏通知区的图标;
NIM_MODIFY 更改任务栏通知区的图标、回调消息标志、回调窗口句柄或提示字串;
pnid为NOTIFYICONDATA结构的指针。
回调信息的获得及处理
如果一个任务栏图标有应用程序定义的回调消息,那么当这个图标有鼠标操作时,系统将给hWnd所标志的窗口发送下列的消息:
| messageID = uCallbackMessage wParam = uID lParam = mouse event(例如WM_LBUTTONDOWN) |
通过这种方式,系统通知应用程序用户对图标的操作。如果一个应用程序生成了两个以上的图标,那么你可以根据wParam来判断是哪个图标返回的鼠标操作。通常,标准的Win95任务栏图标有以下鼠标操作响应:
当鼠标停留在图标上时,系统应显示提示信息tooltip;
当使用鼠标右键单击图标时,应用程序应显示快捷菜单;
当使用鼠标左键双击图标时,应用程序应执行快捷菜单的缺省菜单项。
在Microsoft Windows环境中,0x8000到0xBFFF的消息是保留的,应用程序可以定义自定义消息。
关于消息处理的详细内容,请参考下一部分。
源码及实现
在本文中关于任务栏图标的类叫做CTrayIcon,这个类由CCmdTarget(或CObject)类派生,它有如下的成员变量和成员函数:
// TrayIcon.h class CTrayIcon : public CCmdTarget |
下面是成员函数的定义:
// TrayIcon.cpp CTrayIcon::CTrayIcon() CTrayIcon::~CTrayIcon() BOOL CTrayIcon::CreateIcon(CWnd* pNotifyWnd, UINT uID, HICON hIcon, ASSERT(CallBackMessage >= WM_USER);//确定回调消息不发生冲突 ASSERT(_tcslen(lpszTip) <= 64);//提示字串不能超过64个字符 m_NotificationWnd = pNotifyWnd;//获得m_NotificationWnd //设置NOTIFYICONDATA结构 //设置NOTIFYICONDATA结构的提示字串 //显示图标 BOOL CTrayIcon::DeleteIcon() LRESULT CTrayIcon::OnNotify(WPARAM WParam, LPARAM LParam) //准备快捷菜单 if (LParam == WM_RBUTTONUP) //设置第一个菜单项为缺省 //显示并跟踪菜单 BOOL CTrayIcon::SetTipText(LPCTSTR lpszTip) _tcscpy(m_nid.szTip, lpszTip); return Shell_NotifyIcon(NIM_MODIFY, &m_nid); BOOL CTrayIcon::SetTipText(UINT nID) return SetTipText(szTip); m_nid.hIcon = hIcon; return Shell_NotifyIcon(NIM_MODIFY, &m_nid); BOOL CTrayIcon::ChangeIcon(UINT nID) BOOL CTrayIcon::ChangeIcon(LPCTSTR lpszIconName) BOOL CTrayIcon::ChangeStandardIcon(LPCTSTR lpszIconName) BOOL CTrayIcon::SetNotificationWnd(CWnd * pNotifyWnd) //确定窗口是有效的 m_NotificationWnd = pNotifyWnd; return Shell_NotifyIcon(NIM_MODIFY, &m_nid); CWnd* CTrayIcon::GetNotificationWnd() const |
三点补充:
关于使用回调消息的补充说明:
首先,在MainFrm.cpp中加入自己的消息代码;
| // MainFrm.cpp : implementation of the CMainFrame class // #define MYWM_ICONNOTIFY WM_USER + 10//定义自己的消息代码 |
第二步增加消息映射和函数声明,对于自定义消息不能由ClassWizard添加消息映射,只能手工添加。
| // MainFrm.cpp : implementation of the CMainFrame class BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) //{{AFX_MSG_MAP(CMainFrame) //其他的消息映射 ...... //}}AFX_MSG_MAP ON_MESSAGE(WM_ICONNOTIFY,OnNotify) END_MESSAGE_MAP() 并且在头文件中添加函数声明 // MainFrm.h afx_msg LRESULT OnNotify(WPARAM WParam, LPARAM LParam); |
第三步增加消息处理函数定义
| LRESULT CMainFrame::OnNotify(WPARAM WParam, LPARAM LParam) { return trayicon.OnNotify(WParam, LParam);//调用CTrayIcon类的处理函数 } |
如何隐藏任务栏上的按钮
可以使用下列两种方法:
1.在CreateWindowEx函数中使用WS_EX_TOOLWINDOW窗口式样(相反的如果要确保应用程序在任务栏上生成按钮,可以使用WS_EX_APPWINDOW窗口式样)。 The problem with this is that the window decorations are as for a small floating toolbar, which isn't normally what's wanted.
2.生成一个空的隐藏的top-level窗口,并使其作为可视窗口的父窗口。
3.在应用程序的InitInstance()函数中使用SW_HIDE式样调用ShowWindow()函数。
| //pMainFrame->ShowWindow(m_nCmdShow); pMainFrame->ShowWindow(SW_HIDE); pMainFrame->UpdateWindow(); |
如何动画任务栏上的图标
在TrayIcon类中加入下列两个函数:
BOOL CTrayIcon::SetAnimateIcons(HICON* hIcon, UINT Number) m_AnimateIcons = new HICON[Number]; BOOL CTrayIcon::Animate(UINT Index) |
怎样在应用程序中添加相应的菜单和函数
void CMainFrame::OnMenuAnimate() void CMainFrame::OnTimer(UINT nIDEvent) CMDIFrameWnd::OnTimer(nIDEvent); |