System Tray Icons

转载 2006年06月23日 15:39:00

Sample Image - SysTrayBalloon.jpg

System tray icons with a tooltip


Note :- This code will work only under Windows 2000 and above, when compiled with VC++ .NET or VC++ 6.0 (with the latest platform SDK).

The system tray is a familiar place for every reasonably experienced Windows OS user. Many applications use this area to place small icons there, which give information about their status. They give the user additional flexibility to directly interact with the application. Almost all applications provide a context menu over the system tray icons for interaction with the application. With the advent of Windows 2000/XP, popup balloons can also be shown over the system tray icons, to notify the user of any relevant event. This article explains the process of creating and showing icons in the system tray for any application. This also caters for multiple icons to be shown for the same application. You can also show popup balloons over the specified icons.

Using the code

  • Include the files SYSTRAYICON.H and SYSTRAYICON.CPP in your project.
  • Create an object of class CSysTrayIcon. In case you wish to process mouse messages over the icons derive a class from CSysTrayIcon and override any or all of the mouse messages mentioned in section "Overridable functions"
  • Create the object of class CSysTrayIcon or a class derived from CSysTrayIcon (preferably in the MainFrame class).
  • Create and manipulate icons in the system tray using the functions given in section "Functions for creating and manipulating icons in the system tray".
  • Mouse messages are trapped and overridable functions are provided for custom processing. See section "Overridable functions" for the list of overridable functions which are triggered by mouse messages.

Functions for creating and manipulating icons in the system tray

  • BOOL CreateIcon(HICON hIcon, UINT nIconID, PCSTR szTip)

    Input parameters

    • HICON hIcon -> Handle to an icon to be shown in the system tray.
    • UINT nIconID -> A user defined icon ID. It can be any unsigned integer.
    • PCSTR szTip -> A tooltip that is shown when the user moves the mouse over the icon.

    Return value

    TRUE if a new tray icon with the ID nIconID could be created, else FALSE

  • BOOL ShowIcon(UINT nIconID)

    Input parameters

    • UINT nIconID ->The icon with this ID to be shown.

    Return value

    TRUE if the icon with this ID exists and could be shown, else FALSE

  • BOOL HideIcon(UINT nIconID) - Hides the icon. It does not delete the icon from memory.

    Input parameters

    • UINT nIconID -> The icon with this ID to be hidden. It is not deleted from memory.

    Return value

    TRUE if the icon with this ID exists and could be hidden, else FALSE

  • BOOL DeleteIcon(UINT nIconID) - Hides and deletes the icon from the memory.

    Input parameters

    • UINT nIconID -> The icon with this ID to be hidden and deleted from memory.

    Return value

    TRUE if the icon with the ID exists and could be removed and deleted from the system tray and memory, else FALSE

  • BOOL ChangeIconTip(UINT nIconID, CString strTip) - This changes the tool tip associated with the system tray icon.

    Input parameters

    • UINT nIconID -> The icon with this ID whose tool tip has to be changed.
    • CString strTip -> The new tool tip to be associated with this icon.

    Return value

    TRUE if the icon with this ID exists and its tool tip cold be changed, else FALSE

  • BOOL ShowBalloon(UINT nIconID, PTSTR szBalloonTitle, PTSTR szBalloonMsg, DWORD dwIcon = NIIF_NONE, UINT nTimeOut = 10) - Shows a popup balloon over the icon with the ID, nIconID.

    Input parameters

    • UINT nIconID -> The icon ID over which the balloon will be shown.
    • PTSTR szBalloonTitle -> A string for the heading of the balloon message
    • PTSTR szBalloonMsg -> A string for the balloon message.
    • DWORD dwIcon -> An additional symbol in the left corner of the balloon that will emphasize the meaning of the balloon. There are four possibilities, NIIF_NONE, NIIF_ERROR, NIIF_INFO and NIIF_WARNING. The default is NIIF_NONE. These are standard constants defined in Windows Platform SDK in shellapi.h
    • UINT nTimeOut -> Time in seconds for the balloon to be visible. In Windows 2000/XP, the minimum is 10 seconds. Even if you specify a time less than 10 seconds, it will be visible for a minimum of 10 seconds. This will probably change with the future versions of Windows.

    Return value

    TRUE if the balloon with given ID exists and the requested balloon could be shown, else FALSE.

System tray balloon details

Overridable functions

