Click here to Skip to main content
Click here to Skip to main content

System Tray Icons - Minimize Your Application to the SysTray

By , 6 Nov 2000
 

Sample Image - TrayIcons.jpg

Introduction

This article illustrates the use of Shell_NotifyIcon to create and manage System Tray icons. The article explains the basics of this operation and assists you in creating your own 'Minimize To Tray' applications. The source code provided with this article is designed to work with dialog-based applications, but it can easily be modified to work with a CFrameWnd or CWnd based application.

Creating and Using Tray Icons

To create a Tray Icon, you need to call the following shell function: -

BOOL Shell_NotifyIcon( DWORD dwMessage, PNOTIFYICONDATA pnid );

The dwMessage parameter specifies the action to be taken - NIM_ADD, NIM_DELETE, NIM_MODIFY adds, deletes and modifies tray icons respectively.

The pnid parameter is used to customize, create, delete and obtain data from the Tray Icon. (See the MSDN Library for more details about this structure.)

Creating The Application

1. Create a new VC++ dialog based project. For this example, I will call this project MyTray which will contain the CMyTrayApp and CMyTrayDlg classes.

2. Download and extract the DialogTray source code to the root of the project folder

3. From the Project->Add To Project menu, select Files and then select TrayDialog.h and TrayDialog.cpp. This will add a new class to your project named CTrayDialog.

4. Replace the CMyTrayDlg base class with CTrayDialog.

class CMyTrayDlg : public CDialog

becomes

#include "TrayDialog.h"

class CMyTrayDlg : public CTrayDialog

5. Replace the other occurrences of CDialog in the MyTrayDlg.cpp file as follows :-

CMyTrayDlg::CMyTrayDlg(CWnd* pParent /*=NULL*/)
  : CDialog(CMyTrayDlg::IDD, pParent)

becomes

CMyTrayDlg::CMyTrayDlg(CWnd* pParent /*=NULL*/)	
    : CTrayDialog(CMyTrayDlg::IDD, pParent)

6. Create a menu resource and name it IDR_MENU1

7. In the InitDialog member function, enter the following:

    TraySetIcon(IDR_MAINFRAME);
    TraySetToolTip("ToolTip for tray icon");
    TraySetMenu(IDR_MENU1);

8. Modify the IDD_MYTRAY _DIALOG resource to have a minimize box.

9. Build and run the application

NB : To add tray menu item handlers use the class wizard.

Displaying the tray icon all the time

Simply add a TrayShow() statement to InitDialog() in CMyTrayDlg.cpp, and call TraySetMinimizeToTray(FALSE) to disable minimizing to the tray.

The events that occur in the tray are captured through the following functions:

    virtual void OnTrayLButtonDown(CPoint pt);
    virtual void OnTrayLButtonDblClk(CPoint pt);

	virtual void OnTrayRButtonDown(CPoint pt);
	virtual void OnTrayRButtonDblClk(CPoint pt);
  
	virtual void OnTrayMouseMove(CPoint pt);

Feel free to add more events or to improve on these ones.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Daniel Zilcsak
Software Developer
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralThanks just perfectmemberasierra0111 Jan '10 - 9:14 
I saw a sample on wxWidgets, Python win32, but my code is in MFC, this is perfect.
 
Jorge Sierra
C++ Programmer
www.geocities.com/asierra01
404-409-4540 Cell

GeneralRight Click MenumemberShup15 May '09 - 1:20 
Hi,
 
First of all, a great class and my full rating.
 
I have a strange problem, I used the following code:
 
void CTrayDialog::OnTrayRButtonDown(CPoint pt)
{
	CMenu *pcSubMenu = m_mnuTrayMenu.GetSubMenu(0);
	
	if(pcSubMenu)
	{
		pcSubMenu->SetDefaultItem(m_nDefaultMenuItem, TRUE);
 
		SetForegroundWindow();
		pcSubMenu->TrackPopupMenu(TPM_VERNEGANIMATION | TPM_BOTTOMALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, pt.x, pt.y, this);
		PostMessage(WM_NULL, 0, 0);
	}
}
 
