环境:VisualStudio2022
框架: MFC 对话框窗体
功能:托盘
对话框类:CBLToolsDlg
作者:CDamogu
时间:20220308
效果展示
头文件
1.1 头文件声明
头文件声明如下:
//最小化图表到托盘
public:
#define WM_SYSTEMTRAY WM_USER+1001 //最小化图表到托盘用到
NOTIFYICONDATA m_nid;
static DWORD WINAPI NotifyIconProc(LPVOID lpParameter);
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
afx_msg void OnDestroy();
CPP文件
2.1 初始化
// TODO: Add your message handler code here and/or call default
HICON m_hicon = ::LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_ICON_M));//[大蘑菇Mark][BEGIN]加载一个托盘图标
m_nid.cbSize = sizeof(NOTIFYICONDATA);
m_nid.hWnd = m_hWnd; //指定窗口句柄
m_nid.uID = IDI_ICON_M;
m_nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; //指定有效成员
m_nid.uCallbackMessage = WM_SYSTEMTRAY; //自定义消息
m_nid.hIcon = m_hicon; //指定托盘图标
wcscpy_s(m_nid.szTip, _T("[MushroomerV1.00]")); //添加气泡提示
::Shell_NotifyIcon(NIM_ADD, &m_nid); //在托盘区添加图标
//HANDLE hNotifyTherad = CreateThread(NULL, 0, NotifyIconProc, (LPVOID)&m_nid, 0, NULL);//创建一个线程来更新托盘图标
//CloseHandle(hNotifyTherad); //[大蘑菇Mark][END]
//下述功能放在OnClose中可以实现点击X,然后最小化到托盘,并且取消任务栏显示
//最小化窗口
//ShowWindow(SW_MINIMIZE);
//修改风格使得他不在任务栏显示(但是会引起一个问题就说窗体不显示icon)
//ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);
2.2 功能实现
/********************************************************************************************************/
/* 功能:WindowProc() //托盘
/********************************************************************************************************/
LRESULT CBLToolsDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO:在此添加专用代码和/或调用基类
switch (message)
{
case WM_SYSCOMMAND:
if (wParam == SC_MINIMIZE)
{
CBLToolsDlg* dlg = (CBLToolsDlg*)AfxGetApp()->GetMainWnd();//获取窗口CWnd指针
HWND hwnd = dlg->m_hWnd;//获取h_hWnd指针
::ShowWindow(hwnd, 0);//隐藏界面
return TRUE;
}
if (wParam == SC_RESTORE)
{
}
break;
case WM_CLOSE:
Shell_NotifyIcon(NIM_DELETE, &m_nid);//关闭软件时卸载托盘图标
break;
case WM_SYSTEMTRAY:
{
if (wParam != IDI_ICON_M)
return 1;
switch (lParam)
{
case WM_RBUTTONUP://右键起来时弹出快捷菜单,这里只有一个"关闭"
{
CMenu menu;
LPPOINT lpoint = new tagPOINT;
::GetCursorPos(lpoint); // 得到鼠标位置
menu.CreatePopupMenu(); // 声明一个弹出式菜单
SetForegroundWindow();//如果点击弹出菜单的时候,菜单失去焦点让菜单自动关闭
menu.AppendMenu(MF_STRING, WM_DESTROY, _T("设置"));// 增加菜单项"关闭",点击则发送消息WM_DESTROY 给主窗口(已隐藏),将程序结束
menu.AppendMenu(MF_STRING, WM_DESTROY, _T("关于"));// 增加菜单项"关闭",点击则发送消息WM_DESTROY 给主窗口(已隐藏),将程序结束
menu.AppendMenu(MF_STRING, WM_DESTROY, _T("退出"));// 增加菜单项"关闭",点击则发送消息WM_DESTROY 给主窗口(已隐藏),将程序结束
//此类型的菜单需要自定义消息,做消息映射和相关的消息响应函数
menu.TrackPopupMenu(TPM_LEFTALIGN, lpoint->x, lpoint->y, this);// 确定弹出式菜单的位置
HMENU hmenu = menu.Detach();
menu.DestroyMenu();// 资源回收
delete lpoint;// 资源回收
break;
}
case WM_LBUTTONDBLCLK://双击左键的处理
{
//修改风格使得他取消不在任务栏显示的模式至正常模式,可以显示icon
ModifyStyleEx(WS_EX_TOOLWINDOW, WS_EX_APPWINDOW);
this->ShowWindow(SW_NORMAL);//简单的显示主窗口完事儿
break;
}
case WM_LBUTTONDOWN://单击左键的处理
{
this->ShowWindow(SW_SHOW);//简单的显示主窗口完事儿
break;
}
}
}
break;
}
return CDialogEx::WindowProc(message, wParam, lParam);
}
/********************************************************************************************************/
/* 功能:NotifyIconProc() 托盘图表
/********************************************************************************************************/
DWORD WINAPI CBLToolsDlg::NotifyIconProc(LPVOID lpParameter)
{
NOTIFYICONDATA* pnotifyicon = (NOTIFYICONDATA*)lpParameter;//把传递进来的指针转换
/先在工程里面调入几个图标
HICON m_hstateicon_1 = ::LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));//加载4个图标
HICON m_hstateicon_2 = ::LoadIcon(AfxGetInstanceHandle(), NULL);//空图标
HICON m_hstateicon_3 = ::LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
HICON m_hstateicon_4 = ::LoadIcon(AfxGetInstanceHandle(), NULL);
不断的切换托盘图标
/*初始化线程关闭了图标切换,这边也关闭掉
while (true)
{
pnotifyicon->uFlags = NIF_ICON;
pnotifyicon->hIcon = m_hstateicon_1;
::Shell_NotifyIcon(NIM_MODIFY, pnotifyicon);
Sleep(400);//400ms切换一次
pnotifyicon->uFlags = NIF_ICON;
pnotifyicon->hIcon = m_hstateicon_2;
::Shell_NotifyIcon(NIM_MODIFY, pnotifyicon);
Sleep(400);//400ms切换一次
pnotifyicon->uFlags = NIF_ICON;
pnotifyicon->hIcon = m_hstateicon_3;
::Shell_NotifyIcon(NIM_MODIFY, pnotifyicon);
Sleep(400);//400ms切换一次
pnotifyicon->uFlags = NIF_ICON;
pnotifyicon->hIcon = m_hstateicon_4;
::Shell_NotifyIcon(NIM_MODIFY, pnotifyicon);
Sleep(400);//400ms切换一次
}
*/
return 0;
}
/********************************************************************************************************/
/* 功能:OnDestroy()
/********************************************************************************************************/
void CBLToolsDlg::OnDestroy()
{
CDialogEx::OnDestroy();
// TODO: Add your message handler code here
Shell_NotifyIcon(NIM_DELETE, &m_nid);//关闭软件时卸载托盘图标
}