MFC程序最小化到系统托盘及其响应函数
预备知识:
Windows API函数:
WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(
DWORD dwMessage,
PNOTIFYICONDATA pnid
);
该函数的两个参数:
第一个参数dwMessage可以取以下值:
NIM_ADD 向托盘中加入一个图标;
NIM_MODIFY 修改托盘中的图标
NIM_DELETE 从托盘中删除一个图标
NIM_MODIFY 修改托盘中的图标
NIM_DELETE 从托盘中删除一个图标
第二个参数pnid是NOTIFYICONDATA结构的一个引用。该结构的原型如下:
typedef struct _NOTIFYICONDATA { DWORD cbSize; // 结构的大小,必须在程序中给出 HWND hWnd; // 程序中将要接收托盘消息的窗口句柄 UINT uID; // 应用程序中定义的托盘图标ID,此参数用作标识 UINT uFlags; //设置属性 标记下边3个参数是否有效 UINT uCallbackMessage; // 自定义的消息ID值 HICON hIcon; //显示在系统托盘上的Icon的句柄 char szTip[64]; // 用于图标显示的提示字符串 } NOTIFYICONDATA, *PNOTIFYICONDATA;
具体步骤:
1.在CxxxDlg.h中增加一个私有的NOTIFYICONDAT对象和消息处理函数;
private: NOTIFYICONDATA m_notify; afx_msg LRESULT OnTrayMsg(WPARAM wparan, LPARAM lparam); //托盘处理函数 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);//最小化按键响应 afx_msg void OnDestroy();//程序退出时删除托盘图标 afx_msg void setTray();//设置托盘图标
2.WM_USER_NOTIFYICON是自定义的消息 在文件CxxxDlg.cpp文件开头中进行声明;
#define WM_USER_NOTIFYICON WM_USER+1
3.添加映射:
BEGIN_MESSAGE_MAP(CxxxDlg, CDialog)
ON_WM_SYSCOMMAND() ON_MESSAGE(WM_USER_NOTIFYICON, &CxxxDlg::OnTrayMsg) //}}AFX_MSG_MAP END_MESSAGE_MAP()
4.实现自定义的消息处理函数,在消息处理函数中对自定义的消息进行处理;
LRESULT CxxxDlg::OnTrayMsg(WPARAM wparam, LPARAM lparam);
LRESULT CxxxDlg::OnTrayMsg(WPARAM wparam, LPARAM lparam) { if(wparam!=IDR_MAINFRAME) return 1; switch(lparam) { case WM_RBUTTONUP://右键起来时弹出快捷菜单,这里只有一个“关闭” { LPPOINT lpoint=new tagPOINT; ::GetCursorPos(lpoint);//得到鼠标位置 CMenu menu; menu.CreatePopupMenu();//声明一个弹出式菜单 //增加菜单项“关闭”,点击则发送消息WM_DESTROY给主窗口(已 //隐藏),将程序结束。 menu.AppendMenu(MF_STRING,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_SHOWNORMAL);//显示主窗口 this->SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);//使窗口总是在最前面 this->SetWindowPos(&wndNoTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);//使窗口可以被其他窗口覆盖 } break; } return 0; }
void CxxxDlg::OnDestroy();
void CxxxDlg::OnDestroy() { CDialog::OnDestroy(); Shell_NotifyIcon(NIM_DELETE, &m_notify);//退出程序后删除图标 }
void CxxxDlg::setTray();
void CxxxDlg::setTray() { m_notify.cbSize = (DWORD)sizeof(NOTIFYICONDATA); m_notify.hWnd = this->m_hWnd; m_notify.uID = IDR_MAINFRAME; m_notify.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP; m_notify.uCallbackMessage = WM_USER_NOTIFYICON;//自定义的消息名称 m_notify.hIcon = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME)); strcpy(m_notify.szTip,"托盘程序"); //信息提示条 Shell_NotifyIcon(NIM_ADD,&m_notify); //在托盘区添加图标 ShowWindow(SW_HIDE); //隐藏主窗 }
void CxxxDlg::OnSysCommand(UINT nID, LPARAM lParam);
void CxxxDlg::OnSysCommand(UINT nID, LPARAM lParam) {
CDialog::OnSysCommand(nID, lParam); if(nID==SC_MINIMIZE) { setTray();//最小化到托盘 } }
完成。
参考资料: