Click here to Skip to main content
11,648,455 members (77,305 online)
Click here to Skip to main content

Easy Animated Tray Icon

, 4 Feb 2002 173.8K 5.2K 69
Rate this:
Please Sign up or sign in to vote.
This is a class (SS_TrayIcon) that allows for the easy addition of a tray icon into any project (whether you use MFC or not).
<!-- Download Links -->

Sample Image

Introduction

This is a class (SS_TrayIcon) that creates a tray icon in the system tray, allowing easy integration into any project, whether or not you use MFC. Some of the features include:
  • Create multiple icons, animated icons, blinking icons, or still icons
  • Easily define a message map for routing Windows messages generated by the tray icon to user defined functions...
    -or-
    Let MFC handle the message mapping by sending all messages to the CWnd::WindowProc function.
  • Easily add a popup window (context menu) to the icon when the user clicks on it.
  • Avoid processing the WM_LBUTTONDOWN Windows message before a user double-clicks. This is a common problem... when the user double-clicks, programs often process a single-click before processing the double-click. This class will wait to send the single-click message until it is sure that the user won't double-click. (note: this feature does not work if you let MFC handle the message routing.)

This class is similar to Chris Maunder's class in Adding Icons to the System Tray except that it allows you to specify the mode (SSTI_MODE_SHOWNORMAL, SSTI_MODE_HIDE, SSTI_MODE_BLINK, SSTI_MODE_ANIMATE)

A simple demo project is included:

Sample Image

Integration Into Your Project

You will need to include the 2 header files into your project (SS_TrayIcon.h and SS_Wnd.h), add the SS_TrayIconD.lib file to your debug project, and the SS_TrayIcon.lib file to your release project. (or you can skip the lib files and add the two *.cpp files instead.)

To create a tray icon, you only need 3 lines of code:
SS_TrayIcon* m_pTrayIcon = new SS_TrayIcon( m_hInstance, 1, 1 );  // create the instance
m_pTrayIcon->LoadIcon( 0, 0, IDI_SOME_ICON_RESOURCE );            // load an icon resource
m_pTrayIcon->ShowIcon( 0 );                                       // show it!
Some other options include:
m_pTrayIcon->Mode( 0, SSTI_MODE_BLINK );                      // make it blink
m_pTrayIcon->SetAnimateSpeed( 0, 400 );                       // 400 is milliseconds
m_pTrayIcon->ToolTip( 0, _T("This is a blinking icon...") );  // add a tool tip
m_pTrayIcon->ShowMenuAtMouse( nMenuResourceID, hWnd );        // show a popup menu

m_pTrayIcon->HideIcon();                                      // hide it!
Most of the functions that alter the icon require an integer as the first parameter (nIconSet). Because you can have multiple icons, this integer specifies which icon you want to alter. Then when you show the icon, you specify which icon you want to show. From here on out, we will refer to each one of these icons as an IconSet... here's why: each IconSet can contain multiple "sub-icons", which we will refer to as "frames". So each IconSet makes up an animation that is composed of some number of frames. You can load icon resources into the frames of your IconSets as in the following code, which creates 3 IconSets, one with 8 frames, and two with only 1 frame:
//             How many icons (IconSets)?
                                        //             |  How many icons per set (frames)?
                                        //             |  |
m_pTrayIcon = new SS_TrayIcon( AfxGetInstanceHandle(), 3, 8 );


// prep IconSet 1 (animated with 8 frames)
//
//                     This is which IconSet to load into...
//                     |  This is the frame number...
//                     |  |
m_pTrayIcon->LoadIcon( 0, 0, IDI_ICON1 );
m_pTrayIcon->LoadIcon( 0, 1, IDI_ICON2 );
m_pTrayIcon->LoadIcon( 0, 2, IDI_ICON3 );
m_pTrayIcon->LoadIcon( 0, 3, IDI_ICON4 );
m_pTrayIcon->LoadIcon( 0, 4, IDI_ICON5 );
m_pTrayIcon->LoadIcon( 0, 5, IDI_ICON4 );
m_pTrayIcon->LoadIcon( 0, 6, IDI_ICON3 );
m_pTrayIcon->LoadIcon( 0, 7, IDI_ICON2 );

m_pTrayIcon->Mode( 0, SSTI_MODE_ANIMATE );
m_pTrayIcon->SetAnimateSpeed( 0, 150 );
m_pTrayIcon->ToolTip( 0, _T("This is an animated icon...") );


