Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / C++
Article

CTrayIcon - System Tray Icon Wrapper

Rate me:
Please Sign up or sign in to vote.
3.17/5 (14 votes)
6 Jun 20078 min read 174.2K   5K   47   40
An article exhibiting a wrapper class for System Taskbar icon.

Screenshot - CTrayIcon_1.gif

Introduction

The system tray icon notification area -- or "systray" or "taskbar notification system area" -- is a section of the taskbars in the Microsoft Windows desktop user interface. This section displays the clock and the icons of certain programs so that a user is continually reminded that they are there and can easily click one of them. Unfortunately, MFC does not contain a class to wrap system tray functionality. So, I decided to write one and put it up for public use.

Background

The system tray is a section located at the one end of the taskbar in Windows 9x, and NT (Family). Icons that are often installed in the system tray include the volume control for sound, anti-virus software, and a system resources indicator. When more icons are installed in the system tray than can fit in the space allotted, the system tray becomes horizontally scrollable or expandable. To interact with a program in the system tray, you select an icon with your mouse and double-click or right-click the icon. When you minimize the program after using it, it shrinks back into the system tray instead of into the main part of the taskbar.

What makes a system tray icon special is that, when installed, it can have a customized message appear when the mouse is hovering over it. The menu that appears when you right-click it can be customized and the action that occurs when you double-click it can also be customized. For example, the double-click action for Internet Explorer could be to launch (start, or open a window for) the program, but the double-click action for a desktop icon could be to "View desktop," i.e. remove the active windows and show the underlying desktop.

An icon can be placed in the system tray when a program is installed by making an entry in the system registry. It can also be placed later by creating a shortcut to a program and dragging the shortcut icon to the system tray. An icon can be removed by deleting the registry entry or by right-clicking it and selecting Delete on the pop-up menu. The clock is removed by deselecting the show clock option in the taskbar Properties.

About CTrayIcon

JTray Menu Screenshot - Metal MenuCTrayIcon lets VC++ developers add icons to the Windows system tray. This quickly makes any VC++ application more attractive and intuitive to Windows users.

CTrayIcon can display pop-ups. This allows developers to modify the look and feel and add powerful menu items.

JTray Balloon Message Screenshot With CTrayIcon, tray icons can have Tool Tip Text that appears during a mouse-over. In addition, a cool mouse-hover effect is provided.

CTrayIcon class summary

This class is a wrap around the system tray icon notification. It adds a specified set of icon-pairs -- i.e. icons & hover-icons -- and tooltips to the system tray notification area, as well as a callback notification handler for mouse message handling.

CTrayIcon construction

Syntax

C++
// Use if notification messages are to be 
// sent to the parent window. 
CTrayIcon(
    CWnd *pWnd,
    unsigned int uNotificationMessage,
    MouseMsgHandlerPtr *pMouseMsgHandler,
    unsigned int uHandlersCount,
    IconDataPtr *pIconData,
    unsigned int uIconsCount,
    int nSelectedIconIndex,
    unsigned int uElapsed
    );

// Use if notification messages are to 
// be sent to the CTrayIcon class.
CTrayIcon(
    MouseMsgHandlerPtr *pMouseMsgHandler,
    unsigned int uHandlersCount,
    IconDataPtr *pIconData,
    unsigned int uIconsCount,
    int nSelectedIconIndex,
    unsigned int uElapsed
    );

Parameters

  • pWnd: Pointer to the window that receives notification messages associated with an icon in the taskbar status area. If the pWnd parameter is not provided, then the function CTrayIcon::OnNotifyIcon will be called whenever the icon sends a notification message.
  • uNotificationMessage: Message identifier for handling proper mouse notification messages associated with an icon in the taskbar status area. If a uNotificationMessage parameter is not provided, then a new window message is registered -- i.e. ::RegisterWindowMessage(_T("NotifyIcon") -- and is used as a default notification message identifier.
  • pMouseMsgHandlerPtr: An array of pointers to objects of classes derived from CTrayIconMouseMsgHandler to handle mouse messages.
  • uHandlersCount: Indicates the number of handlers in the array pointed to by pMouseMsgHandlerPtr.
  • pIconDataPtr: An array of pointers to objects of CIconData -- i.e. units of icons, hover icons, and tool tips -- to be added to the taskbar status area.
  • uIconsCount: Indicates the number of icons in the array pointed to by p IconDataPtr.
  • nSelectedIconIndex: Index of the selected icon in the array pointed to by p IconDataPtr.
  • uElapsed: Indicates the elapsed time for the taskbar status area icon animation timer.

CTrayIcon getters and setter

C++
// Sets the notification message target window
void SetTargetWnd(CWnd *pWnd);

// Sets the notification message identifier
void SetNotificationMsg(unsigned
int uNotificationMsg);

// Sets the selected icon index
void SetSelectedIconIndex(int nIconIndex);

// Gets the selected icon index
int GetSelectedIconIndex() const;

// Sets the mouse message handler
void SetMouseMsgHandler(
    MouseMsgHandlerPtr *pMouseMsgHandler, 
    unsigned int uHandlersCount);

// Gets the mouse message handler
MouseMsgHandlerPtr* GetMouseMsgHandler()
const;

// Sets timer elapse
void SetTimerElapse(unsigned int uElapse);

// Gets timer elapse
int GetTimerElapse() const;

// Sets icon data
void SetIconData(IconDataPtr *pIconData, unsigned
int uIconsCount);

// Gets icons data
IconDataPtr* GetIconData()
const;

// Indicates whether animation is in progress
BOOL IsAnimating () const ;  

CTrayIcon methods

C++
// Dispalys a hidden icon
BOOL ShowIcon();

// Hides a visible icon
BOOL HideIcon();

// Refreshes icon
BOOL RefreshIcon();

// Shows the hover icon
BOOL HoverIcon();

// Starts icon animation
BOOL StartIconAnimation();

// Stops icon animation
BOOL StopIconAnimation();

CTrayIcon events & callbacks

OnTaskBarCreated

This is used to process the WM_TI_TASKBARCREATED message for verifying taskbar status icon creation.

Syntax

C++
// Callback handler for the taskbar created event 
LRESULT OnTaskBarCreated( 
    WPARAM wParam, 
    LPARAM lParam 
    ); 

Result

Returns the LRESULT after verification.

OnNotifyIcon

This is used to process the WM_TI_NOITIFYICON message for proper mouse message handling.

Syntax

C++
// Default callback handler for 
// taskbar notification message event 
LRESULT OnNotifyIcon(
    WPARAM wParam, 
    LPARAM lParam 
    ); 

Result

Returns the LRESULT after verification.

WindowProc

This provides a Windows procedure for a CTrayIcon object. The WindowProc function is an application-defined function that processes messages sent to a window.

Syntax

C++
// Callback handler for the window procedure 
LRESULT WindowProc( 
    unsigned int uMsg, 
    WPARAM wParam, 
    LPARAM lParam 
    );

Result

Returns the LRESULT after verification.

OnTimer

This is used to process the WM_TIMER messages, triggered as soon as the elapsed time has passed.

Syntax

C++
// Callback handler for the timer elapsed event 
void OnTimer( 
    unsigned int uIDEvent 
    );

CTrayIconMouseMsgHandler class summary

This class stands as an abstract base-class for handling mouse notification messages. Classes derived from CTrayIconMouseMsgHandler should handle mouse notification messages and must implement the pure-virtual MouseMessageHandler() method.

CTrayIconMouseMsgHandler construction

Only a single parameter constructor is available that takes a Window message to be associated with it for receiving other system tray icon notification messages.

Syntax

C++
// Single paramenter constructor, a 
// mosue message identfier has to be passed
CTrayIconMouseMsgHandler( 
    unsigned int uMouseMsgID 
    );

Parameters

uMouseMsgID Windows messages that the OS generates when the user performs any action with the mouse over the system tray icon. For example, the pressing or releasing of the mouse buttons, etc.

CTrayIconMouseMsgHandler getters and setters

C++
// Gets the mouse message identifier 
unsigned int GetMouseMsgID() const; 

// Sets the mosue message identifier 
void SetMouseMsgID(
    unsigned int uMouseMsgID
    );

CTrayIconMouseMsgHandler events & callbacks

MouseMsgHandler

This method is a pure-virtual method and must be defined in the derived classes for handling system tray icon mouse notification messages. This event is generated by the CTrayIcon::OnNotifyIcon() method.

Syntax

C++
// Pure-virtual callback mouse message handler, 
// necessary to be implemented by the derived class, 
// for handling system tray icon notifications. 
virtual void MouseMsgHandler() = 0;

CTrayIconMouseMsgHandler synonyms

MouseMsgHandlerPtr

C++
// Synomym for CTrayIconMouseMsgHandler pointer 
typedef CTrayIconMouseMsgHandler* MouseMsgHandlerPtr;

CIconData class summary

This class encapsulates a set of icon-pairs -- i.e. icons & hover-icons -- and tooltips for the system tray notification area. It wraps the basic functionality to switch between icon & hover-icon, as well as between two different CIconData objects along with their respective tooltips.

CIconData construction

For object creation, a quad parameter constructor is available that takes icon-pair (icon & hover-icon) identifiers -- where hover-icon is optional -- a tooptip and an optional handler to an icon.

Syntax

C++
// Quad parameter constructor 
CIconData(
    unsigned int uDefaultIconID, 
    LPSTR lpToolTip,
    unsigned int uHoverIconID = 0, 
    HICON hIcon = NULL
    );

// Copy constructor
CIconData(
    const CIconData &pIconData
    );

Parameters

  • uDefaultIconID: Application-defined identifier of an icon, to be showed in the system tray icon notification area.
  • lpToolTip: Pointer to a null-terminated string with the text for a standard ToolTip. It can have a maximum of 64 characters, including the terminating NULL.
  • uHoverIconID: Application-defined identifier of an icon, to be showed in the system tray icon notification area during mouse-hover.
  • hIcon: Handle to the icon to be added, modified or deleted. To avoid icon distortion, be aware that notification area icons have different levels of support under different versions of Microsoft® Windows®. Windows 95, Windows 98, and Microsoft Windows NT® 4.0 support icons of up to 4 bits per pixel (BPP). Windows Millennium Edition (Windows Me) and Windows 2000 support icons of a color depth up to the current display mode. Windows XP supports icons of up to 32 BPP.

CIconData getters and setters

C++
// Gets the selected icon's identifer
unsigned int GetIconID() const;

// Gets the default icon identfier
unsigned int GetDefaultIconID() const;

// Sets the default icon identifier
void SetDefaultIconID(unsigned int uIconID);

// Gets the hover icon identifer
unsigned int GetHoverIconID() const;

// Sets the hover icon identifier
void SetHoverIconID(unsigned int uIconID);

// Gets the tooltip
LPSTR GetToolTip() const;

// Sets the tooltip
void SetToolTip(LPSTR lpToolTip);

// Gets the icon handler
HICON GetIconHandler() const;

CIconData methods

C++
// Selects and loads the speciifed icon into memory
bool LoadIcon(unsigned int uIconID);

CIconData synonyms

IconDataPtr

C++
// Synomym for CIconData pointer 
typedef CIconData* IconDataPtr;

How to use

Let's go step-wise to accomplish our task.

Step 1 - starting

Create an application and add the TrayIcon.h, TrayIcon.cpp, TrayIconMouseMsgHandler.h, IconData.h, Utilities.h and MouseMsgHandlerImpl.h files to the project.

Step 2 - pre-empting reusability

It is always beneficial to set up a global header library of reusable utility methods that can be used anywhere in the project.

C++
// Utilities functions

// Shows a window
BOOL ShowWnd(CWnd* pWnd)
{
    return pWnd->ShowWindow(SW_SHOW);
}

// Hides a window
BOOL HideWnd(CWnd* pWnd)
{
    return pWnd->ShowWindow(SW_HIDE);
}

// Shows a popup menu
void ShowPopupMenu(CWnd* pWnd, 
    unsigned int uResourseID, int nSubMenuPos)
{
    CPoint aPos;
    GetCursorPos(&aPos);
    CMenu aMenu;
    aMenu.LoadMenu(uResourseID);
    aMenu.GetSubMenu(nSubMenuPos)->TrackPopupMenu(
        TPM_RIGHTALIGN | TPM_RIGHTBUTTON, 
        aPos.x, 
        aPos.y, 
        pWnd, 
        0
        );
}

Step 3 - setting up mouse message handlers

In this phase, we will set up a few classes derived from CTrayIconMouseMsgHandler to handle mouse notification messages.

Setting up left mouse double click message handler

C++
// Left mouse button double click message handler
class CLeftMouseDblClickMsgHandler: public CTrayIconMouseMsgHandler
{
    public:

    CLeftMouseDblClickMsgHandler() : CTrayIconMouseMsgHandler(
        WM_LBUTTONDBLCLK){}

    void MouseMsgHandler()
    {
        ShowWnd(AfxGetMainWnd());
    }
};

Setting up right mouse click message handler

C++
// Right mouse button click message handler
class CRightMouseClickMsgHandler: public CTrayIconMouseMsgHandler
{
    public:

    CRightMouseClickMsgHandler() : CTrayIconMouseMsgHandler(
        WM_RBUTTONDOWN){}

    void MouseMsgHandler()
    {
        ShowPopupMenu(AfxGetMainWnd(), IDR_TASKBAR_MENU, 0);
    }
};

Setting up mouse hover message handler

C++
// Mouse hover message handler
class CMouseHoverMsgHandler: public CTrayIconMouseMsgHandler
{
    public:

    CMouseHoverMsgHandler(CTrayIcon* pTrayIcon) : CTrayIconMouseMsgHandler(
        WM_MOUSEFIRST)
    {
        m_pTrayIcon = pTrayIcon;
    }

    void SetTrayIcon(CTrayIcon* pTrayIcon)
    {
        m_pTrayIcon = pTrayIcon;
    }

    void MouseMsgHandler()
    {
        m_pTrayIcon->HoverIcon();
    }

    private:
    CTrayIcon* m_pTrayIcon;
};

Step 4 - declaring

Add a member to your class that points to CTrayIcon.

C++
// Declarying CTrayIcon object pointer for adding an icon to 
// the system tray notification area
CTrayIcon* m_pTrayIcon;

Step 5 - initialization

In this phase, we will initialize the CTrayIcon object to add icon to the system tray notification area.

C++
// Declare an array of MouseMsgHandlerPtr of size 3, 
// to handle three types of mouse events
MouseMsgHandlerPtr *pHandler = new MouseMsgHandlerPtr [3];

// Define an object for handling right mouse button click events
MouseMsgHandlerPtr rbcHandler = new CRightMouseClickMsgHandler();

// Define an object for handling left mouse button double click events
MouseMsgHandlerPtr lbcHandler = new CLeftMouseDblClickMsgHandler();

// Define an object for handling mouse hover events
MouseMsgHandlerPtr mhHandler = new CMouseHoverMsgHandler(m_pTrayIcon);

pHandler[0] = lbcHandler;
pHandler[1] = rbcHandler;
pHandler[2] = mhHandler;

// Declare an array of IconDataPtr of size 2, to add two sets of icons. 
// Only one will be active though.
IconDataPtr *pIconData = new IconDataPtr[2];

// Define an object of Blue MFC icon
pIconData[0] = new CIconData(IDR_MAINFRAME, _T("CTrayIcon Blue Demo"), 
    IDR_MAINFRAME_HOVER);

// Define an object of Green MFC icon
pIconData[1] = new CIconData(
    IDR_MAINFRAME_GREEN, _T("CTrayIcon Green Demo"), IDR_MAINFRAME_HOVER);

// Define the CTrayIcon object
m_pTrayIcon = new CTrayIcon(pHandler, 3, pIconData, 2, 0, SECOND);

// Refer the CTrayIcon object to the CMouseHoverMsgHandler object, 
// for handling mouse events
((CMouseHoverMsgHandler*)mhHandler)->SetTrayIcon(m_pTrayIcon);

Step 6 - setting up functionality

In this phase, we will set up functionality to hide, show and animate the system tray notification icon.

Showing the tray notification icon

C++
void CCTrayIconDemoDlg::OnBnClickedBtnshowicon()
{
    m_pTrayIcon->ShowIcon();
}

Hiding the tray notification icon

C++
void CCTrayIconDemoDlg::OnBnClickedBtnhideicon()
{
    m_pTrayIcon->HideIcon();
}

Starting the tray notification icon animation

C++
void CCTrayIconDemoDlg::OnBnClickedBtnstartani()
{
    m_pTrayIcon->StartIconAnimation();
}

Stopping the tray notification icon animation

C++
void CCTrayIconDemoDlg::OnBnClickedBtnstopani()
{
    m_pTrayIcon->StopIconAnimation();
}

Minimizing the window to the tray notification icon

C++
void CCTrayIconDemoDlg::OnBnClickedBtnminimize()
{
    m_pTrayIcon->ShowIcon();
    HideWnd(this);
}

Showing the window from the tray notification icon

C++
void CCTrayIconDemoDlg::OnShow() 
{
    ShowWnd(this);
}

Step 7 - the finishing touch

Once we are done, we release the resources gracefully.

C++
void CCTrayIconDemoDlg::OnCancel() 
{
    delete m_pTrayIcon;
    CDialog::OnCancel();
}

Alternate step - the other way around

In the above steps, we saw how efficiently we can handle the system tray notification icon messages by using the CTrayIcon class. What if you want to handle those messages in you own CWnd class? Implement this phase if you'd like to handle the system tray notification icon messages in you CWnd or CDialog class. In this example, that class would be the CCTrayIconDemoDlg class. Go to the header file and register a Window message to be handled once the system tray notification icon is created.

C++
const unsigned int WM_TI_NOTIFYICON = 
    ::RegisterWindowMessage(_T("TaskBarCreated"));

Go to AFX_MSG and add the line in bold.

C++
//{{AFX_MSG(CCTrayIconDemoDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnNotifyIcon(WPARAM wp, LPARAM lp);
//}}AFX_MSG

Then go to AFX_MSG_MAP and add the line in bold.

C++
//{{AFX_MSG_MAP(CCTrayIconDemoDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_REGISTERED_MESSAGE(WM_TI_NOTIFYICON, OnNotifyIcon)
//}}AFX_MSG_MAP

Replace the CTrayIcon object creation with the following code.

C++
// Define the CTrayIcon object
m_pTrayIcon = new CTrayIcon(
    this, WM_TI_NOTIFYICON, pHandler, 
    3, pIconData, 2, 0, SECOND);

Finally, redirect to the CTaskIcon method.

C++
void CCTrayIconDemoDlg::OnNotifyIcon(WPARAM wParam, LPARAM lParam) 
{ 
    // TODO
    m_pTrayIcon->OnNotifyIcon(wParam, lParam);
}

History

  • 23 August, 2004 -- Original version posted
  • 6 June, 2007 -- Article and downloads updated

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Pakistan Pakistan
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMem leek Pin
hu_vane24-Jan-07 13:58
hu_vane24-Jan-07 13:58 
GeneralRe: Mem leek Pin
Muneeb Awan25-Jan-07 3:26
Muneeb Awan25-Jan-07 3:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.