实现程序的托盘功能
思路
- 在程序启动的时候,加入设置托盘的操作。(封装成一个函数)
- 修改程序的最小化、关闭按钮的响应,使其隐藏。而不再关闭。
- 对托盘的图标加上一定的事件响应,如:左键双击还原,右键单击出现菜单
- 在程序结束时,删除掉图标。
依次放上代码:
- 封装函数CMainFrame::SetTray(void),并在在CMainFrame::OnCreate()调用:
注意需要将tnd的声明放在头文件里,作为全局变量,因为销毁时还要调用。
bool CMainFrame::SetTray(void)
{
//在头文件里设定托盘通知数据结构
//NOTIFYICONDATA tnd;
tnd.cbSize=sizeof(NOTIFYICONDATA);
tnd.hWnd=this->m_hWnd;
tnd.uID=IDR_MAINFRAME;//IDR_MSPMfrdasTYPE;
tnd.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP|NIF_INFO;
tnd.uCallbackMessage=WM_TRAY;
tnd.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
tnd.dwInfoFlags=NIIF_INFO;
wcscpy_s(tnd.szTip,_T("空间天气监控软件"));
wcscpy_s(tnd.szInfoTitle,_T("监控软件"));
wcscpy_s(tnd.szInfo,_T("空间天气监测站监控软件启动"));
tnd.uTimeout=3000;
Shell_NotifyIcon(NIM_ADD,&tnd);
return true;
}
- 修改最小化和关闭的响应:
void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
switch (nID)
{
case SC_MINIMIZE:
{
int iIsVisible = AfxGetApp()->GetMainWnd()->IsWindowVisible()? SW_HIDE:SW_SHOW;
ShowWindow(iIsVisible);
return;
}
case SC_CLOSE:
{
//从MainFrame得到Document的成员
CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
// Get the active MDI child window.
CMDIChildWnd *pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();
// or CMDIChildWnd *pChild = pFrame->MDIGetActive();
// Get the active view attached to the active MDI child
// window.
CMSVideoMonitorView *pView = (CMSVideoMonitorView *) pChild->GetActiveView();
//Get the active Document
CMSPMSDoc* pDoc = (CMSPMSDoc*)pView->GetDocument();
//////////////////////////////////////////////////////////////////////////
if (pDoc->m_bCloseToTray)
{
int iIsVisible = AfxGetApp()->GetMainWnd()->IsWindowVisible()? SW_HIDE:SW_SHOW;
ShowWindow(iIsVisible);
return;
}
else
{
PostMessage(WM_CLOSE);
return;
}
}
default:
Default();
break;
}
CBCGPMDIFrameWnd::OnSysCommand(nID, lParam);
}
- 对托盘图标加鼠标事件响应需要几步:
//自定义消息 #define WM_TRAY WM_USER+120
afx_msg LRESULT OnClickTray(WPARAM wParam, LPARAM lParam);
ON_MESSAGE(WM_TRAY,OnClickTray)
3.实现函数:
LRESULT CMainFrame::OnClickTray(WPARAM wParam, LPARAM lParam)
{
if(wParam!=IDR_MAINFRAME)
return 1;
switch(lParam)
{
case WM_RBUTTONUP: //右键起来时弹出快捷菜单,这里只有一个"关闭"
{
POINT lpoint;
::GetCursorPos(&lpoint); //得到鼠标位置
CMenu menu;
//执行相应操作
menu.LoadMenu(IDR_MENU_Tray);
HMENU hMenu = menu.GetSubMenu (0)->Detach();
CBCGPPopupMenu* pMenu = GetWorkspace ()->GetContextMenuManager()->ShowPopupMenu (
hMenu, lpoint.x, lpoint.y, this, TRUE);
pMenu->SetForegroundWindow ();
}break;
case WM_LBUTTONDBLCLK: //双击左键的处理
{
this->ShowWindow(SW_SHOW); //简单的显示主窗口完事儿
}break;
}
return 0;
}
其中菜单需要在资源管理器里设计好,并为之添加响应函数。
void CMainFrame::OnTrayClose()
{
// TODO: 在此添加命令处理程序代码
PostMessage(WM_CLOSE);
}
- 在结束时销毁图标
void CMainFrame::OnDestroy()
{
CBCGPMDIFrameWnd::OnDestroy();
// TODO: 在此处添加消息处理程序代码
Shell_NotifyIcon(NIM_DELETE,&tnd);
}
浙公网安备 33010602011771号