1.头文件.h:
//添加全局变量
#define WM_NC (WM_USER + 1) //托盘消息
const CString TRAY_TIP("Bulk Data Export");
//添加成员变量与成员函数
private:
NOTIFYICONDATA m_stNotifyIcon; // 托盘图标
void InitTray();//初始化托盘图标
protected:
afx_msg void OnClose();//WM_CLOSE消息响应
afx_msg LRESULT OnNotifyIcon(WPARAM wParam, LPARAM lParam);//托盘消息相应
afx_msg void OnUpdateTrayShow(CCmdUI* pCmdUI);//对托盘鼠标右键消息ID_TRAY_SHOW的响应
afx_msg void OnUpdateTrayQuit(CCmdUI* pCmdUI);//对托盘鼠标右键消息ID_TRAY_QUIT的响应
/*为了防止用户定义的消息ID与系统的消息ID冲突,MS定义了一个宏WM_USER,小于WM_USER的ID被系统使用,大于 WM_USER的ID被用户使用。所以是WM_USER +1 */
TRAY_TIP:当鼠标移动到托盘图标时显示的信息字符串的声明
2.资源文件.rc
在资源视图中添加
Quit的资源ID为ID_TRAY_QUIT
Show的资源ID为ID_TRAY_SHOW
3.源文件.cpp
//析构函数中添加
Shell_NotifyIcon(NIM_DELETE, &m_stNotifyIcon);//删除托盘图标
//消息映射中添加
BEGIN_MESSAGE_MAP(CBulkDataExportDlg, CDialogEx)
ON_MESSAGE(WM_NC, &CBulkDataExportDlg::OnNotifyIcon)
ON_UPDATE_COMMAND_UI(ID_TRAY_SHOW, &CBulkDataExportDlg::OnUpdateTrayShow)
ON_UPDATE_COMMAND_UI(ID_TRAY_QUIT, &CBulkDataExportDlg::OnUpdateTrayQuit)
ON_WM_CLOSE()
END_MESSAGE_MAP()
//OnInitDialog()的定义中添加
InitTray();//初始化托盘参数
//增加以下函数的实现
void CBulkDataExportDlg::OnClose()
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (MessageBox(L"确实要退出吗?", L"提示", MB_OKCANCEL | MB_ICONWARNING) == IDOK)
{
CDialogEx::OnClose();
}
}
//设定托盘参数
void CBulkDataExportDlg::InitTray()
{
m_stNotifyIcon.cbSize = (DWORD)sizeof(NOTIFYICONDATA);
m_stNotifyIcon.hWnd = this->m_hWnd;
m_stNotifyIcon.hIcon = m_hIcon/*AfxGetApp()->LoadIcon(IDR_MAINFRAME)*/;//加载托盘图标资源
m_stNotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
m_stNotifyIcon.uCallbackMessage = WM_NC;
wcscpy_s(m_stNotifyIcon.szTip, TRAY_TIP);//信息提示
ShowWindow(SW_HIDE);
Shell_NotifyIcon(NIM_ADD, &m_stNotifyIcon);//在托盘区添加图标
}
//托盘消息相应
LRESULT CBulkDataExportDlg::OnNotifyIcon(WPARAM wParam, LPARAM lParam)
{
if ((lParam == WM_LBUTTONDOWN) ||
(lParam == WM_LBUTTONDBLCLK))
{
ModifyStyleEx(0, WS_EX_TOPMOST);
ShowWindow(SW_SHOWNORMAL);
SetForegroundWindow();//在最前端显示
}
else if ((lParam == WM_RBUTTONDOWN))
{
CMenu menuPopup;
menuPopup.LoadMenu(IDR_MENU_TRAY);
CMenu* subMenu = menuPopup.GetSubMenu(0);
if (nullptr == subMenu)return 0;
CPoint pos;
GetCursorPos(&pos);
SetForegroundWindow(); //失去焦点时菜单自动消失
subMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
pos.x, pos.y, FromHandle(m_stNotifyIcon.hWnd), NULL);
}
return 0;
}
void CBulkDataExportDlg::OnUpdateTrayShow(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
ModifyStyleEx(0, WS_EX_TOPMOST);
ShowWindow(SW_SHOWNORMAL);
}
void CBulkDataExportDlg::OnUpdateTrayQuit(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
::PostMessage(this->GetSafeHwnd(), WM_CLOSE, NULL, NULL);
}
注:如果只是想点击关闭时最小化(隐藏)程序,点击托盘的Quit时提示是否退出程序,以下两个函数可这样设计:
void CBulkDataExportDlg::OnClose()
{
ShowWindow(SW_HIDE);
}
void CBulkDataExportDlg::OnUpdateTrayQuit(CCmdUI* pCmdUI)
{
if (MessageBox(L"确实要退出吗?", L"提示", MB_OKCANCEL | MB_ICONWARNING) == IDOK)
{
CDialogEx::OnClose();
}
}