VC++任务栏托盘图标及右键菜单实现

来源:互联网 发布:网络分线器很慢 编辑:程序博客网 时间:2024/05/16 01:33
  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);