MFC托盘编程

MFC窗口程序启动时最小化到托盘、不在任务栏中显示、显示时在右小角(一)

       经过一天的努力,终于完成了如题的一系列窗体效果,因为我做的是管理公司服务开启、关闭、与配置的程序。所以设计成:程序安装完成后,立即启动服务管理器;服务管理器要求最小化启动,不显示在任务栏中,在右下角托盘中显示一个图标;左键单击后显示窗体,显示在屏幕右下角;右键单击后显示菜单:配置、启动服务、退出。这一系列窗体功能一直没做过。今天查网络、看文档,终于做成了预计的效果。在此记录,也备下次使用,也希望能帮助到有同样需求的朋友。

       如果有更好的方法实现这些功能,希望前辈们可以指点。

       进入正题:

       第一步:窗口最小化到托盘,显示图标。

       这一步在网上一搜,真的很多文章,基本上都可以用吧。有的是在OnSize中最化时画图标,隐藏窗口;有的是在初始化时画图标,在OnSysCommand中判断最大化和最小化时进行窗口显示隐藏。我选择了后者。一开始在后面的步骤遇到了麻烦,最后第二种方法完成了。谅没再去试第一种方法。在OnSysCommand中显示隐藏,效果挺好的。

       我的开发环境是VS2008,创建一个对话框应用程序,选中包含最小化框(因为要最小化到托盘)。因为我的程序只是设计成在屏幕右小角显示一个小窗口来开启、停止、配置服务的一些操作。所以不要最大化功能。

       1、XXXDlg.h中声明一个方法用作显示托盘图标。void _fnToTray();

             XXXDlg.cpp中实现如下

             //在桌面右下角显示托盘图标
             void CXXXDlg::_fnToTray()
             {
                    NOTIFYICONDATA nid;
                    nid.cbSize = sizeof( NOTIFYICONDATA );
                    nid.hWnd = m_hWnd;
                    nid.uID = IDR_MAINFRAME;
                    nid.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
                    nid.uCallbackMessage = WM_SYSTEMTRAY;
                    nid.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
                    wcscpy_s(nid.szTip, _T("服务管理器"));
                    ::Shell_NotifyIcon(NIM_ADD,&nid );
             }

       2、修改CXXXDlg::OnSysCommand(UINT nID, LPARAM lParam)方法,橙色为增加的代码

             void CXXXDlg::OnSysCommand(UINT nID, LPARAM lParam)
             {
                    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
                    {
                            CAboutDlg dlgAbout;
                            dlgAbout.DoModal();
                    }
                    else if(nID == SC_MAXIMIZE) //最大化
                    {
                            this->ShowWindow(SW_SHOW);
                    }
                    else if(nID == SC_MINIMIZE) //最小化,把他隐藏起来
                    {
                            this->ShowWindow(SW_HIDE);
                    }
                    else
                    {
                            CDialog::OnSysCommand(nID, lParam);
                    }
             }

      3、在资源中新建一个菜单资源,我这里为IDR_MENU1,在菜单中添加一个子菜单,设ID为ID_EXIT,文字为

          “退出”。

      4、在targetver.h文件中,最后添加一行#define  WM_SYSTEMTRAY WM_USER+1

      5、在XXXDlg.h文件中,添加方法声明:

            afx_msg LRESULT OnSystemTray(WPARAM wParam, LPARAM lParam);

      6、在XXXDlg.cpp文件中,BEGIN_MESSAGE_MAP(CXXXDlg,CDialog)和END_MESSAGE_MAP()之间增加

            ON_MESSAGE(WM_SYSTEMTRAY,OnSystemTray)

      7、在XXXDlg.cpp文件中,实现方法:

            LRESULT CXXXDlg::OnSystemTray(WPARAM wParam, LPARAM lParam)
            {
                   if ( wParam = IDR_MAINFRAME )
                   {
                            switch( lParam )
                            {
                            case WM_LBUTTONDOWN:            //左键点击托盘图标显示窗口
                                     this->ShowWindow(SW_NORMAL);
                                     break;
                            case WM_RBUTTONDOWN:           //右键点击托盘图标显示菜单
                                     CMenu menu;
                                     menu.LoadMenu(IDR_MENU1);
                                     POINT pt;
                                     ::GetCursorPos(&pt);
                                     menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTALIGN, pt.x, pt.y, this);
                                     break;
                            }
                   }
                   return 1;
            }

       8、声明右键菜单:在XXXDlg.h中声明afx_msg void OnExit();

       9、在XXXDlg.cpp中BEGIN_MESSAGE_MAP(CXXXDlg,CDialog)和END_MESSAGE_MAP()之间增加

             ON_COMMAND(ID_EXIT,OnExit)

       10、在XXXDlg.cpp中实现退出

               void CXXXDlg::OnExit()
               {
                        this->PostMessageW(WM_QUIT);
               }

       11、在程序的OnDestroy()消息中移除图标



               void CXXXDlg::OnDestroy()
               {
                        CDialog::OnDestroy();

                        // TODO: 在此处添加消息处理程序代码
                        NOTIFYICONDATA nid;
                        nid.cbSize = sizeof( NOTIFYICONDATA );
                        nid.hWnd = m_hWnd;
                        nid.uID = IDR_MAINFRAME;
                        nid.uFlags = 0;
                        ::Shell_NotifyIcon( NIM_DELETE,&nid );
               }

        12、一切准备好了。在CXXXDlg::OnInitDialog()中添加

                _fnToTray();

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值