让一个程序托盘显示,并且右键托盘图标可以弹出菜单
1. 在对话框类中添加一个NOTIFYICONDATA变量:
NOTIFYICONDATA m_Nid;
2. 初始化NOTIFYICONDATA变量
//初始化NOTIFYICONDATA m_Nid.cbSize = sizeof(NOTIFYICONDATA); //指定结构体大小 m_Nid.hWnd = m_hWnd; //指定接收通告消息的窗口句柄.系统就是通过hWnd和uID来辨别当Shell_NotifyIcon函数调用的时候操作的是哪个托盘图标 m_Nid.uID = 0; //应用程序定义的任务栏图标表示符。一个hWnd可以有很多的图标与之关联,这是通过指定不同的uID实现的 m_Nid.hIcon = AfxGetApp()->LoadIcon(IDI_TRAY_ICON); //要操作(添加、删除、修改)的图标句柄 m_Nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE; //标记那些成员有效 m_Nid.uCallbackMessage = WM_COMMAND; //当鼠标在图标区域内发生了事件,比如单击、双击时,系统会把这个消息发送到hWnd成员对应的窗口,然后该窗口可以处理该事件。这里可以不是WM_COMMAND,可以自定义消息,然后响应这个消息 TCHAR szTitle[] = _T("企业培训管理系统"); _tcscpy(m_Nid.szTip, szTitle); //当鼠标放在tray icon上面的时候显示的文字
3.调用Shell_NotifyIcon(NIM_ADD, &m_Nid);函数添加、删除或者修改图标
Shell_NotifyIcon(NIM_ADD, &m_Nid);
4.窗口销毁时记得删除icon
void CTrainingSystemDlg::OnDestroy() { CDialog::OnDestroy(); Shell_NotifyIcon(NIM_DELETE, &m_Nid); }
5.添加一个菜单,并且添加消息响应
void CTrainingSystemDlg::OnShowMaindlg() { // 把窗口放在最前方 SetForegroundWindow(); ShowWindow(SW_SHOW); }
6.在对话框中声明消息响应函数:
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
7.本来还应该BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间添加一个响应宏,但是这里我选择发送的是WM_COMMAND,所以直接重写类的OnCommand函数就行了。如果是你自定义的消息,就应该在这里添加ON_MESSAGE来响应你自定义的消息
8.响应上面NOTIFYICONDATA结构体中uCallbackMessage成员定义的消息。这里就是WM_COMMAND,当然可以是别的自定义消息。
BOOL CTrainingSystemDlg::OnCommand(WPARAM wParam, LPARAM lParam) { if (!wParam)//wParam为0表示消息来自一个菜单 { switch (lParam) { case WM_RBUTTONDOWN: { CMenu menu, *pMenu; menu.LoadMenu(IDR_TRAY_MENU); pMenu = menu.GetSubMenu(0); POINT ptPos; GetCursorPos(&ptPos); pMenu->SetDefaultItem(IDM_SHOW_MAINDLG); SetForegroundWindow();//这一行代码很重要,否则右键菜单工作//不正常。详见msdn说明: http://support.microsoft.com/kb/135788 pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, ptPos.x, ptPos.y, this); } break; case WM_LBUTTONDBLCLK: SetForegroundWindow(); ShowWindow(SW_SHOW); break; } } return CDialog::OnCommand(wParam, lParam); }