MFC 应用最小化到系统托盘

本指南将实现 MFC 应用程序在关闭时最小化系统托盘的功能,并左键和右键系统托盘图标进行交互。

目标:

  • 左键点击托盘图标:恢复对话框窗口。
  • 右键点击托盘图标 :弹出右键菜单,提供 恢复窗口 和 退出程序 两个选项。
  • 退出时删除托盘图标,并关闭对话框。

步骤详解:

1. 定义托盘图标的 ID 和所需资源

定义托盘图标的菜单项 ID,例如:

cpp 复制代码
#define ID_TRAY_RESTORE 1001  // 恢复窗口
#define ID_TRAY_EXIT 1002     // 退出程序

2. 定义成员变量和消息映射

在 CDlgMFCApplicationDlg 类的头文件中,定义托盘图标的数据结构和处理方法。

cpp 复制代码
private:
    NOTIFYICONDATA m_trayIconData;  // 托盘图标数据
    UINT m_nTrayIconID;             // 托盘图标ID
    BOOL m_bTrayIconCreated;        // 标记托盘图标是否创建成功

protected:
    afx_msg void OnClose();               	// 关闭窗口时的处理
    afx_msg LRESULT OnTrayIconClick(WPARAM wParam, LPARAM lParam);  // 托盘图标点击事件
    afx_msg void OnTrayRestore();          	// 恢复窗口
    afx_msg void OnTrayExit();             	// 退出应用

通过 ON_COMMAND 映射来处理菜单项的选择:

cpp 复制代码
BEGIN_MESSAGE_MAP(CDlgMFCApplicationDlg, CDialogEx)
    ON_WM_CLOSE()
    ON_MESSAGE(WM_USER + 1, &CDlgMFCApplicationDlg::OnTrayIconClick)  	// 托盘图标点击事件
    ON_COMMAND(ID_TRAY_RESTORE, &CDlgMFCApplicationDlg::OnTrayRestore)  // 恢复窗口
    ON_COMMAND(ID_TRAY_EXIT, &CDlgMFCApplicationDlg::OnTrayExit)  		// 退出程序
END_MESSAGE_MAP()

在 OnInitDialog() 中初始化托盘图标数据:

cpp 复制代码
m_trayIconData.cbSize = sizeof(NOTIFYICONDATA);  				// 设置托盘图标数据结构的大小
m_trayIconData.hWnd = m_hWnd;                    				// 设置窗口句柄
m_trayIconData.uID = m_nTrayIconID;              				// 设置托盘图标 ID
m_trayIconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;  		// 设置托盘图标的标志(图标、消息、提示文本)
m_trayIconData.uCallbackMessage = WM_USER + 1;   				// 设置回调消息(WM_USER + 1)
m_trayIconData.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);  	// 加载托盘图标
lstrcpy(m_trayIconData.szTip, _T("MFC Tray App"));   			// 设置托盘提示文本

// 添加托盘图标
Shell_NotifyIcon(NIM_ADD, &m_trayIconData);
m_bTrayIconCreated = TRUE;

3. 处理托盘图标点击事件

通过 OnTrayIconClick() 来响应托盘图标的点击事件。根据 lParam 的值判断是左键点击还是右键点击。

cpp 复制代码
LRESULT CDlgMFCApplicationDlg::OnTrayIconClick(WPARAM wParam, LPARAM lParam) {
    if (wParam == m_nTrayIconID) {
        if (LOWORD(lParam) == WM_LBUTTONUP) {
            // 左键点击恢复窗口
            ShowWindow(SW_SHOW);
            SetForegroundWindow();
        } else if (LOWORD(lParam) == WM_RBUTTONUP) {
            // 右键点击弹出菜单
            CMenu menu;
            menu.CreatePopupMenu();
            menu.AppendMenu(MF_STRING, ID_TRAY_RESTORE, _T("Restore"));
            menu.AppendMenu(MF_STRING, ID_TRAY_EXIT, _T("Exit"));

			// 获取鼠标当前位置,并显示菜单
            POINT pt;
            GetCursorPos(&pt);  
            menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this);
        }
    }
    return 0;
}

4. 实现右键菜单项处理方法

  • 恢复窗口:
cpp 复制代码
void CDlgMFCApplicationDlg::OnTrayRestore() {
    ShowWindow(SW_SHOW);  	// 恢复窗口
    SetForegroundWindow();  // 将窗口置于前端
}
  • 退出程序:
cpp 复制代码
void CDlgMFCApplicationDlg::OnTrayExit() {
    Shell_NotifyIcon(NIM_DELETE, &m_trayIconData);  // 删除托盘图标
    PostMessage(WM_CLOSE);  						// 关闭窗口并退出应用
}

5. 实现关闭窗口

在 OnClose() 中,询问用户是否希望将应用最小化到系统托盘,如果选择是,则隐藏窗口并保留托盘图标;否则直接退出。

cpp 复制代码
void CDlgMFCApplicationDlg::OnClose() {
    int nResult = AfxMessageBox(_T("Do you want to minimize the application to the system tray?"), MB_YESNO | MB_ICONQUESTION);
    
    if (nResult == IDYES) {
        ShowWindow(SW_HIDE);  // 隐藏窗口
    } else {
        Shell_NotifyIcon(NIM_DELETE, &m_trayIconData);  // 删除托盘图标
        CDialogEx::OnClose(); // 关闭对话框
    }
}

6. 清理托盘图标

在 OnTrayExit 或 OnClose 中删除托盘图标,并释放资源:

cpp 复制代码
Shell_NotifyIcon(NIM_DELETE, &m_trayIconData);  // 删除托盘图标

总结:

通过以上步骤,已经实现了以下功能:

  1. 当用户关闭窗口时,询问是要最小化到系统托盘还是退出应用程序。
  2. 左键单击托盘图标以恢复窗口。
  3. 右键单击托盘图标以显示上下文菜单,允许用户恢复窗口或退出应用程序。
相关推荐
qq_40698103几秒前
c++构造函数初始化列表
c++
王老师青少年编程15 分钟前
2026年9月GESP真题及题解(C++八级):末班车
c++·题解·真题·gesp·八级·2026年9月·末班车
cu14324 分钟前
细谈GM7123C的具体功能与其应用
c语言·c++·人工智能·嵌入式硬件
朝朝辞暮i1 小时前
C++ 第 10 课:函数 Function
开发语言·c++
Zootopia6261 小时前
快递无人车与无人机各自进入配送网络后,路线能否一起算?
c++·人工智能·机器学习·matlab·ai·机器人·无人机
朝朝辞暮i1 小时前
C++ 第7课 while 循环
开发语言·c++·算法
huanbailu3 小时前
Qt 跨线程信号槽:connect 返回 true 但槽函数不执行的坑
开发语言·c++·qt·信号槽·跨线程·元类型
HEJOO93 小时前
C++ 虚函数表(vtable)深度解析
开发语言·c++
xailorliu5 小时前
矩阵定性-正定负定不定半正定半负定
c++·opencv·线性代数·计算机视觉·矩阵
个 人 练 习 生5 小时前
C++-----string基本使用详解
开发语言·c++·学习