通常电脑里边的软件,当你打开后会在电脑最右下角的任务栏上生成一个系统托盘,当你点击最小化或者点击关闭按钮后,若想恢复窗口,可以左键双击或者单机这个系统图标,同时鼠标右键点击,又会有其他的菜单弹出,比如退出。
我看着感觉还是挺酷炫的,所以打算也在我的程序里边添加一个这样的功能。下边我把我自己探索的过程记录一下:
首先,我们需要用到NOTIFYICONDATA类,它是我们实现系统托盘的核心。关于这个类,百度百科上是这么说的:NOTIFYICONDATA是一个函数公式,主要含义和作用是以此函数用来向任务栏托盘区域发送消息。好了,其他的就不用管了,接下来进行实际的操作。
1、声明一个NOTIFYICONDATA类对象,一般可以放在父类里边作为成员变量或者作为全局的变量。

private:NOTIFYICONDATA NotifyIcon;  //系统托盘类

2、自定义一个消息

#define   WM_SYSTEMTRAY WM_USER+5

为什么是 WM_USER+5?关于消息WM_USER,为了防止用户定义的消息ID与系统的消息ID冲突,MS(Microsoft)定义了一个宏WM_USER,小于WM_USER的ID被系统使用,大于WM_USER的ID被用户使用。加5是我自己随便定义的,当然你可以自己指定具体的数值。
3、接下来这步,可以自己手动添加,也可以通过类向导来操作。我采用手动添加方式。声明一个响应函数,用来响应鼠标的操作。

protected:afx_msg LRESULT OnSystemtray(WPARAM wParam, LPARAM lParam);

4、注册刚才自定义的消息。在BEGIN_MESSAGE_MAP(CMyPlayerDlg, CDialogEx)和END_MESSAGE_MAP()之间添加如下代码:

ON_MESSAGE(WM_SYSTEMTRAY, &CMyPlayerDlg::OnSystemtray)

5、然后这一步就是开始产生作用的操作。一般添加在Oninitdialog()中,但是也可以是其他的函数中,比如只有在你点击关闭按钮后才添加系统拖盘图标,那么就不是在此处添加,具体在哪里添加,后面我会讲到。

