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
CTrayIcon 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.
|
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
CTrayIcon(
CWnd *pWnd,
unsigned int uNotificationMessage,
MouseMsgHandlerPtr *pMouseMsgHandler,
unsigned int uHandlersCount,
IconDataPtr *pIconData,
unsigned int uIconsCount,
int nSelectedIconIndex,
unsigned int uElapsed
);
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
void SetTargetWnd(CWnd *pWnd);
void SetNotificationMsg(unsigned
int uNotificationMsg);
void SetSelectedIconIndex(int nIconIndex);
int GetSelectedIconIndex() const;
void SetMouseMsgHandler(
MouseMsgHandlerPtr *pMouseMsgHandler,
unsigned int uHandlersCount);
MouseMsgHandlerPtr* GetMouseMsgHandler()
const;
void SetTimerElapse(unsigned int uElapse);
int GetTimerElapse() const;
void SetIconData(IconDataPtr *pIconData, unsigned
int uIconsCount);
IconDataPtr* GetIconData()
const;
BOOL IsAnimating () const ;
CTrayIcon methods
BOOL ShowIcon();
BOOL HideIcon();
BOOL RefreshIcon();
BOOL HoverIcon();
BOOL StartIconAnimation();
BOOL StopIconAnimation();
CTrayIcon events & callbacks
OnTaskBarCreated
This is used to process the WM_TI_TASKBARCREATED
message for verifying taskbar status icon creation.
Syntax
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
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
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
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
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
unsigned int GetMouseMsgID() const;
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
virtual void MouseMsgHandler() = 0;
CTrayIconMouseMsgHandler synonyms
MouseMsgHandlerPtr
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
CIconData(
unsigned int uDefaultIconID,
LPSTR lpToolTip,
unsigned int uHoverIconID = 0,
HICON hIcon = NULL
);
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
unsigned int GetIconID() const;
unsigned int GetDefaultIconID() const;
void SetDefaultIconID(unsigned int uIconID);
unsigned int GetHoverIconID() const;
void SetHoverIconID(unsigned int uIconID);
LPSTR GetToolTip() const;
void SetToolTip(LPSTR lpToolTip);
HICON GetIconHandler() const;
CIconData methods
bool LoadIcon(unsigned int uIconID);
CIconData synonyms
IconDataPtr
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.
BOOL ShowWnd(CWnd* pWnd)
{
return pWnd->ShowWindow(SW_SHOW);
}
BOOL HideWnd(CWnd* pWnd)
{
return pWnd->ShowWindow(SW_HIDE);
}
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
class CLeftMouseDblClickMsgHandler: public CTrayIconMouseMsgHandler
{
public:
CLeftMouseDblClickMsgHandler() : CTrayIconMouseMsgHandler(
WM_LBUTTONDBLCLK){}
void MouseMsgHandler()
{
ShowWnd(AfxGetMainWnd());
}
};
Setting up right mouse 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
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
.
CTrayIcon* m_pTrayIcon;
Step 5 - initialization
In this phase, we will initialize the CTrayIcon
object to add icon to the system tray notification area.
MouseMsgHandlerPtr *pHandler = new MouseMsgHandlerPtr [3];
MouseMsgHandlerPtr rbcHandler = new CRightMouseClickMsgHandler();
MouseMsgHandlerPtr lbcHandler = new CLeftMouseDblClickMsgHandler();
MouseMsgHandlerPtr mhHandler = new CMouseHoverMsgHandler(m_pTrayIcon);
pHandler[0] = lbcHandler;
pHandler[1] = rbcHandler;
pHandler[2] = mhHandler;
IconDataPtr *pIconData = new IconDataPtr[2];
pIconData[0] = new CIconData(IDR_MAINFRAME, _T("CTrayIcon Blue Demo"),
IDR_MAINFRAME_HOVER);
pIconData[1] = new CIconData(
IDR_MAINFRAME_GREEN, _T("CTrayIcon Green Demo"), IDR_MAINFRAME_HOVER);
m_pTrayIcon = new CTrayIcon(pHandler, 3, pIconData, 2, 0, SECOND);
((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
void CCTrayIconDemoDlg::OnBnClickedBtnshowicon()
{
m_pTrayIcon->ShowIcon();
}
Hiding the tray notification icon
void CCTrayIconDemoDlg::OnBnClickedBtnhideicon()
{
m_pTrayIcon->HideIcon();
}
Starting the tray notification icon animation
void CCTrayIconDemoDlg::OnBnClickedBtnstartani()
{
m_pTrayIcon->StartIconAnimation();
}
Stopping the tray notification icon animation
void CCTrayIconDemoDlg::OnBnClickedBtnstopani()
{
m_pTrayIcon->StopIconAnimation();
}
Minimizing the window to the tray notification icon
void CCTrayIconDemoDlg::OnBnClickedBtnminimize()
{
m_pTrayIcon->ShowIcon();
HideWnd(this);
}
Showing the window from the tray notification icon
void CCTrayIconDemoDlg::OnShow()
{
ShowWnd(this);
}
Step 7 - the finishing touch
Once we are done, we release the resources gracefully.
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.
const unsigned int WM_TI_NOTIFYICON =
::RegisterWindowMessage(_T("TaskBarCreated"));
Go to AFX_MSG
and add the line in bold.
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);
Then go to AFX_MSG_MAP
and add the line in bold.
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_REGISTERED_MESSAGE(WM_TI_NOTIFYICON, OnNotifyIcon)
Replace the CTrayIcon
object creation with the following code.
m_pTrayIcon = new CTrayIcon(
this, WM_TI_NOTIFYICON, pHandler,
3, pIconData, 2, 0, SECOND);
Finally, redirect to the CTaskIcon
method.
void CCTrayIconDemoDlg::OnNotifyIcon(WPARAM wParam, LPARAM lParam)
{
m_pTrayIcon->OnNotifyIcon(wParam, lParam);
}
History
- 23 August, 2004 -- Original version posted
- 6 June, 2007 -- Article and downloads updated