背景
有些时候需要程序在最小化的时候可以看到程序进度,甚至需要完全关闭界面,只留下托盘显示,这篇文章就是在这个背景下诞生的,其实很简单,但是比较少用到,这里做个笔记记录一下。
干货
直接上代码
//启动隐藏主窗口和任务栏 1
ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW); //隐藏任务栏
ShowWindow(SW_HIDE);
//启动显示主窗口和任务栏 2
ModifyStyleEx(WS_EX_TOOLWINDOW, WS_EX_APPWINDOW); //显示任务栏
ShowWindow(SW_SHOW);
//处理托盘程序 3
NOTIFYICONDATA m_tnd;
//初始化托盘 4
m_tnd.cbSize = sizeof(NOTIFYICONDATA);
m_tnd.hWnd = m_hWnd;
m_tnd.uID = IDR_MAINFRAME;
m_tnd.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
m_tnd.uCallbackMessage = WM_NOTIFYICON;
m_tnd.hIcon = m_hIcon;
//添加第一条消息 5
wcscpy_s(m_tnd.szTip, _T("第一条消息"));
Shell_NotifyIcon(NIM_ADD, &m_tnd);
//消息写到托盘 6
wcscpy_s(m_tnd.szTip, Message.GetBuffer());
Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
//更新消息 7
PostMessage(WM_UPDATE_MESSAGE, 0, 0);
解析
以上就是所有需要的代码
控制窗口显示
在主窗口中任意地方使用1的代码,主窗口和任务栏就隐藏了,使用2的代码,主窗口和任务栏就显示
其中ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);切换了显示的模式,WS_EX_APPWINDOW是显示任务栏,WS_EX_TOOLWINDOW是显示在托盘,这个函数还有更多参数可以自己去看和试一试
初始化托盘
一般在主界面的头文件添加3,声明一个托盘句柄,然后通过4初始化托盘,参数也很多,可以修改一下看看区别
添加第一条消息
添加消息使用5,修改消息使用6.
其实主要是wcscpy_s(m_tnd.szTip, Message.GetBuffer());将消息写到托盘的缓存,然后Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
把消息发送出去NIM_ADD,NIM_MODIFY分别是添加和修改,看需要自己选择,我就添加了一次,后面都是使用的修改。
更新界面
最后如果有消息没有即时刷新,就需要使用7进行一个刷新提示,他并不会立马刷新界面,只是提示系统要repaint。
结束啦
关于托盘的问题就这些了欢迎指正。结尾彩蛋附windows窗口改变形状,窗口所有控件等比缩放。
只需要重载OnSize(UINT nType, int cx, int cy),在函数里面添加一下代码就可以了
if (old.x == 0 || old.y == 0)
{
return;
}
float fsp[2];
POINT Newp; //获取现在对话框的大小
CRect recta;
GetClientRect(&recta); //取客户区大小
Newp.x = recta.right - recta.left;
Newp.y = recta.bottom - recta.top;
fsp[0] = (float)Newp.x / old.x;
fsp[1] = (float)Newp.y / old.y;
TextSizeRate = min(fsp[0], fsp[1]);
CRect Rect;
int woc;
CPoint OldTLPoint, TLPoint; //左上角
CPoint OldBRPoint, BRPoint; //右下角
HWND hwndChild = ::GetWindow(m_hWnd, GW_CHILD); //列出所有控件
while (hwndChild) {
woc = ::GetDlgCtrlID(hwndChild);//取得ID
Rect = ItemRect[woc];
OldTLPoint = Rect.TopLeft();
TLPoint.x = long(OldTLPoint.x * fsp[0]);
TLPoint.y = long(OldTLPoint.y * fsp[1]);
OldBRPoint = Rect.BottomRight();
BRPoint.x = long(OldBRPoint.x * fsp[0]);
BRPoint.y = long(OldBRPoint.y * fsp[1]);
Rect.SetRect(TLPoint, BRPoint);
GetDlgItem(woc)->MoveWindow(Rect, TRUE);
hwndChild = ::GetWindow(hwndChild, GW_HWNDNEXT);
}