So that the right click menu would be dismissed if the mouse is clicked somewhere outside of there menu. But after the addition of this code, the strange thing that started to happen is that sometimes (I couldn't determine exactly when) the Windows Task Bar right click menu popes up over the application right click menu when right clicking on the application tray icon.
 
Any ideas as to how that can be resolved?
 
Regards,
 
Shup
Mind & Machines

GeneralThank you!memberDevMan7712 May '09 - 8:20 
Great article! It helps me a lot...
 
Thank you Daniel!
GeneralChanging tray icon while minimizedmembereight26 Mar '09 - 2:21 
I've added a simple timer to switch the tray icon every 5 second and it doesn't seem to work while minimized. To have the tray icon changed, I have to restore the dialog and re-minimize it back. Any idea on how I can get the tray icon to change while the dialog is minimized?
GeneralThanks!!!memberIAM...15 Feb '09 - 5:56 
that is all my friend. Cool | :cool:
 
Oscar Rangel

QuestionOnly minimizing to tray in my application?memberMember 192119231 Oct '08 - 5:03 
Hi,
 
I just downloaded the sample, followed the instructions in a new sample project, everything ok.
 
When I added TrayDialog to my current dialog based project in the same way, the only thing what happens is, that the program minimizes to the tray. There's no menu, no reaction on left double click. The only thing shown is the tooltip. I have to kill the application with the task manager...
 
There's no more CDialog reference in my source. It's nearly 99% the same code in OnInitDialog, message maps etc.
 
Any idea what to look for?
 
Alexander
QuestionBalloon Tip??memberthanasis_rassp12 Aug '08 - 3:16 
Is there a simple way to show a Windows XP Tip balloon when the program is minimized to tray? I google it and i cant understand any of the examples. Frown | :(
 
Anyway, thanks for the minimize code Wink | ;) it's neat.
AnswerRe: Balloon Tip??membervarandas7924 Sep '08 - 5:25 
Great class.
 
replace .cpp:
 
void CTrayDialog::TraySetToolTip(CString mToolTip, DWORD mIcon)
{
strcpy(m_nidIconData.szInfo, mToolTip);

CString tmp;
GetWindowText(tmp);
strcpy(m_nidIconData.szInfoTitle, tmp);
 
m_nidIconData.uFlags |= NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_INFO;
// Flag Description:
// - NIF_ICON The hIcon member is valid.
// - NIF_MESSAGE The uCallbackMessage member is valid.
// - NIF_TIP The szTip member is valid.
// - NIF_STATE The dwState and dwStateMask members are valid.
// - NIF_INFO Use a balloon ToolTip instead of a standard ToolTip. The szInfo, uTimeout, szInfoTitle, and dwInfoFlags members are valid.
// - NIF_GUID Reserved.
 
m_nidIconData.dwInfoFlags = mIcon; // add an icon to a balloon ToolTip
// Flag Description
// - NIIF_ERROR An error icon.
// - NIIF_INFO An information icon.
// - NIIF_NONE No icon.
// - NIIF_WARNING A warning icon.
// - NIIF_ICON_MASK Version 6.0. Reserved.
// - NIIF_NOSOUND Version 6.0. Do not play the associated sound. Applies only to balloon ToolTips
}
 
replace .h
 
void TraySetToolTip(CString mToolTip, DWORD mIcon=NIIF_INFO);
GeneralBug in CTrayDialog::OnSysCommand preventing sizingmemberEricGen24 Mar '08 - 23:02 
If you want your dialogue to be resizable, you need to modify CTrayDialog::OnSysCommand as follows:
 
void CTrayDialog::OnSysCommand(UINT nID, LPARAM lParam)
{
if(m_bMinimizeToTray)
{
if ((nID & 0xFFF0) == SC_MINIMIZE)
{
if( TrayShow())
{
this->ShowWindow(SW_HIDE);
return;
}
}
}
CDialog::OnSysCommand(nID, lParam);
}

GeneralSystem get slow...memberMember 385006728 Feb '08 - 21:52 
Tried this application...Its working nicely..but system gets slow..Confused | :confused:

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 7 Nov 2000
Article Copyright 2000 by Daniel Zilcsak
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid