Windows 95 and subsequent versions of Windows allow you to place your program icons in the system tray. This is the area normally at the bottom right of the screen that displays the time, volume icon, and so on.
This area is useful for displaying status information or allowing easy access to your program's main features while your program may not be visible. It is also useful to have a small application display an icon in the system tray that allows the user to easily access the main program, or to load your main program at a scheduled time.
Some system tray icons change to indicate program status. For example, your browser program might include an icon in the system tray that changes to show when data is being sent and received by your modem. Holding the mouse over a tray icon normally displays a tooltip, which may also change depending on the program's status. Right-clicking on the icon normally displays a program menu, and double-clicking normally launches the main window or application.
Access to the system tray is made via the Shell_NotifyIcon function and the NOTIFYICONDATA structure.
typedef struct _NOTIFYICONDATA {
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
TCHAR szTip[64];
DWORD dwState; //Version 5.0
DWORD dwStateMask; //Version 5.0
TCHAR szInfo[256]; //Version 5.0
UINT uTimeout; //Version 5.0
TCHAR szInfoTitle[64]; //Version 5.0
DWORD dwInfoFlags; //Version 5.0
} NOTIFYICONDATA, *PNOTIFYICONDATA;
To display an icon in the system tray, call Shell_NotifyIcon with the NIM_ADD flag.
#define ID_TASKBARICON 100
#define WM_ICONNOTIFY (WM_USER + 101)
NOTIFYICONDATA nid;
// Initialize system tray icon
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hWnd;
nid.uID = ID_TASKBARICON;
nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP;
nid.uCallbackMessage = WM_ICONNOTIFY;
nid.hIcon = LoadImage(hInst, MAKEINTRESOURCE(IDI_TRAY1), IMAGE_ICON, 16, 16, 0);
strcpy(nid.szTip, "My Tooltip Text");
Shell_NotifyIcon(NIM_ADD, &nid);
The cbSize member should be sent to the size of the structure (supported sizes may be added in the future). Set the hWnd member to your window handle. When something happens to the icon (such as a click, double-click, etc.) Windows will send the message specified by the uCallbackMessage member to this window. The uID member specifies an ID associated with your icon. This is not important unless your application needs to display and keep track of several icons.
The uFlags member tells Windows which members should be read. When adding an icon, this should include most members. When you are updating an icon and, for example, need to change only the icon, you can set only the appropriate flags.
Set the hIcon member to the icon you want displayed. Finally, set the szTip member to your tooltip text and call Shell_NotifyIcon.
Windows will send the message specified by the uCallbackMessage member when an event occurs associated with your icon. lParam will contain the message being sent. When you get a WM_LBUTTONDBLCLK message, you should display your main window or launch your main application. When you get a WM_RBUTTONUP message, you should display a menu.
Note that there are some peculiarities associated with displaying a popup menu as a result of right-clicking in the system tray. It involves the fact that your window may not be the foreground window at that time. The code below shows how to deal with this per Microsoft knowledgebase article Q135788.
switch(nMsg) {
case WM_ICONNOTIFY:
switch(lParam) {
case WM_LBUTTONDBLCLK:
// Load main window here
break;
case WM_RBUTTONUP:
{
POINT point;
HMENU hMenu, hSubMenu;
// Get mouse position
GetCursorPos(&point);
// Popup context menu
hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MYMENU));
hSubMenu = GetSubMenu(hMenu, 0);
SetMenuDefaultItem(hSubMenu, IDM_DEFAULTCMD, FALSE);
SetForegroundWindow(hMainDlg); // Per KB Article Q135788
TrackPopupMenu(hSubMenu,
TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_LEFTALIGN,
point.x, point.y, 0, hWnd, NULL);
PostMessage(hMainDlg, WM_NULL, 0, 0); // Per KB Article Q135788
DestroyMenu(hMenu);
}
break;
default:
return FALSE;
}
}
Any time you want to change the icon, tooltip text, etc, you can call Shell_NotifyIcon with NIM_MODIFY.
Before your program terminates, call Shell_NotifyIcon with NIM_DELETE to clear your icon from the system tray.
Shell_NotifyIcon(NIM_DELETE, &nid);