// prep IconSet 2 (blinking)
//
m_pTrayIcon->LoadIcon( 1, 0, IDR_MAINFRAME );

m_pTrayIcon->Mode( 1, SSTI_MODE_BLINK );
m_pTrayIcon->SetAnimateSpeed( 0, 450 );
m_pTrayIcon->ToolTip( 1, _T("This is a blinking icon...") );


// prep IconSet 3 (standing still)
//
m_pTrayIcon->LoadIcon( 2, 0, IDI_ICON6 );

m_pTrayIcon->Mode( 2, SSTI_MODE_SHOWNORMAL );
m_pTrayIcon->ToolTip( 2, _T("This is a non-animated icon...") );


// Now show the first (animated) icon
//
m_pTrayIcon->ShowIcon( 0 ); // or '1' for the second, or '2' for the third
The last thing you need to know is about the message map. For each message you want to respond to, you need the call the m_pTrayIcon->MapMessageToFunction function. You need to supply the function with a pointer to your global callback function so it can call that function when the message is generated, as so:
// *global* callback function for the WM_LBUTTONDBLCLK message
LRESULT CALLBACK OnMouseDblClickTI(WPARAM wParam, LPARAM lParam)
{
    ::MessageBox(NULL, _T("Double-clicked!!"), _T("Test"), MB_OK|MB_ICONINFORMATION);
    return 0;
}

// in your initialization routine
CYourClass::InitObject()
{
	...

	m_pTrayIcon = new SS_TrayIcon( AfxGetInstanceHandle(), 3, 8 );

	m_pTrayIcon->MapMessageToFunction(WM_LBUTTONDBLCLK, ::OnMouseDblClickTI);

	...
}
Now whenever the user double-clicks on the tray icon (no matter which one you have showing), your OnMouseDblClickTI() function will be called. You can do anything you want from there. If you want to respond differently depending on which icon you have showing, you will have to keep track of which icon is showing and use a switch in the callback function to determine what action is appropriate.

Notes

There are LOTS of comments in the demo code explaining how to use the SS_TrayIcon class, and there are also lots of comments in the SS_TrayIcon code explaining how the code works, so please read through those comments for a much more detailed explanation of the inner workings of this project.

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

Share

About the Author

