玩转VC++系统托盘程序(WIN8)



WINDOWS系统托盘是一个特殊区域,通常在桌面的右下角,也就是任务栏的右边。系统常驻在托盘的程序有时钟,音量控制,输入法,网络状态等。第三方应用如QQ程序也是一个典型的托盘程序,当最小化时企鹅会乖乖的待在屏幕右下角等待主人的呼唤。

系统托盘的方便之处在于,程序在暂时不用时,将它放到托盘里,随用随叫,不必将其关闭。而QQ在接收到消息后,也会在托盘中闪动提示,十分人性化。

那么如何用VC++来开发托盘程序呢?下面会用一个例子来玩转WINDOWS托盘程序。

首先,定义一下需要的功能。(需求确定)

  1. 程序最小化到托盘。
  2. 右键点击,显示一个菜单。
  3. 鼠标左键双击托盘图标,打开程序。
  4. 程序中点击一个按钮,改变托盘图标。

好了,就这么简单的Demo,下面看看如何实现。

其次,归纳一下用到的技术点。

  1. 托盘相关API
  2. MFC对鼠标操作消息的接收

先来说说托盘相关的API。MFC并没有直接提高便利的类来支持系统托盘编程,我们需要用到SHELLAPI中的Shell_NotifyIcon函数。原型为:

BOOL Shell_NotifyIcon(
    DWORD dwMessage,
    PNOTIFYICONDATA lpdata
);

函数很简单清晰,只有两个参数。参数一dwMessage用来指定托盘的动作,这是一个四字节的值。如下:

  1. NIM_ADD(0X00000000):添加一个系统托盘
  2. NIM_MODIFY(0X00000001):系统托盘的修改
  3. NIM_DELETE(0X00000002):系统托盘的删除
  4. NIM_SETFOCUS(0X00000003):令系统托盘获得焦点
  5. NIM_SETVERSION(0X00000004):系统托盘设置版本

参数二PNOTIFYICONDATA是专门为此服务的结构体。原型如下:

typedef struct _NOTIFYICONDATA {
  DWORD cbSize;//结构体的大小,单位是字节
  HWND  hWnd;//此托盘程序的句柄
  UINT  uID;// 系统为托盘区域每个图标分配的ID
  UINT  uFlags;//简单的说,就是一个标示
  UINT  uCallbackMessage;//回调消息。需要自定义一个消息,用来接收鼠标滑过或点击等消息。
  HICON hIcon;//图标
  TCHAR szTip[64];//提示文字的大小
  DWORD dwState;//图标的状态
  DWORD dwStateMask;//与上面类似
  TCHAR szInfo[256];//显示在气泡通知中的文本
  union {
    UINT uTimeout;
    UINT uVersion;
  };
  TCHAR szInfoTitle[64];//气泡通知的标题
  DWORD dwInfoFlags;//修改气泡通知相关的标示
  GUID  guidItem;//图标的GUID
  HICON hBalloonIcon;//气泡通知的图标
} NOTIFYICONDATA, *PNOTIFYICONDATA;

再来说说MFC中对鼠标操作信息的接收。

其实上面的调查结果一出,这个问题也就迎刃而解了。关键在uCallbackMessage。我们会自定义一个消息,比如就叫做WM_ICON_NOTIFY,当此托盘图标有鼠标滑过,悬停或点击,键盘操作时回调这个接收自定义消息的函数来处理。这一切都被安排好了,我们照着做就可以了。

第三、功能的实现

1.最小化到托盘

创建托盘的函数ToTray:

	m_tnd.cbSize = sizeof(NOTIFYICONDATA);
	m_tnd.hWnd	 = pWnd->GetSafeHwnd();
	m_tnd.uID	 = uID;
	m_tnd.hIcon  = icon;
	m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
	m_tnd.uCallbackMessage = uCallbackMessage;
	strcpy (m_tnd.szTip, szToolTip);
	// Set the tray icon
	Shell_NotifyIcon(NIM_ADD, &m_tnd);

窗口最小化在OnSysCommand中判断:

    else if (nID == SC_MINIMIZE)
    {
        ToTray();
	ShowWindow(SW_HIDE);//隐藏窗口
}

2、3功能都可以在获得托盘事件函数处理:

LRESULT CTrayIcon::OnTrayNotification(UINT wParam, LONG lParam)
{
	//Return quickly if its not for this tray icon
	if (wParam != m_tnd.uID)
		return 0L;

	// Clicking with right or left button brings up a context menu
	if (LOWORD(lParam) == WM_RBUTTONUP /*|| LOWORD(lParam) == WM_LBUTTONUP*/)
	{
		//TODO:WHEN RIGHT CLICK,YOUR MENU SHOW HERE
	}
	else if (LOWORD(lParam) == WM_LBUTTONDBLCLK)
	{
		//TODO:DOUBLE LEFT CLICK,SHOW MAIN WINDOW
	}

	return 1;
}

4.修改图标

这个就比较容易了,直接修改参数即可:

	m_tnd.uFlags = NIF_ICON;
	m_tnd.hIcon = hIcon;

	Shell_NotifyIcon(NIM_MODIFY, &m_tnd);