There are ten overridable virtual functions, all of which deal with mouse messages.

  • virtual void OnLButtonDown(UINT nIconID, CPoint ptMouse)

    Gets called when the left mouse button has been pressed

  • virtual void OnRButtonDown(UINT nIconID, CPoint ptMouse)
  • Gets called when the right mouse button has been pressed


  • virtual void OnMButtonDown(UINT nIconID, CPoint ptMouse)

    Gets called when the middle mouse button has been pressed

  • virtual void OnLButtonUp(UINT nIconID, CPoint ptMouse)

    Gets called when the left mouse button is released

  • virtual void OnRButtonUp(UINT nIconID, CPoint ptMouse)

    Gets called when the right mouse button is released

  • virtual void OnMButtonUp(UINT nIconID, CPoint ptMouse)

    Gets called when the middle mouse button is released

  • virtual void OnLButtonDblClk(UINT nIconID, CPoint ptMouse)

    Gets called when the left mouse button is double clicked

  • virtual void OnRButtonDblClk(UINT nIconID, CPoint ptMouse)

    Gets called when the right mouse button is double clicked

  • virtual void OnMButtonDblClk(UINT nIconID, CPoint ptMouse)

    Gets called when the middle mouse button is double clicked

  • virtual void OnMouseMove(UINT nIconID, CPoint ptMouse)

    Gets called when the mouse moves over the icon

Input parameters for all overridables:

  • UINT nIconID -> The icon ID over which the mouse message has been generated
  • CPoint ptMouse -> The mouse position in screen co-ordinates

Helper function for handling a context menu

  • BOOL OnContextMenu(CMenu* pContextMenu, CPoint ptMouse, CWnd* pWndMessageHandler)

    This function should be called by the programmer, as it will help him to do the requisite processing to show a context menu. This sets the window mentioned in the third parameter in the foreground, so that commands can be routed to it for processing.

    This function should generally be called in response to a right button down message, typically in the overridden method OnRButtonDown of the class derived from CSysTrayIcon.

    Input parameters:

    • CMenu* pContextMenu -> Pointer to the menu to be shown, it is mostly on a right button press.
    • CPoint ptMouse -> Mouse position in screen co-ordinates.
    • CWnd* pWndMessageHandler -> A pointer to the window that will process the command handlers of the menu pContextMenu. This function sets this window in the foreground so that it is capable of processing the command handlers. This function was written specifically for bringing the menu command handler receiver window in the foreground. In case you don’t bring the window that will receive the menu commands in the foreground, the commands won’t be routed properly. This window is generally the MainFrame window in a typical Windows application.


The implementation of the class CSysTrayIcon

The CSysTrayIcon class is a wrapper around the Windows API, Shell_NotifyIcon and the Windows Platform SDK structure NOTIFYICONDATA, which is declared in the header file shellapi.h. Details about the above mentioned API and structure are well documented in the MSDN documentation.

The class CSysTrayIcon contains a linked list of NOTIFYICONDATA structures (CSystrayIcon::NOTIFYICONDATAList), which maintains information about each icon in the system tray related to that application. Every application can have more than one icon in the system tray. There is no restriction on an application to have only one system tray icon. It is only restricted by the maximum value of an unsigned integer!

Since this class CSysTrayIcon can’t directly receive mouse messages, there has to be a way to route the messages to this class. This is done by creating a hidden window as a private member variable m_wndTrayMsgReceiver (of type CSysTrayWnd) in the class CSysTrayIcon, which is registered to receive the WM_SYSTRAYMSG. When a message WM_SYSTRAYMSG is received by the window object CSysTrayIcon::m_wndTrayMsgReceiver, it is mapped to CSysTrayWnd::OnSysTrayMsg(WPARAM wParam, LPARAM lParam). The lParam gives the type of mouse message and the wParam gives the icon ID on which the mouse message was generated. If you look at the implementation of CSysTrayIcon::CreateIcon(), the NOTIFYICONDATA structure members hWnd and uCallBackMessage are initialized as shown below. This is where the operating system comes to know which window is to be sent the WM_SYSTRAYMSG.

pnidIconInfo->hWnd  = m_wndTrayMsgReceiver.GetSafeHwnd();
pnidIconInfo->uCallbackMessage = WM_SYSTRAYMSG;

Message Routing Mechanism

An object of CSysTrayWnd window is created in the constructor of CSysTrayIcon itself. The CSystTrayWnd also has a pointer to the CSysTrayIcon class which helps in calling the virtual overridable functions as mentioned in "Overridable functions".

