1)定义CallbackMessage消息WM_MYNOTIFYICON
2)定义NOTIFYICONDATA m_nid并初始化, 其中m_nid.uCallbackMessage = WM_MYNOTIFYICON
3)添加WM_MYNOTIFYICON的消息处理函数LRESULT OnMyNotifyIcon(WPARAM, LPARAM)
4)Shell_NotifyIcon (NIM_ADD, &m_nid)添加
5)注册并处理TaskbarCreated消息来重建图标LRESULT OnTaskBarCreated(WPARAM, LPARAM)
6)Shell_NotifyIcon(NIM_DELETE, &m_nid);删除图标
Method - 1
1)添加菜单资源(ID,菜单项显示的文本)
2)添加菜单项处理函数,如OnContextmenuShowHide
3)加载菜单资源m_oMyMenu.LoadMenu(IDR_MYCONTEXTMENU)
4)显示菜单pMenuContext->TrackPopupMenu
Method - 2
1)定义菜单项ID
2)创建菜单oPopupMenu.CreatePopupMenu()
3)添加菜单项oPopupMenu.AppendMenu(flag, ID, 文本)
4)显示菜单oPopupMenu.TrackPopupMenu
5)销毁菜单oPopupMenu.DestroyMenu();
class CMyClientDlg : public CDialogEx
{
... ...
public:
afx_msg void OnClose();
afx_msg void OnContextmenuShowHide();
afx_msg LRESULT OnMyNotifyIcon(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnTaskBarCreated(WPARAM wParam, LPARAM lParam);
private:
BOOL InitialBarIcons();
BOOL ShowBalloonTip(LPCTSTR szInfo, LPCTSTR szInfoTitle=_T("title"), DWORD dwInfoFlags = NIIF_INFO);
NOTIFYICONDATA m_nid;
CMenu m_oMyMenu;//Menu Method 1
}
#define WM_MYNOTIFYICON (WM_USER + 100)
//重启explorer.exe时重建任务栏图标
const UINT WM_TASKBARCREATED = ::RegisterWindowMessage(_T("TaskbarCreated"));
BEGIN_MESSAGE_MAP(CMyClientDlg, CDialogEx)
... ...
ON_WM_CLOSE()
ON_MESSAGE(WM_MYNOTIFYICON, &CMyClientDlg::OnMyNotifyIcon)
ON_REGISTERED_MESSAGE(WM_TASKBARCREATED, &CMyClientDlg::OnTaskBarCreated)
ON_COMMAND(ID_CONTEXTMENU_SHOW_HIDE, &CMyClientDlg::OnContextmenuShowHide)
END_MESSAGE_MAP()
BOOL CMyClientDlg::OnInitDialog()
{
... ...
InitialBarIcons();
... ...
}
BOOL CMyClientDlg::InitialBarIcons()
{//创建任务栏图标,初始化右键菜单
m_nid.cbSize =sizeof(NOTIFYICONDATA);
m_nid.hWnd =m_hWnd;
m_nid.uID = 0;
m_nid.hIcon =m_hIcon;
m_nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP|NIF_INFO;
m_nid.uCallbackMessage = WM_MYNOTIFYICON;
_tcscpy_s(m_nid.szTip, _T("Dictionary - Client"));
_tcscpy_s(m_nid.szInfo, _T("Dictionary Client is running"));
_tcscpy_s(m_nid.szInfoTitle, _T("Dictionary Client"));
m_nid.dwInfoFlags = NIIF_INFO;
m_nid.uTimeout = 1500;
if(NULL == m_oMyMenu.GetSafeHmenu())//Menu - Method 1
m_oMyMenu.LoadMenu(IDR_MYCONTEXTMENU);//menu for bar
return Shell_NotifyIcon (NIM_ADD, &m_nid);
}
BOOL CMyClientDlg::ShowBalloonTip(LPCTSTR szInfo, LPCTSTR szInfoTitle, DWORD dwInfoFlags /*= NIIF_INFO*/)
{//显示气泡通知
m_nid.cbSize = sizeof(NOTIFYICONDATA);
m_nid.uFlags = NIF_INFO;
_tcscpy_s(m_nid.szInfo, szInfo);
_tcscpy_s(m_nid.szInfoTitle, szInfoTitle);
m_nid.dwInfoFlags = dwInfoFlags;//NIIF_INFO;
m_nid.uTimeout = 1500;//deprecated as of Windows Vista
return Shell_NotifyIcon(NIM_MODIFY, &m_nid);
}
LRESULT CMyClientDlg::OnTaskBarCreated(WPARAM wParam, LPARAM lParam)
{//重建任务栏图标
InitialBarIcons();
return 0;
}
void CMyClientDlg::OnClose()
{//退出时删除托盘图标
Shell_NotifyIcon(NIM_DELETE, &m_nid);
CDialogEx::OnClose();
}
void CMyClientDlg::OnContextmenuShowHide()
{//右键菜单响应
if(IsWindowVisible ())
ShowWindow (SW_HIDE );
else
ShowWindow (SW_SHOWNORMAL );
}
LRESULT CMyClientDlg::OnMyNotifyIcon(WPARAM wParam, LPARAM lParam)
{
switch(lParam)
{
case WM_LBUTTONDBLCLK://双击托盘图标, 显示窗体
ShowWindow (SW_SHOWNORMAL );
SetForegroundWindow();
break;
case WM_RBUTTONUP://右键, 弹出菜单
{
//Method 1 - use Menu resource: m_oMyMenu.LoadMenu(IDR_MYCONTEXTMENU)
//CMenu* pMenuContext = m_oMyMenu.GetSubMenu(0);
//if(NULL != pMenuContext)
//{
// CPoint pos;
// GetCursorPos(&pos);
// SetForegroundWindow();//加这句是为了鼠标点击其他地方时,弹出的菜单能够消失
// pMenuContext->TrackPopupMenu(TPM_RIGHTBUTTON |TPM_RIGHTALIGN, pos.x+1, pos.y+1, this);
//}
//Method 2 - Add when need
CMenu oPopupMenu;
if(!oPopupMenu.CreatePopupMenu()||NULL == oPopupMenu.GetSafeHmenu())
return 0;
oPopupMenu.AppendMenu(0/*MF_STRING|MF_POPUP|MF_DISABLED|MF_GRAYED*/, ID_CONTEXTMENU_SHOW_HIDE, _T("Show/HIde"));
oPopupMenu.AppendMenu(MF_SEPARATOR);
oPopupMenu.AppendMenu(0/*MF_STRING|MF_POPUP|MF_DISABLED|MF_GRAYED*/, ID_APP_EXIT, _T("Exit"));
CPoint pos;
GetCursorPos(&pos);
SetForegroundWindow();//加这句是为了鼠标点击其他地方时,弹出的菜单能够消失
oPopupMenu.TrackPopupMenu(TPM_RIGHTBUTTON |TPM_RIGHTALIGN, pos.x+1, pos.y+1, this);
oPopupMenu.DestroyMenu();
}
break;
}
return 0;
}