给我的程序加上托盘

    为什么在让程序启动后只显示其图标在托盘上,而让主界面隐藏起来,我想到了将创建对话框的时候,将其创建的方式改为非模态对话框的形式。

     现在,具体的来说一下,怎么样实现托盘的功能,实现很简单,先来看一个结构体吧:

 

NOTIFYICONDATA结构包含了系统用来处理托盘图标的信息,

 

它包括选择的图标、回调消息、提示消息、图标对应的窗口等内容

 

其定义为:

    typedef struct _NOTIFYICONDATA

    {
                       DWORD cbSize;            //以字节为单位的这个结构的大小

                         HWND hWnd;             //接收托盘图标通知消息的窗口句柄

                          UINT uID;                  //应用程序定义的该图标的ID号


                         UINT uFlags;                //设置该图标的属性


                         UINT uCallbackMessage;      //应用程序定义的消息ID号,此消息传递给hWnd

                         HICON hIcon;                //图标的句柄

                        char szTip[64];             //鼠标停留在图标上显示的提示信息

       } NOTIFYICONDATA, *PNOTIFYICONDATA;


    该结构中,成员uFlags可以使下列之一或组合:
    NIF_ICON        设置成员hIcon有效
    NIF_MESSAGE    设置成员uCallbackMessage有效
    NIF_TIP           设置成员szTip有效

 

 

二、Shell_NotifyIcon函数
全局函数Shell_NotifyIcon() 用于在托盘上增加、删除或修改图标。其原型为:

 

WINSHELLAPI BOOL WINAPI Shell_NotifyIcon( DWORD dwMessage, PNOTIFYICONDATA pnid);

 

Pnid是上面的NOTIFYICONDATA结构的指针; dwMessage是被传递的消息,可以是以下消息之一:
              NIM_ADD               增加图标
              NIM_DELETE          删除图标
              NIM_MODIFY          修改图标

 

三、托盘图标程序设计示例


现在对话框的类中添加这个成员函数,用于我们创建托盘的时候,填充结构体:

void CUserDlg::ToTray()
{
      m_nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA); 
      m_nid.hWnd = this->m_hWnd;
      m_nid.uID = IDR_MAINFRAME;
      m_nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP ;
      m_nid.uCallbackMessage = WM_SHOWTASK;         //自定义的消息名称 WM_SHOWTASK 头函数中定义为WM_USER+1

      m_nid.hIcon = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
      strcpy(m_nid.szTip,"托盘图标");                              //当鼠标放在上面时,所显示的内容 
      Shell_NotifyIcon(NIM_ADD,&m_nid);                      //在托盘区添加图标
}

 

四:添加消息 WM_SHOWTASK 的响应函数 :  afx_msg LRESULT onShowTask(WPARAM wParam,LPARAM lParam);

 

在BEGIN_MESSAGE_MAP(CUserDlg, CDialog)和END_MESSAGE_MAP()之间加代码:

 

ON_MESSAGE(WM_SHOWTASK,onShowTask)

 

编写该函数:

LRESULT

CUserDlg::onShowTask(

                                    WPARAM wParam,

                                     LPARAM lParam

                                     )                                             //wParam接收的是图标的ID,lParam接收的是鼠标的行为
{
               if(wParam!=IDR_MAINFRAME)
                     return 1;
              switch(lParam)
             {
                      case WM_RBUTTONUP://右键起来时弹出快捷菜单,这里只有一个“关闭”
                      {   
                             LPPOINT lpoint=new tagPOINT;
                             ::GetCursorPos(lpoint);//得到鼠标位置 
                             CMenu menu;
                             menu.CreatePopupMenu();                       //声明一个弹出式菜单
                             //增加菜单项“关闭”,点击则发送消息WM_DESTROY给主窗口(已 隐藏),将程序结束。 
                             menu.AppendMenu(MF_STRING,WM_DESTROY,"退出"); 
                             menu.TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this);   //确定弹出式菜单的位置 
                             HMENU hmenu=menu.Detach();   //资源回收 
                             menu.DestroyMenu();
                             delete lpoint;
                          }
                           break;
                      case WM_LBUTTONDBLCLK://双击左键的处理
                      {    
                             this->ShowWindow(SW_SHOWNORMAL);//简单的显示主窗口
                      }
                        break;
               } 


              return 0;
}

 

 

然后在OnInitDialog函数中调用ToTray();

 

五:为使应用程序退出时图标消失,映射WM_DESTROY消息,在OnDestroy()函数中加入:

这里边得创建WM_DESTROY事件,然后在这个函数中添加     ::Shell_NotifyIcon(NIM_DELETE,&m_tnid);

 

现在可以实现了托盘功能,但是,当程序运行后,对话框并没有隐藏,现在,我们来将其隐藏。。。

一张图片即可说明问题:

 CMyUIDlg dlg;
 m_pMainWnd = &dlg;


 dlg.Create(DLG_MAIN);   // 修改为非模态的形式
 dlg.ShowWindow(SW_HIDE);  // 隐藏我们的主界面
 dlg.RunModalLoop();


/* int nResponse = dlg.DoModal(); // 这里是之前的样子
 if (nResponse == IDOK)
 {
 }
 else if (nResponse == IDCANCEL)
 {
 }*/

 

最后,当我们点击最小化按钮的时候,我们想让程序隐藏起来,但是不退出。我们可以给对话框添加

WM_SIZE 这个事件,当点击最小化后,我们调用 ShowWindow(SW_HIDE); 将对话框隐藏即可。

//
// 当点击最小化后,隐藏到托盘
//
void CMyUIDlg::OnSize(UINT nType, int cx, int cy)
{
         CDialog::OnSize(nType, cx, cy);
 
        switch (nType)
        {
              case SIZE_MINIMIZED:
             {
                     ShowWindow(SW_HIDE);
                      break;
               }
        } 
}

 

 

这样,基本就算完成了。。。

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值