MFC制作简单的托盘图标

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
在资源视图中添加
在这里插入图片描述
MFC制作简单的托盘图标_第1张图片
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();
	}
}

你可能感兴趣的:(MFC,c++)