MFC实现窗口关闭为最小化托盘
新建一个 MinTray 的MFC工程(基于Dialog),
在 MinTrayDlg.h 头文件中,自定义消息 WM_SHOWTASK
////////////////// MinTrayDlg.h /////////////// #pragma once #define WM_SHOWTASK (WM_USER +1) //自定义消息WM_SHOWTASK //添加成员函数 class CMinTrayDlg : public CDialogEx { //.... afx_msg LRESULT OnShowTask(WPARAM wParam, LPARAM lParam);//wParam接收的是图标的ID,而lParam接收的是鼠标的行为 //1、最小化的原理:首先要将窗口隐藏,然后在右下角绘制图标。 //2、恢复的原理:将窗口显示,再将托盘中的图片删除。 void ToTray();//最小化窗口到托盘 void DeleteTray();////删除托盘图标函数 }
在 MinTrayDlg.cpp 中
// MinTrayDlg.cpp : 实现文件 BEGIN_MESSAGE_MAP(CMinTrayDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_MESSAGE(WM_SHOWTASK, OnShowTask) //其中WM_SHOWTASK是消息名,OnShowTask是自己定义的消息响应函数 END_MESSAGE_MAP() void CMinTrayDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else if (nID == SC_CLOSE)//右上角的关闭和标题栏的关闭WM_CLOSE { ToTray();//最小化到托盘 } else { CDialogEx::OnSysCommand(nID, lParam); } } LRESULT CMinTrayDlg::OnShowTask(WPARAM wParam, LPARAM lParam) {//wParam接收的是图标的ID,而lParam接收的是鼠标的行为 if (wParam != IDR_MAINFRAME) return 1; switch (lParam) { case WM_RBUTTONUP://右键起来时弹出快捷菜单,这里只有一个“关闭” { LPPOINT lpoint = new tagPOINT; ::GetCursorPos(lpoint);//得到鼠标位置 CMenu menu; menu.CreatePopupMenu();//声明一个弹出式菜单 menu.AppendMenu(MF_STRING, WM_DESTROY, L"关闭"); //增加菜单项“关闭”,点击则发送消息WM_DESTROY给主窗口(已隐藏),将程序结束。 menu.TrackPopupMenu(TPM_LEFTALIGN, lpoint->x, lpoint->y, this); //确定弹出式菜单的位置 HMENU hmenu = menu.Detach(); menu.DestroyMenu(); //资源回收 delete lpoint; } break; case WM_LBUTTONDBLCLK: //双击左键的处理 { this->ShowWindow(SW_SHOW);//简单的显示主窗口完事儿 DeleteTray(); } break; default: break; } return 0; } //最小化窗口到托盘 void CMinTrayDlg::ToTray() { NOTIFYICONDATA nid; nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA); nid.hWnd = this->m_hWnd; nid.uID = IDR_MAINFRAME; nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; nid.uCallbackMessage = WM_SHOWTASK;//自定义的消息名称 nid.hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME)); wcscpy(nid.szTip, L"程序名称"); //信息提示条 Shell_NotifyIcon(NIM_ADD, &nid); //在托盘区添加图标 ShowWindow(SW_HIDE); //隐藏主窗口 } //删除托盘图标函数 void CMinTrayDlg::DeleteTray() { NOTIFYICONDATA nid; nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA); nid.hWnd = this->m_hWnd; nid.uID = IDR_MAINFRAME; nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; nid.uCallbackMessage = WM_SHOWTASK; //自定义的消息名称 nid.hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME)); wcscpy(nid.szTip, L"程序名称"); //信息提示条为“计划任务提醒” Shell_NotifyIcon(NIM_DELETE, &nid); //在托盘区删除图标 }
另外:MFC中屏蔽 Esc 和 Enter 关闭窗口(由于Esc直接调用 OnCancel(),Enter 直接调用 OnOk())
方法一:
在头文件中
protected: virtual BOOL PreTranslateMessage(MSG* pMsg); // PreTranslateMessage是消息在送给TranslateMessage函数之前被调用的 public: virtual void OnOK();
在cpp文件中
BOOL CxxxDlg::PreTranslateMessage(MSG* pMsg) { //屏蔽ESC关闭窗体/ if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_ESCAPE ) return TRUE; //屏蔽回车关闭窗体,但会导致回车在窗体上失效. //if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_RETURN && pMsg->wParam) return TRUE; else return CDialog::PreTranslateMessage(pMsg); } void CxxxDlg::OnOK() { //CDialogEx::OnOK(); }
方法二:
////////////////// 头文件 ///////// public: virtual void OnOK(); virtual void OnCancel(); afx_msg void OnClose(); //响应关闭事件! /////////////// cpp文件 ///////////////// void CxxxDlg::OnOK() { return; } void CxxxDlg::OnCancel() { return; } void CxxxDlg::OnClose() { // TODO: 在此添加消息处理程序代码和/或调用默认值 CDialogEx::OnCancel(); //CDialogEx::OnClose(); }
常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。
昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。