系统托盘
为程序添加系统托盘
1:创建菜单资源 ID: IDR_MENU_NOTIFY
2:添加子菜单
显示 IDM_NOTIFY_SHOW
退出 IDM_NOTIFY_CLOSE
3:查看MSDN Shell_NotifyIcon
1 BOOL Shell_NotifyIcon( //向系统托盘中加入图标 2 DWORD dwMessage, //状态 3 PNOTIFYICONDATA lpdata //含有图标 消息响应 的一个结构体);
4:认识NOTIFYICONDATA 结构体:
1 typedef struct _NOTIFYICONDATA { 2 DWORD cbSize; //结构体自身大小 这里一定要进行初始化 3 HWND hWnd; //托盘的父窗口 托盘发出的消息由哪一个窗口响应 4 UINT uID; //显示图标的ID 5 UINT uFlags; //托盘的状态 (如有图标,有气泡提示,有消息响应等) 6 UINT uCallbackMessage; //托盘事件的消息响应函数 7 HICON hIcon; //图标的变量 8 TCHAR szTip[64]; //气泡的显示文字 就是我们的鼠标停留在托盘图标上有文字显示 9 DWORD dwState; //图标的显示状态 10 DWORD dwStateMask; //图标的显示状态 11 TCHAR szInfo[256]; //气泡的显示文字 (可以忽略) 12 union { 13 UINT uTimeout; 14 UINT uVersion; 15 }; 16 TCHAR szInfoTitle[64]; 17 DWORD dwInfoFlags; 18 GUID guidItem; 19 HICON hBalloonIcon; 20 } NOTIFYICONDATA, *PNOTIFYICONDATA;
5:定义上述结构变量为类的成员变量 并在OnInitDialog函数中进行初始化添加代码
1 nid.cbSize = sizeof(NOTIFYICONDATA); //大小赋值 2 nid.hWnd = m_hWnd; //父窗口 是被定义在父类CWnd类中 3 nid.uID = IDR_MAINFRAME; //icon ID 4 nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; //托盘所拥有的状态 5 nid.uCallbackMessage = UM_ICONNOTIFY; //回调消息 6 nid.hIcon = m_hIcon; //icon 变量 7 CString str="Remote远程协助软件........."; //气泡提示 8 lstrcpyn(nid.szTip, (LPCSTR)str, sizeof(nid.szTip) / sizeof(nid.szTip[0])); 9 Shell_NotifyIcon(NIM_ADD, &nid); //显示托盘
6:声明自定义的回调消息:
UM_ICONNOTIFY 在Stdafx.h中添加 这里也使用枚举因为我们在工程的后期会有很多的自定义消息
如下:enum
{ UM_ICONNOTIFY=WM_USER+1 };
7:声明消息处理函数:
1 afx_msg void OnIconNotify(WPARAM wParam,LPARAM lParam); ---->这里很重要
8:添加消息响应:
1 ON_MESSAGE(UM_ICONNOTIFY, (LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM))OnIconNotify) 注:vc里面不需要(LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM))
9:实现消息响应函数
1 void CRemoteDlg::OnIconNotify(WPARAM wParam, LPARAM lParam) 2 { 3 switch ((UINT)lParam) 4 { 5 case WM_LBUTTONDOWN: 6 case WM_LBUTTONDBLCLK: 7 if (!IsWindowVisible()) 8 ShowWindow(SW_SHOW); 9 else 10 ShowWindow(SW_HIDE); 11 break; 12 case WM_RBUTTONDOWN: 13 CMenu menu; 14 menu.LoadMenu(IDR_MENU_NOTIFY); 15 CPoint point; 16 GetCursorPos(&point); 17 SetForegroundWindow(); //设置当前窗口 18 menu.GetSubMenu(0)->TrackPopupMenu( 19 TPM_LEFTBUTTON|TPM_RIGHTBUTTON, 20 point.x, point.y, this, NULL); 21 PostMessage(WM_USER, 0, 0); 22 break; 23 } 24 }
10:添加我们系统托盘的菜单响应函数 注意类的名称。
1 void CRemoteDlg::OnNotifyShow() ID_NOTIFY_SHOW 2 { 3 // TODO: 在此添加命令处理程序代码 4 ShowWindow(SW_SHOW); 5 } 6 7 11:void CRemoteDlg::OnNotifyClose() ID_NOTIFY_EXIT 8 9 { 10 // TODO: 在此添加命令处理程序代码 11 PostMessage(WM_CLOSE); 12 }
12:编译运行。我们发现系统的托盘图标不能迅速销毁
解决方案:
添加一个系统托盘的消息
1 afx_msg void OnClose(); 2 3 ON_WM_CLOSE() 4 5 void CRemoteDlg::OnClose() 6 { 7 // TODO: 在此添加消息处理程序代码和/或调用默认值 8 Shell_NotifyIcon(NIM_DELETE, &nid); 9 CDialogEx::OnClose(); 10 }
到此我们的托盘的大概设置就完毕了。