Windows 95以及后来的Windows版本允许你将程序图标放入系统托盘。所谓系统托盘,通常指的是屏幕右下方显示时间,音量等图标的那个区域。托盘图标通常可以执行一些快捷操作,如窗口隐藏时通常最小化到托盘区域,用户可以单击鼠标左键显示程序窗口界面,右键单击托盘图标通常会弹出快捷菜单进行一些快捷操作。
在MFC中访问托盘图标是通过Shell_NotifyIcon函数和NOTIFYICONDATA结构实现。以下简单说明其实现步骤:
( 1 ) 添加托盘图标右键菜单资源(可以动态创建亦可利用VC自带的菜单编辑器),指定ID为IDR_TUOPAN_MENU
( 2 ) 初始化托盘图标:
NOTIFYICONDATA tnd; //NOTIFYICONDATA 结构声明
tnd.cbSize=sizeof(NOTIFYICONDATA); //结构体的大小,以字节为单位。
tnd.hWnd=this->m_hWnd; //窗口句柄,标示的窗口用来接收与托盘图标相关的消息。
tnd.uID=IDR_MAINFRAME; //应用程序定义的任务栏图标的标识符。Shell_NotifyIcon函数调用时,hWnd和uID成员用来标示具体要操作的图标
tnd.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP; //指示具体哪些其他成员为合法数据
tnd.uCallbackMessage=WM_LIBEN; //应用程序定义的消息标示,当托盘图标区域发生鼠标事件或者使用键盘选择或激活图标时,系统将使用此标示向由hWnd成员标示的窗口发送消息。
tnd.hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME); //图标ID
strcpy(tnd.szTip,"提示文本"); //托盘图标提示文本
Shell_NotifyIcon(NIM_ADD,&tnd); //安装托盘图标
( 3 ) 消息处理
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_MESSAGE(WM_LIBEN, OnNotifyIcon) //WM_LIBEN消息映射
END_MESSAGE_MAP()
//消息处理
LRESULT CMainFrame::OnNotifyIcon(WPARAM wParam,LPARAM lParam)
{
UINT uID;//发出该消息的图标的ID
UINT uMouseMsg;//鼠标动作
POINT pt;
uID=(UINT) wParam;
uMouseMsg=(UINT) lParam;
if(uMouseMsg==WM_LBUTTONDOWN)//如果是单击左键
{
switch(uID)
{
case IDR_MAINFRAME:
GetCursorPos(&pt);//取得鼠标位置
//判断当前窗口是否为隐藏,隐藏就让其显示
if(AfxGetApp()->m_pMainWnd -> IsIconic())
{
AfxGetApp()->m_pMainWnd -> ShowWindow(SW_SHOWNORMAL);
}
break;
}
}
if(uMouseMsg==WM_LBUTTONDOWN)//如果是单击右键
{
switch(uID)
{
case IDR_MAINFRAME:
CMenu menu; //定义右键菜单对象
GetCursorPos(&pt); //获取当前鼠标位置
menu.LoadMenu(IDR_TUOPAN_MENU); //载入右键快捷菜单
SetForegroundWindow();//放置在前面
CMenu* pmenu; //定义右键菜单指针
pmenu=menu.GetSubMenu(0); //该函数取得被指定菜单激活的下拉式菜单或子菜单的句柄
ASSERT(pmenu!=NULL);
pmenu-> TrackPopupMenu(TPM_RIGHTBUTTON | TPM_LEFTALIGN,pt.x,pt.y,this); //在指定位置显示右键快捷菜单
HMENU hmenu=pmenu -> Detach();
pmenu ->DestroyMenu();
}
}
}
( 4 ) 在程序退出消息处理程序中执行托盘图标卸载过程
void CMainFrame::OnAppExit()
{
ExitNotifyIcon();
}
void CMainFrame::ExitNotifyIcon()
{
NOTIFYICONDATA tnid;
tnid.cbSize=sizeof(NOTIFYICONDATA);
tnid.hWnd=this->m_hWnd;
tnid.uID=IDR_MAINFRAME;//保证删除的是我们的图标
Shell_NotifyIcon(NIM_DELETE,&tnid); //卸载图标
AfxPostQuitMessage(0);
|