BOOL CMyPlayerDlg::OnInitDialog()
{//设置系统托盘NotifyIcon.cbSize=sizeof(NOTIFYICONDATA);//NotifyIcon.hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);NotifyIcon.hIcon=m_hIcon;  //上面那句也可以NotifyIcon.hWnd=m_hWnd;lstrcpy(NotifyIcon.szTip,_T("爆疯牛逼一代"));NotifyIcon.uCallbackMessage=WM_SYSTEMTRAY;NotifyIcon.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP;Shell_NotifyIcon(NIM_ADD,&NotifyIcon);   //添加系统托盘//...}

其中比较重要的函数是Shell_NotifyIcon(NIM_ADD,&NotifyIcon),关于这个函数的具体解释,可以看这里:http://www.cnblogs.com/duzouzhe/archive/2010/04/08/1707050.html
NIM_ADD参数表示添加一个图标到系统托盘区。

6、上面我们定义了响应函数afx_msg LRESULT OnSystemtray(WPARAM wParam, LPARAM lParam),那么具体如何响应鼠标左键和右键的操作呢?
直接上代码:

afx_msg LRESULT CMyPlayerDlg::OnSystemtray(WPARAM wParam, LPARAM lParam)
{//wParam接收的是图标的ID,而lParam接收的是鼠标的行为
//  if(wParam!=IDR_MAINFRAME)
//      return    1;     switch(lParam)     {     case  WM_RBUTTONDOWN://右键起来时弹出快捷菜单{       CMenu menuexit;//menu.LoadMenuW(IDR_MENU1);//加载菜单资源menuexit.LoadMenuA(IDR_MENUexit);CMenu *pPopup=menuexit.GetSubMenu(0);CPoint mypoint;GetCursorPos(&mypoint);//ClientToScreen(&mypoint);//将客户区坐标转换为屏幕坐标SetForegroundWindow(); PostMessage(WM_NULL,0,0);//显示右键菜单,由视类窗口拥有。pPopup->TrackPopupMenu(TPM_LEFTALIGN,mypoint.x,mypoint.y,this); }     break;  case  WM_LBUTTONDOWN://左键单击的处理     {     ModifyStyleEx(0,WS_EX_TOPMOST);   //可以改变窗口的显示风格ShowWindow(SW_SHOWNORMAL);  }     break;     } return 0;
}

代码中我只实现了两个消息的响应,即鼠标左键单击和右键单击的消息。当鼠标左键单击后,恢复原窗口的大小和位置;当鼠标右键单击后,弹出菜单。我自己的菜单是如下设置的:

case WM_LBUTTONDOWN:里边的代码没有什么好讲的,关于case WM_RBUTTONDOWN:里边的代码,其实也没什么好讲的,也就是当鼠标右键单击时,装载一个右键菜单而已,其他的没有什么。具体可以看我之前的博客: 右键弹出菜单和快捷键的设置 。
然后菜单里的每一个子菜单的响应函数记得要编写,但先预留退出子菜单我下面讲。

7、其实上面的几部就已经可以实现想要的效果了。但是如果想要点击关闭按钮后程序并不关闭,而只是以系统托盘的形式出现在托盘区,直到你鼠标右键点击图标,执行退出操作,才真正退出,另一方面当你点击最小化后,程序最小化,但任务栏上任然具有程序的图标。如果想要实现这样的效果,其实也很简单,我们需要重写关闭“X”的响应函数。
具体重写的操作我就不写了,之前的博客写过这样的过程。重写代码如下:

void CMyPlayerDlg::OnCancel()  //点击X 按钮,最小化到系统托盘
{// TODO: 在此添加专用代码和/或调用基类this->ShowWindow(HIDE_WINDOW);//CDialogEx::OnCancel();
}

注意,注意,上面代码中的CDialogEx::OnCancel();一定要注释掉。因为我们只是想改写关闭操作,但并不真的执行关闭操作,也就是说我们只是想重写关闭按钮操作的响应函数。
但是,如果这样操作以后,你运行会发现,程序关不了了,因为关闭按钮只是执行隐藏窗口功能,你的右键菜单的退出操作也还没写,那怎么办,先杀了这个进程,接着编写如下的步骤。

(关于第5步提到的如果只是想在点击关闭按钮的时候才添加系统托盘,那也应该再OnCancel函数中书写第5步的代码,同时书写this->ShowWindow(HIDE_WINDOW);)

8、关于窗口的关闭过程,我前面的博客里边也记录过,此处就不多说了 。窗口关闭的过程中会执行DestroyWindow()函数,那么我们也将重写这个函数。

BOOL CMyPlayerDlg::DestroyWindow()
{// TODO: 在此添加专用代码和/或调用基类Shell_NotifyIcon(NIM_DELETE, &NotifyIcon);//消除托盘图标return CDialogEx::DestroyWindow();
}

其中Shell_NotifyIcon(NIM_DELETE, &NotifyIcon);//消除托盘图标很关键,正好和之前的Shell_NotifyIcon(NIM_ADD,&NotifyIcon)对应起来了。一个是添加,一个是删除。如果不写Shell_NotifyIcon(NIM_DELETE, &NotifyIcon),当你程序退出后,在系统托盘区的图标还会存在,因为进程残留,需要你鼠标移上去才会消失。
那么我们还需要在子菜单退出的响应函数中调用DestroyWindow()函数。

void CMyPlayerDlg::Onexit()
{// TODO: 在此添加命令处理程序代码DestroyWindow();
}

到此,我们就实现了一个比较满意的系统托盘方案,当然我自己探索的时候,还是碰到了 一些问题的,比如如何执行关闭操作,如何调用退出函数等等。但是,都一一克服了,仔细想想,其实也蛮简单的。

ok ,关于这个就到这里。

                              拙见,小记!

MFC系统托盘的实现相关推荐

  1. MFC最小化到系统托盘

    在VC++中,想实现将MFC最小化到系统托盘,需要调用NOTIFYICONDATA类,并注册相应的消息,以下详细讲解如何实现: 第一步,声明一个NOTIFYICONDATA类,也就是NOTIFYICO ...

  2. MFC中将窗口最小化到系统托盘和还原

    通过以下步骤可以在MFC程序中将窗口最小化到系统托盘,和还原成窗口,附加代码中如有特殊说明则会用红色标出. 1.添加一个ICON图标,其ID为IDI_ICON_TESTICON,在VS2008坐标的R ...

  3. MFC小笔记:系统托盘实现

    一.需求 本文实现程序系统托盘. 二.界面 主界面为对话框,有最小化.最大化.关闭等功能. 三.原理 利用系统托盘类NOTIFYICONDATA,响应自定义消息,处理托盘鼠标事件. 四.编码 4.1 ...

  4. delphi 关闭时缩小到托盘_delphi 实现最小化系统托盘

    1.new -->application 2.在form1中加入一个tPopMenu 命名为pm1 3.uses ShellAPI; 4.定义一个常量在 const WM_TRAYMSG = W ...

  5. VC6系统托盘类|崩溃自动重建图标|HOOK窗口消息|气泡效果更新SDK

    解决制作托盘气泡提示中遇到的'NIF_INFO' : undeclared identifier VC6下实现托盘气泡提示的关键是要更新SDK,实际上应该就是要更新SHELLAPI.h,SHELL32 ...

  6. windows系统托盘及托盘菜单

    window系统托盘及托盘菜单 下面是一个MFC写的wifi助手程序用于实现系统托盘的代码片段 void CWiFiAssistantDlg::OnClose() {  // TODO: 在此添加消息 ...

  7. 在 Ubuntu Natty 中解除系统托盘限制

    在 Ubuntu 11.04 Natty 中,Ubuntu 对顶部面板右上角的通知区域(系统托盘)采用了白名单制度,只有支持 Indicators 并位于白名单的部分程序才会被显示在系统托盘中,目前支 ...

  8. TrayIcon 类 添加系统托盘不显示托盘图标

    为什么80%的码农都做不了架构师?>>>    好久不碰 java swing最近写了一个swing 程序 添加托盘时,怎么也不显示图标,就一空白 ,在网上搜了老半天,大部无效. 边 ...

  9. 将 VMware 最小化到系统托盘

    1, 下载 Trayconizer 官网地址: http://www.whitsoftdev.com/trayconizer/ 下载地址: http://www.whitsoftdev.com/fil ...

最新文章

  1. android 循环平移动画
  2. Codeforces Round #698 (Div. 2) D. Nezzar and Board(一步步推出来,超级清晰,不猜结论,看不懂来打我 ~ 好题 )
  3. [3/18]Windows Server 2008 服务器配置之一DNS
  4. 【内核】linux内核启动流程详细分析
  5. spring jdbc设计与实现
  6. java 循环关键字_Java循环结构_常量_关键字
  7. 轻松简单地开发Web Services 2
  8. 史上最强大型分布式架构详解:高并发+数据库+缓存+分布式+微服务+秒杀
  9. 使用wireshark对HTTPS解密
  10. 学计算机编程笔记本电脑推荐,想选一款笔记本电脑,主要用来学编程,有什么好的推荐吗?...
  11. STM32学习——矩阵键盘
  12. 讯飞tts语音引擎_讯飞iFLYOS语音让家居产品更智能
  13. p9plus升级鸿蒙,华为P9 Plus(VIE-AL10 EMUI 8.0)手机完美获取root教程,最强root工具,亲测可用!...
  14. 点亮LED灯及IAR调试
  15. red hat linux 9下载地址,Red Hat Linux 9.0 ISO下载 (转)
  16. 龙ol服务器维护补偿boss,《龙OL》12月17日更新公告
  17. ESP-MQTT-AT指令连接阿里云物联网平台
  18. 控制windows 8,win8.1 win10 虚拟键盘
  19. putty 报错no supported authentication methods available (server sent:publickey...)
  20. MySQL多表查询练习题

热门文章

  1. xuanke java_wangshangxuankexitong - WEB源码|JSP源码/Java|源代码 - 源码中国
  2. Window10 VS17下 Opencv3.4.5配置
  3. 【开源分享】VIDO-SLAM:一种视觉惯性动态物体SLAM系统
  4. PCL之C++动态内存学习
  5. 设置VSCode代码编辑器右侧的Minimap代码缩略图滚动条切换显示、隐藏的快捷键Alt+M
  6. 在Ubuntu 14.04 64bit上为Sublime text 3安装搜狗拼音输入法
  7. Blender与UE5完美结合全流程创作游戏资产视频教程
  8. Linux命令之top
  9. getURLParameters - 网址参数
  10. w3cscholl的在线代码编辑工具