程序添加托盘图标
一般的程序都有托盘图标和在托盘上弹出右击菜单的功能,那么如何给自已的程序添加这样的功能呢?本文通过MDI程序为例,介绍一种实现托盘上弹出右击菜单的方法
以MDI程序为例
CMainFrm.h中
1)
#define ID_DATAMAN_SYSTEM_TROY_ICON 2001
//用于处理托盘弹出菜单消息
#define WM_DATASMASH_SYSTEM_TROY_MSG WM_USER + 1006
CMainFrm.cpp中
2)
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
... ...
// 将图标放入系统托盘
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
NOTIFYICONDATA nd;
nd.cbSize = sizeof (NOTIFYICONDATA);
nd.hWnd = m_hWnd;
nd.uID = ID_DATAMAN_SYSTEM_TROY_ICON;
nd.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nd.uCallbackMessage = WM_DATASMASH_SYSTEM_TROY_MSG;
nd.hIcon = m_hIcon;
strcpy_s(nd.szTip, 63, _T("双击打开主界面") );
Shell_NotifyIcon(NIM_ADD, &nd);
... ...
}
3)
void CMainFrame::OnClose()
{
... ...
// 删除托盘图标
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
NOTIFYICONDATA nd;
nd.cbSize = sizeof (NOTIFYICONDATA);
nd.hWnd = m_hWnd;
nd.uID = ID_DATAMAN_SYSTEM_TROY_ICON;
nd.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nd.uCallbackMessage = WM_DATASMASH_SYSTEM_TROY_MSG;
nd.hIcon = m_hIcon;
strcpy_s(nd.szTip, 63, _T("双击打开主界面") );
Shell_NotifyIcon(NIM_DELETE, &nd);
... ...
}
4)
//弹出菜单
CMainFrm.h中
LONG OnDataManSystemTroyMsg(WPARAM wParam, LPARAM lParam);
CMainFrm.cpp中
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
ON_MESSAGE(WM_DATASMASH_SYSTEM_TROY_MSG, OnDataManSystemTroyMsg)
END_MESSAGE_MAP()
LONG CMainFrame::OnDataManSystemTroyMsg(WPARAM wParam, LPARAM lParam)
{
// 响应在托盘图标上的单击
if (ID_DATAMAN_SYSTEM_TROY_ICON != wParam )
{
return 0;
}
// 左键双击托盘图标,弹出程序主界面
if( WM_LBUTTONDBLCLK == lParam )
{
ShowWindow(SW_SHOWNORMAL);
::SetForegroundWindow(m_hWnd);
}
// 右键点击托盘图标,松开的时候,弹出右键菜单
if( WM_RBUTTONUP == lParam )
{
CMenu menu;
if( menu.LoadMenu(IDR_MENU_SYS_TROY_POPUP) )
{
CMenu* popup = menu.GetSubMenu(0);
if( NULL != popup )
{
// Make first menu item the default (bold font)
::SetMenuDefaultItem(popup->m_hMenu, 0, TRUE);
// 系统托盘中显示右键菜单
CPoint ptMouse;
GetCursorPos(&ptMouse);
popup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, ptMouse.x, ptMouse.y, this );
}
}
}
return 0;
}
5)
// 闪烁效果
// 处理闪烁系统托盘的相关成员变量和成员函数,不考虑闪烁功能可以不加入
CMainFrm.h中
BOOL m_bFlashTroyIcon;
BOOL m_bFlashMainIcon;
HICON m_hIcon;
LONG OnDataManSystemTroyMsg(WPARAM wParam, LPARAM lParam);
void FlashTroyIcon();
void StopFlashTroyIcon();
CMainFrm.cpp中
CMainFrame::CMainFrame()
{
...
m_bFlashTroyIcon= FALSE;
m_bFlashMainIcon= TRUE;
...
}
void CMainFrame::OnTimer(UINT_PTR nIDEvent)
{
... ...
if(m_bFlashTroyIcon)
{
NOTIFYICONDATA nd;
nd.cbSize = sizeof (NOTIFYICONDATA);
nd.hWnd = m_hWnd;
nd.uID = ID_DATAMAN_SYSTEM_TROY_ICON;
nd.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nd.uCallbackMessage = WM_DATASMASH_SYSTEM_TROY_MSG;
strcpy_s(nd.szTip, 63, _T("双击打开主界面") );
if(m_bFlashMainIcon)
{
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_NULL);
nd.hIcon= m_hIcon;
m_bFlashMainIcon = FALSE;
}
else
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
nd.hIcon= m_hIcon;
m_bFlashMainIcon = TRUE;
}
Shell_NotifyIcon(NIM_MODIFY, &nd);
//InvalidateRect(NULL,TRUE);//刷当前程序界面
}
CXTPMDIFrameWnd::OnTimer(nIDEvent);
}
void CMainFrame::FlashTroyIcon()
{
m_bFlashTroyIcon = TRUE;
SetTimer(301, 400, NULL);
}
void CMainFrame::StopFlashTroyIcon()
{
m_bFlashTroyIcon = FALSE;
NOTIFYICONDATA nd;
nd.cbSize = sizeof (NOTIFYICONDATA);
nd.hWnd = m_hWnd;
nd.uID = ID_DATAMAN_SYSTEM_TROY_ICON;
nd.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nd.uCallbackMessage = WM_DATASMASH_SYSTEM_TROY_MSG;
strcpy_s(nd.szTip, 63, _T("双击打开主界面") );
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
nd.hIcon= m_hIcon;
Shell_NotifyIcon(NIM_MODIFY, &nd);
KillTimer(301);
}