MFC 手把手教你实现托盘应用程序

概述:

什么是托盘应用程序?

当你打开后会在电脑最右下角的任务栏上生成一个系统托盘,当你点击最小化或者点击关闭按钮后,若想恢复窗口,可以左键双击或者单机这个系统图标,同时鼠标右键点击,又会有其他的菜单弹出,比如退出。像QQ等可以停靠在电脑桌面的右下方:

实现操作步骤

(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)修改对话框属性,设置最大化最小化按钮:

在解决方案资源管理器中点击TrayIcon.rc显示资源视图

右键对话框,选择属性,将最大化框和最小化框设置为true

(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,&CTrayIconDlg::OnTrayNotification)

放在图中位置:

②添加实现函数OnTrayNotification(WPARAM wParam, LPARAM lParam)

在TrayIconDlg.h声明函数:

public:
  LRESULT OnTrayNotification(WPARAM wParam, LPARAM lParam);

在TrayIconDlg.cpp实现函数:

在文件最开始的定义定义两个宏

#define ID_MENU_RECOVER 2001

#define ID_MENU_CLOSE 2002

作为菜单项的ID

LRESULT CTrayIconDlg::OnTrayNotification(WPARAM wParam, LPARAM lParam))
{
// TODO: 在此处添加实现代码.
switch (lParam)
{
case WM_RBUTTONDOWN://鼠标右键点击图标
                {
POINT point;
GetCursorPos(&point);//检索鼠标光标的位置(以屏幕坐标为单位)
CMenu menu;
menu.CreatePopupMenu();//创建弹出式菜单
menu.AppendMenuW(MF_STRING, ID_MENU_RECOVER, L"恢复");//添加菜单项
menu.AppendMenuW(MF_STRING, ID_MENU_CLOSE, L"关闭");
menu.TrackPopupMenu(TPM_RIGHTBUTTON, point.x, point.y, this);
}
break;
}
return LRESULT();
}

添加子菜单“恢复”的消息响应函数:

①添加消息响应的宏

ON_BN_CLICKED(ID_MENU_RECOVER, &CTrayIconDlg::OnRecover)

放在图示位置:

②添加实现函数OnTrayRestore()

OnTrayRestore()函数的实现:

void CTrayIconDlg::OnRecover()
{
// TODO: 在此处添加实现代码.
ShowWindow(SW_SHOW);
SetForegroundWindow();
}

为子菜单“退出”添加消息响应函数:

void CTrayIconDlg::OnTrayExit()
{
    EndDialog(IDCANCEL);
}

(8)整个项目完成,运行程序:

(9)完整示例代码:

链接:https://pan.baidu.com/s/1cXO1fukiZIdgfHkIQiAU2Q?pwd=ci97

提取码:ci97

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值