概述:
什么是托盘应用程序?
当你打开后会在电脑最右下角的任务栏上生成一个系统托盘,当你点击最小化或者点击关闭按钮后,若想恢复窗口,可以左键双击或者单机这个系统图标,同时鼠标右键点击,又会有其他的菜单弹出,比如退出。像QQ等可以停靠在电脑桌面的右下方:
实现操作步骤
(1)首先新建一个MFC项目
(2)在CTrayIconDlg.cpp文件中的OnInitDialog()添加代码,使程序产生作用:
添加的代码:
//设置系统托盘
NOTIFYICONDATA NotifyIcon;
NotifyIcon.cbSize = sizeof(NOTIFYICONDATA);
//NotifyIcon.hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
NotifyIcon.hIcon = m_hIcon; //上面那句也可以
NotifyIcon.hWnd = m_hWnd;
lstrcpy(NotifyIcon.szTip, _T("我的托盘程序"));
NotifyIcon.uCallbackMessage = WM_ICON_NOTIFY;//自定义消息
NotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
Shell_NotifyIcon(NIM_ADD, &NotifyIcon); //添加系统托盘
WM_ICON_NOTIFY:是后面我们要定义的程序响应菜单。
(3) 在CTrayIconDlg.cpp文件的最开始位置添加一个自定义消息
#define WM_ICON_NOTIFY WM_USER+100
此时,编译运行程序,可以发现程序图标已经在窗口栏中:
将鼠标移动到右下角的下标,会显示“我的托盘程序”。
(4)添加OnClose()消息,当关闭程序时使图标消失
实现代码:
void CTrayIconDlg::OnClose()
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
NOTIFYICONDATA nd = { 0 };
nd.cbSize = sizeof(NOTIFYICONDATA);
nd.hWnd = m_hWnd;
nd.uID = IDR_MAINFRAME;
nd.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nd.uCallbackMessage = WM_ICON_NOTIFY;
nd.hIcon = m_hIcon;
Shell_NotifyIcon(NIM_DELETE, &nd);
CDialogEx::OnClose();
}
此时,运行程序,关闭窗口,会发现右下角的图标会同时消失。
(5)修改对话框属性,使之能够最小化按钮:
(6)在TrayIconDlg.cpp中的OnSysCommand(UINT nID, LPARAM lParam)函数添加以下代码,相应最小化按钮
if (nID == SC_MINIMIZE)
{
ShowWindow(FALSE);//隐藏窗口
}
即:
void CTrayIconDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
if (nID == SC_MINIMIZE)
{
ShowWindow(FALSE);//隐藏窗口
}
}
此时,运行程序,点击右下角的图标,发现没有相应,并且只能通过 任务管理器 关闭程序
(7)添加图标的左键和右键消息响应
①添加消息响应的宏
ON_MESSAGE(WM_ICON_NOTIFY,OnTrayNotification)
放在图中位置:
②添加实现函数OnTrayNotification(WPARAM wParam, LPARAM lParam)
在TrayIconDlg.h声明函数:
protected:
LRESULT OnTrayNotification(WPARAM wParam, LPARAM lParam);
在TrayIconDlg.cpp实现函数:
LRESULT CTrayIconDlg::OnTrayNotification(WPARAM wParam, LPARAM lParam)
{
switch (lParam)
{
case WM_LBUTTONDOWN://点击左键,调出程序
{
AfxGetApp()->m_pMainWnd->ShowWindow(SW_SHOWNORMAL);
SetForegroundWindow();
break;
}
case WM_RBUTTONUP://点击右键,出现选择菜单
{
POINT point;
HMENU hMenu, hSubMenu;
GetCursorPos(&point); //鼠标位置
hMenu = LoadMenu(NULL,
MAKEINTRESOURCE(IDR_MENU_TRAY)); //菜单的ID
hSubMenu = GetSubMenu(hMenu, 0);
SetForegroundWindow();
TrackPopupMenu(hSubMenu, 0,
point.x, point.y, 0, m_hWnd, NULL);
break;
}
}
return 0;
}
③添加菜单IDR_MENU_TRAY
总体名为:TRAY
修改菜单的ID:
添加“恢复”子菜单:
添加“退出”子菜单:
添加子菜单“恢复”的消息响应函数:
OnTrayRestore()函数的实现:
void CTrayIconDlg::OnTrayRestore()
{
// TODO: 在此添加命令处理程序代码
AfxGetApp()->m_pMainWnd->ShowWindow(SW_SHOWNORMAL);
SetForegroundWindow();
}
为子菜单“退出”添加消息响应函数:
void CTrayIconDlg::OnTrayExit()
{
// TODO: 在此添加命令处理程序代码
OnClose();
}
(8)整个项目完成,运行程序:
(9)项目的完整代码:
链接:https://pan.baidu.com/s/11OCyRR5Y3lvAyuLMFSAZJw 密码:qpaq
参考资料:
1. https://blog.csdn.net/u013051748/article/details/45621937
2.https://ke.qq.com/course/253301