完整的例子请下载demo代码,借用了网上比较流行的封装好的TrayIcon类。

参考:

MSDN上的详细解释:http://msdn.microsoft.com/en-us/library/bb762159(VS.85).aspx

Vckbase:http://www.vckbase.com/index.php/cv/122

玩转VC++系统托盘程序(WIN8),布布扣,bubuko.com

时间: 2024-08-01 19:13:17

玩转VC++系统托盘程序(WIN8)的相关文章

VC 系统托盘编程,含有气泡提示

转载一:http://blog.sina.com.cn/s/blog_6acf36ee0100rxdb.html 转载二:http://blog.csdn.net/akof1314/article/details/5121911 转载三:http://www.xuebuyuan.com/1768243.html 在Duilib的Win32程序中,响应托盘消息在HandleCustomMessage函数中坐处理.

使用electron将应用程序加入到系统托盘

博主电脑??进水坏了之后,MDZZ......来回折腾好几个来回,第三次维修店??拿电脑??,终于修好了~.废话不多一如既往先上图     一.将应用程序加入系统托盘 微信对于现代人来说已经是一种生活方式,支持单人.多人参与的一款跨平台的通讯工具. 通过手机网络发送语音.图片.视频和文字.其主要核心技术功能是(仅代表博主个人观点) InstantMessaging(即时通讯,实时传讯) 原谅博主资历尚浅,这里暂且不述~. 微信虽然大家都用,但也不见得自己无论是从产品方面或是技术方面会用/了解她,

系统托盘编程完全指南

原文:http://www.hellocpp.net/Articles/Article/574.aspx 第一部分 自从Windows 95面市以来,系统托盘应用作为一种极具吸引力的UI深受广大用户的喜爱.使用系统托盘UI的Windows应用程序数不胜数,比如"金山词 霸"."Winamp"."RealPlayer"等等.那么如何编写自己的托盘应用呢?本文是系列文章中的第一篇,这些文章将比较系统地描述托盘应用的 编程.并创建自己的C++类来增强系

【VC编程技巧】窗体?3.7托盘程序介绍(模拟QQ消息)

所谓的托盘程序就是运行时在系统托盘区(就是桌面右下角显示时间的区域)出现一个小图标的程序.代表它运行的图标称作托盘图标.我们可以通过使用小图标来控制应用程序的状态. (一)NOTIFYICONDATA Structure typedef struct _NOTIFYICONDATA { DWORDcbSize;//结构体大小 HWNDhWnd;//接受icon消息的窗口句柄 UINT uID;//icon图标的资源Id UINTuFlags;//标志一些成员是否有效 UINTuCallbackM

玩转VC++实现程序开机运行及注册表修改

 一.方案 要实现Windows程序开机运行,需要在注册表中相关位置加入键值.所谓的键可以是你程序的名称,值就是你程序的所在目录.所谓的相关位置有两处: 主键HKEY_LOCAL_MACHINE,Software\Microsoft\Windows\CurrentVersion\Run下. 主键HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Run下. 区别就是前者针对机器上所有用户,而后者只针对当前用户. 在编程中对

java应用程序-系统托盘

本实例是用来制作应用程序的系统托盘,比如类似qq在窗体的右下角的图标格式.代码直接复制可用. 1 import java.awt.AWTException; 2 import java.awt.Image; 3 import java.awt.MenuItem; 4 import java.awt.PopupMenu; 5 import java.awt.SystemTray; 6 import java.awt.TrayIcon; 7 import java.awt.event.ActionE

64 位系统(win7/win8) 下使用C# 程序问题

1  C# 程序是控制台类,使用的组件如果是32位,建议在编译的时候,platform (X86,AnyCPU,X64)选择X86 .使用X86 模式编译,才能调用32位程序的API. 2  ASP.NET MVC 程序 platform 在发布之后,IIS7.0  以上,需要把站点的应用程序池基本设置项 "Enable 32-Bit Applications", 设置为true,默认是false. 使用ASP.NET MVC 3  : 必须安装 .net framework 4: 使

系统托盘

为程序添加系统托盘1:创建菜单资源 ID: IDR_MENU_NOTIFY2:添加子菜单 显示 IDM_NOTIFY_SHOW 退出 IDM_NOTIFY_CLOSE 3:查看MSDN Shell_NotifyIcon BOOL Shell_NotifyIcon( //向系统托盘中加入图标 DWORD dwMessage, //状态 PNOTIFYICONDATA lpdata //含有图标 消息响应 的一个结构体); 4:认识NOTIFYICONDATA 结构体: typedef struct

Qt系统托盘

Qt的系统托盘的使用,可比mfc中好多了!他封装了一个专门的QSystemTrayIcon类,建立系统托盘图标.其实在Qt提供的示例程序已经很不错了,$QTDIR\examples\desktop\systray在这里简单的实现一个系统托盘功能,对其系统托盘类的使用做以演示. #include <QtGui>class Window: public QWidget{    Q_OBJECT        public:    Window(); private:    void showMes