在VC++中,想实现最小化到系统托盘,需要调用NOTIFYICONDATA类,并注册相应的消息,以下详细讲解如何实现:
第一步,声明一个NOTIFYICONDATA类,也就是NOTIFYICONDATA NotifyIcon;该句可以放在Dlg类的声明中,作为Dlg类的一个成员;也可以放在Dlg类的实现中,作为全局变量来使用。
第二步,声明一个响应函数afx_msg void OnNotifyIcon(WPARAM wParam,LPARAM IParam);用于响应鼠标操作。将这个函数放入Dlg类的声明中,作为Dlg类的一个成员。
第三步,定义消息名称以消息号,并注册消息,该步很重要!我就是因为没有注册消息,导致调试了很久都找不到问题所在。该步都是在Dlg.cpp(Dlg的实现中)中操作。定义消息名称和消息号:#define WM_NC (WM_USER+1001),1001只是用于指定一个消息号,可以随便指定。注册则是在BEGIN_MESSAGE_MAP(Dlg,CDialog)和END_MESSAGE_MAP()之间添加ON_MESSAGE(WM_NC,OnNotifyIcon)。
第四步,在要将MFC最小化到系统托盘的函数中添加如下代码:
int CTestDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
m_nid.cbSize=sizeof(NOTIFYICONDATA);
m_nid.hWnd=this->m_hWnd;
m_nid.hIcon=m_hIcon;
m_nid.uFlags=NIF_ICON|NIF_TIP|NIF_MESSAGE;
m_nid.uCallbackMessage=WM_NOTIFYICONDATA;
CString szTip;
szTip=_T("PIC MODE CHANGE");
_tcscpy(m_nid.szTip,szTip);
::Shell_NotifyIcon(NIM_ADD,&m_nid);
return 0;
}
有了上面的代码,当程序运行到含有如上代码的函数时就会在系统托盘处添加一个图标,想隐藏主对话框,就再添加一句ShowWindow(SW_HIDE);这样就实现了将MFC最小化到系统托盘。但还要添加点击托盘图标时响应鼠标的函数,也就是第二步中的函数OnNOtifyIcon。
第五步,OnNOtifyIcon函数,如下:
LRESULT CTestDlg::OnNOtifyIcon(WPARAM wParam,LPARAM lParam)
{
int nRes=lParam;
switch(nRes)
{
case WM_LBUTTONDBLCLK:
{
AfxGetApp()->m_pMainWnd->ShowWindow(SW_SHOWNORMAL);
AfxGetApp()->m_pMainWnd->SetForegroundWindow();
::Shell_NotifyIcon(NIM_DELETE,&m_nid);
this->SetFocus();
}
break;
case WM_RBUTTONDOWN:
{
CMenu menu;
menu.LoadMenu(IDR_MENU1);
CMenu *pMenu=menu.GetSubMenu(0);
CPoint point;
GetCursorPos(&point);
pMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTALIGN|TPM_CENTERALIGN,point.x,point.y,AfxGetMainWnd());
}
break;
}
return false;
}
上面这个函数实现了双击鼠标左键显示主窗口和单击鼠标右键显示菜单的功能。对于上面函数中Shell_NotifyIcon(NIM_DELETE,&NotifyIcon)一句,是清除托盘图标,在这里可以没有,但在退出整个程序的时候一定要加上,不然程序退出了,托盘处还有一个图标,只有鼠标指到那里时系统才会发现是进程残留而清除,这种做法很不好!