实现程序的托盘功能

思路

  • 在程序启动的时候,加入设置托盘的操作。(封装成一个函数)
  • 修改程序的最小化、关闭按钮的响应,使其隐藏。而不再关闭。
  • 对托盘的图标加上一定的事件响应,如:左键双击还原,右键单击出现菜单
  • 在程序结束时,删除掉图标。
依次放上代码:
  • 封装函数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);
}
  • 对托盘图标加鼠标事件响应需要几步:
1添加自定义消息:

//自定义消息
#define WM_TRAY WM_USER+120
2 定义消息响应函数并添加消息映射
afx_msg LRESULT OnClickTray(WPARAM wParam, LPARAM lParam);
ON_MESSAGE(WM_TRAY,OnClickTray)
  其中,wParam携带的是发消息的窗口,lParam携带的是鼠标事件的代码。
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);  
}

  

posted on 2011-09-05 18:40  LateStop  阅读(603)  评论(0)    收藏  举报

导航