Steve Schaneville
Architect Amedisys
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

 
GeneralMy vote of 4 Pin
sariqkhan21-Nov-12 1:31
membersariqkhan21-Nov-12 1:31 
QuestionVarious bugs: NOTIFYICONDATA must be cleared. Pin
_gl4-Aug-11 11:55
member_gl4-Aug-11 11:55 
AnswerTooltip bugs Pin
_gl4-Aug-11 12:44
member_gl4-Aug-11 12:44 
Generalx64 compatibility [modified] Pin
_gl4-Aug-11 13:28
member_gl4-Aug-11 13:28 
AnswerSS_Wnd not destroyed / cleaned up. Pin
_gl4-Aug-11 18:22
member_gl4-Aug-11 18:22 
Questioncan't Compiling Pin
lincolnfz4-Aug-06 16:39
memberlincolnfz4-Aug-06 16:39 
AnswerRe: can't Compiling [modified] Pin
Steve Schaneville4-Aug-06 18:16
memberSteve Schaneville4-Aug-06 18:16 
QuestionBug when used with VB Pin
Babar Shafiq Nazmi19-May-06 11:32
memberBabar Shafiq Nazmi19-May-06 11:32 
GeneralSql Intellisense Pin
Steve Schaneville14-Mar-06 18:01
memberSteve Schaneville14-Mar-06 18:01 
GeneralNIF_INFO flag Pin
eugeneugene5-Oct-04 1:35
membereugeneugene5-Oct-04 1:35 
GeneralRe: NIF_INFO flag Pin
Steve Schaneville5-Oct-04 16:36
memberSteve Schaneville5-Oct-04 16:36 
GeneralGreat. Pin
stotti_no14-Oct-04 3:25
memberstotti_no14-Oct-04 3:25 
GeneralRe: Great. Pin
Steve Schaneville4-Oct-04 16:40
memberSteve Schaneville4-Oct-04 16:40 
GeneralBug when using IE 5.0+ Pin
intensely_radioactive7-Jun-04 16:37
memberintensely_radioactive7-Jun-04 16:37 
GeneralRe: Bug when using IE 5.0+ Pin
Steve Schaneville8-Jun-04 12:10
memberSteve Schaneville8-Jun-04 12:10 
GeneralLoadIcon vs LoadImage Pin
eugeneugene@yahoo.com16-May-04 21:37
membereugeneugene@yahoo.com16-May-04 21:37 
GeneralRe: LoadIcon vs LoadImage Pin
Steve Schaneville17-May-04 2:19
memberSteve Schaneville17-May-04 2:19 
GeneralRe: LoadIcon vs LoadImage Pin
_gl4-Aug-11 11:52
member_gl4-Aug-11 11:52 
GeneralShow/HideMinimize Window State Pin
tyounsi18-Feb-04 4:31
membertyounsi18-Feb-04 4:31 
GeneralRe: Show/HideMinimize Window State Pin
Steve Schaneville18-Feb-04 16:51
memberSteve Schaneville18-Feb-04 16:51 
GeneralExcellent example Pin
GifProg16-Nov-03 9:33
memberGifProg16-Nov-03 9:33 
GeneralRe: Excellent example Pin
Steve Schaneville18-Nov-03 10:46
memberSteve Schaneville18-Nov-03 10:46 
GeneralCompiling in .NET Pin
WolfSupernova28-Oct-03 5:23
memberWolfSupernova28-Oct-03 5:23 
GeneralRe: Compiling in .NET Pin
Steve Schaneville28-Oct-03 6:16
memberSteve Schaneville28-Oct-03 6:16 
GeneralRe: Compiling in .NET Pin
Khumpty7-Nov-03 4:59
memberKhumpty7-Nov-03 4:59 
GeneralRe: Compiling in .NET Pin
Khumpty7-Nov-03 5:28
memberKhumpty7-Nov-03 5:28 
GeneralErrors... Pin
Selevercin6-Apr-02 9:11
memberSelevercin6-Apr-02 9:11 
GeneralRe: Errors... Pin
schaneville18-Apr-02 17:45
memberschaneville18-Apr-02 17:45 
Generalme again ... Pin
Anonymous8-Feb-02 16:31
memberAnonymous8-Feb-02 16:31 
GeneralRe: me again ... Pin
schaneville11-Feb-02 5:26
memberschaneville11-Feb-02 5:26 
GeneralThank you! Pin
Karavaev Denis5-Mar-02 23:00
memberKaravaev Denis5-Mar-02 23:00 
QuestionError??? Pin
Karavaev Denis6-Feb-02 23:12
memberKaravaev Denis6-Feb-02 23:12 
AnswerRe: Error??? Pin
schaneville7-Feb-02 10:30
memberschaneville7-Feb-02 10:30 
GeneralRe: Error??? Pin
Karavaev Denis7-Feb-02 18:35
memberKaravaev Denis7-Feb-02 18:35 
GeneralRe: Error??? Pin
schaneville8-Feb-02 4:53
memberschaneville8-Feb-02 4:53 
GeneralRe: Error??? Pin
Karavaev Den8-Feb-02 16:27
memberKaravaev Den8-Feb-02 16:27 
GeneralRe: Error??? Pin
schaneville9-Feb-02 18:04
memberschaneville9-Feb-02 18:04 
QuestionWhy? Pin
CLY5-Feb-02 23:39
memberCLY5-Feb-02 23:39 
AnswerRe: Why? Pin
schaneville6-Feb-02 4:40
memberschaneville6-Feb-02 4:40 
AnswerRe: Why? Pin
Klaus Probst6-Feb-02 10:42
memberKlaus Probst6-Feb-02 10:42 
GeneralRe: Why? Pin
schaneville6-Feb-02 11:33
memberschaneville6-Feb-02 11:33 
GeneralRe: Why? Pin
Klaus Probst6-Feb-02 12:19
memberKlaus Probst6-Feb-02 12:19 
AnswerRe: Why? Pin
Philippe Lhoste11-Feb-02 5:33
memberPhilippe Lhoste11-Feb-02 5:33 
AnswerRe: Why? Pin
Codebender18-Apr-02 8:26
memberCodebender18-Apr-02 8:26 
GeneralRe: Why? Pin
schaneville18-Apr-02 17:35
memberschaneville18-Apr-02 17:35 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150804.4 | Last Updated 5 Feb 2002
Article Copyright 2002 by Steve Schaneville
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid