Handling System Tray - Adding application Icon to System Tray

The system tray is the area on the far-right corner (or on the bottom if you are using a vertical taskbar) of the taskbar.
This area is also known as the status area or the notification area. In most cases, you will see the time or an icon displayed in this area. This can include icons representing things such as a print job in progress, anti-virus software, sound settings, display monitor icon, to name a few. By double-clicking one of these icons, you bring up part of the application, such as a dialog to change current settings. You can also right-click the icon in the system tray to access a context menu, which can give you even more options specific to that application. Even we can plant our own application-specific icon in this area as shown in the following figure.

We have made the following provisions in the program:

(a) On right clicking the icon a menu appears.

(b) By choosing one of the menu items the icon of our application in the system tray gets animated.

(c) On double clicking the icon of our application in the system tray the default menu item is considered to be selected and the handler related to this menu item gets called.

To implement the system tray we have defined a class called csystray. In the myframe class we have an object m_trayicon as one of its private data members. When the frame window gets created the control reaches myframe::OnCreate( ). From this function we have called the csystray::create( ) function. In the csystray::create( ) function we have created a window of size 10 x 10 using the CreateEx( ) function. Then we have created a menu that would later on get displayed on right clicking our application icon from the system tray. Note that we have not displayed this window or even the frame window.

Next we have set up values in the NOTIFYICONDATA structure through the statements:

m_nid.cbSize = sizeof ( NOTIFYICONDATA ) ;

m_nid.hWnd = m_hWnd ;

m_nid.uID = 1 ;

m_nid.hIcon = i ;

m_nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP ;

m_nid.uCallbackMessage = message ;

strcpy ( m_nid.szTip, tip ) ;

Lastly,we have called the function Shell_NotifyIcon( ). On calling this function our application starts receiving Windows messages from the system tray icon.

The Shell_NotifyIcon( ) function is used to send several different messages that control how your icon in the system tray operates. The first parameter passed to it specifies the operation that will be performed. To add a new icon for your application, it should be set to NIM_ADD, to change the current icon it should be set to NIM_MODIFY and to remove an existing icon it should be set to NIM_DELETE.

The second parameter to Shell_NotifyIcon( ) is a pointer to a NOTIFYICONDATA structure, which is used to pass a variety of information. This structure is shown below:

typedef struct _NOTIFYICONDATA

{

DWORD cbSize ;

HWND hWnd ;

UINT uID ;

UINT uFlags ;

UINT uCallbackMessage ;

HICON hIcon ;

CHAR szTip[64] ;

} NOTIFYICONDATA, *PNOTIFYICONDATA ;

The purpose of each element is as follows:

cbSize field should always be set to sizeof (NOTIFYICONDATA).

When mouse events occur on the icon in the system tray, such as moving over the icon, clicking, or double-clicking, the icon will send a Windows message back to your application. The hWnd field gives the handle of the window that will receive the message, while uID specifies a value that will be passed back to you application in the wParam of this message.

The uFlags field is used to indicate which of the remaining fields contains valid data. This may be a combination of NIF_ICON, NIF_MESSAGE, or NIF_TIP. To pass a new icon, set uFlags to NIF_ICON and pass a handle to the icon in hIcon.

The value passed in uCallbackMessage gives the message ID of the Windows message that will be sent to your application when the user does some thing with the icon.

Lastly, you may pass a short string for tooltip help text for the icon in szTip by setting NIF_TIP in uFlags.

Handling Notifications

When mouse events occur in the icon that we have added to the system tray, a message will be sent to the window whose handle we have set up in the hWnd field of the NOTIFYICONDATA structure. Thus the window that we created in csystray::create( ) will receive a message with a message ID of WM_USER + 15, with the WPARAM field set to 1, the id of our icon. In addition, the low word of LPARAM in the message will be set to one of the mouse event message ids, such as WM_LBUTTONDOWN. Now, let's take a look at how to handle these messages.

First, you will need to add a message handler for the message ID that you passed in the call to Shell_NotifyIcon( ). We have done this through the message map entry:

ON_MESSAGE ( WM_USER + 15, onusermessage )

The value 15 has been added here just to ensure that this message doesn't conflict with any other user-defined message that some other application might be using. We have defined the onusermessage( ) function within the class to tackle the right mouse and the double click mouse messages.