There are few other functions which are used internally in the class to get the icons from the linked list, if given the icon ID as the parameter. These are summarized below.

  • GetNotifyIconDataFromID() -> Retrieves the NOTIFYCOINDATA structure from the linked list CSysTrayIcon::NOTIFYICONDATAList for the given icon ID.
  • CheckIfIconIDExists() -> This is called to check if the icon with the given ID already exists, when creating a new system tray icon.
  • DeleteNotifyIconDataFromID() -> This is called from the DeleteIcon() function and the destructor of the CSystTrayIcon class for deleting the icon and proper cleanup. This function removes the icon by removing and deleting it from the linked list CSysTrayIcon::NOTIFYICONDATAList.

Demo project

A class is derived from CSysTrayIcon with the name CMyAppTrayIcon. This class overrides only two virtual functions, OnLButtonDownDBlClk() to show a message box and OnRButtonDown to show a context menu. These two functions get triggered for the Windows messages WM_LBUTTONDBLCLK and WM_RBUTTONDOWN respectively, by the routing through a CSysTrayWnd object.

An object of CMyAppTrayIcon is kept as a member variable of CMainFrame class. Four icons are created in the CMainFrame::OnCreate(). The CMainFrame class handles all the command handlers for the context menu for the system tray icons.

For the context menu processing, the overridden OnRButtonDown method passes the main window's pointer to the CSysTrayIcon::OnContextMenu as the third parameter. The main window has the command handlers for the required processing.

 void CMyAppTrayIcon::OnRButtonDown(UINT nIconID, CPoint ptMouse)
    CMenu t_Menu;
    OnContextMenu(t_Menu.GetSubMenu(0), ptMouse, ::AfxGetMainWnd());

Use the icon menu to manipulate the system tray icons as shown in the top figure.

Prateek Kaul

Adding Icons to the System Tray
  • ekauq
  • ekauq
  • 2006年01月20日 10:52
  • 512

QT System Tray Icon Example 看看看~

System Tray Icon Example展示了怎么样用菜单和弹出消息添加一个图标到桌面环境的系统托盘。现代操作系统通常在桌面提供一个特别的区域,称为系统托盘或通知区域。在这里长时间运行的应用可...
  • xuguangsoft
  • xuguangsoft
  • 2013年01月23日 02:26
  • 5718


原文地址:Qt之系统托盘(QSystemTrayIcon详解)作者:一去丶二三里    托盘是什么?这个就不用在多说了!而Qt中如何实现自己的托盘功能,Qt自带的demo也很明了,这里我们就来实现自己...
  • u010002704
  • u010002704
  • 2014年09月11日 15:18
  • 634

No system tray detected on this system

今天开机时突然就弹出这个错误,虽然对系统没什么影响,但看着就很不顺眼,Google了一下,知道了原因,原来是HP打印机系统托盘的问题,它的启动顺序排在了Notification Area Panel之...
  • qq280948982
  • qq280948982
  • 2011年10月08日 09:04
  • 928

JavaSwing_5.6: 系统托盘(System Tray)

系统托盘(System Tray)就是最小化图标,程序以最小化图标的方式保持运行状态,Windows系统最小化到右下角的底部任务栏,MAC OS X 最小化到顶部菜单栏。...
  • xietansheng
  • xietansheng
  • 2017年10月29日 23:46
  • 441

System Tray Icon Example

System Tray Icon Example Files: desktop/systray/window.cpp desktop/systray/window.h ...
  • pi9nc
  • pi9nc
  • 2013年12月23日 23:55
  • 1160


在ubuntu的unity桌面环境下,由于白名单问题,深度音乐等非系统的面板的托盘图标不会显示,wine程序也只能有一个可以点击托盘图标。 下面是解决办法: sudo apt-add-reposit...
  • xuelongqy
  • xuelongqy
  • 2016年05月07日 21:32
  • 870


一、简介        Qt自带的例子/usr/lib64/qt4/examples/desktop/systray中详尽介绍了系统托盘的功能,在其基础上进行拓展,定制适合自己的系统托盘。     ...
  • taiyang1987912
  • taiyang1987912
  • 2015年07月20日 12:15
  • 3987

node-webkit教程(9)native api 之Tray(托盘)

node-webkit教程(9)native api 之Tray(托盘)  04/21/2014     玄魂     0    1019 从本篇文章开始,为您介绍Platform Ser...
  • anlun
  • anlun
  • 2014年11月17日 00:19
  • 965


使用VC++进行Tray区编程1.使用向导建立一个MFC对话框应用程序,假设叫TrayDemo2.增加消息处理函数 virtual BOOL OnInitDialog(); afx_msg void ...
  • lithe
  • lithe
  • 2005年01月13日 09:50
  • 1471
您举报文章:System Tray Icons