Adding Icons to the System TRAY

xiaoxiao2021-04-08  365

Download Demo Project (INC. CE 2.0 Project) - 145.1 KB Download Non-MFC Demo Project - 43.4 KB Download Source Files - 22.6 KB

Example Images in Windows 9X, Windows CE and Windows 2000

IntroductionConstructionOperationsicon Minimising An Application To The System TrayDefault Message Handlingexample of UseNote on TRACKPOPUPMENUHISTORYLATEST

Introduction

CSystemTray is a conglomeration of ideas from the MSJ "Webster" application, sniffing round the online docs, from other implementations such as PJ Naughter's "CTrayNotifyIcon" (http://indigo.ie/~pjn/ntray.html), and from the Many Contributions from Other Developers.

This class is a light wrapper around the windows system tray stuff. It adds an icon to the system tray with the specified ToolTip text and callback notification value, which is sent back to the Parent window.

The Old Way:

THE Basic Steps to Using A TRAY ICON VIA The Windows API Are:

Load up the notifyicondata structure call shell_notifyicon (nim_add, & mytraynotifystructure)

Changing the values ​​of the fields in NOTIFYICONDATA and calling Shell_NotifyIcon allows you to change to icon or tool tip text or remove the icon itelf. All this messing around has been bundled in a class wrapper to make it easier and neater.

Better Way

The simpler way to add an icon to the system tray is to create an object of type CSystemTray either as a member variable or dynamically. Two forms of the constructor allow the programmer to insert the icon into the tray as the CSystemTray object is created, or By Using the Member Function Csystemtray :: Create. EG.

Csystemtray M_Trayicon; // Member Variable of Some Class

...

// in Some Member Function Maybe ...

M_Trayicon.create (PParentWnd, WM_MY_NOTIFY, "Click Here", Hicon, Ntrayiconid;

......................

To mfc or not to mfc ...

There are two forms of the class: MFC and Non-MFC They are in the SystemTray * and SystemTraySDK * files respectively The MFC version has been written to use MFC classes (CWnd etc) whereas the non-MFC will use HWND's.... . I May in Future Revise this So They Both Use HWnd's for Optimum Compatibility.

Both classes have essentially the same functionality, excepting that the non-MFC version only supports a single tray icon per application. Because the non-MFC version is not derived from CWnd you need to be careful about the window you choose to receive the icon messages . If you set the parent of the icon as NULL, then the tray icon will handle it's own tray notification messages -. but will also try and handle the menu commands sent from the context menu for the icon to get around this you need to either :

Set The Parent of The THE ICON As A WINDOW THAT WILL HANDLE ALL TRY ICON NOTIFICATIONS, AND USE CSYSTEMTRAY: SETTARGETWND TO NOMINATE The WINDOW THAT WILL Receive The Menu Commands.

Eg. For a non-mfc TRAY ICON, DO The FOLLOWING:

Csystemtray M_Trayicon; // Member Variable of Some Class

...

// in Some Member Function Maybe ...

m_trayicon.create (Hinstance, NULL, WM_MY_NOTIFY,

"Click Here", Hicon, NID);

// send all menu messages to hmymainwindow

m_trayicon.SetTargetWnd (HMYMAINWINDOW);

CONSTRUCTION

Csystemtray ();

Csystemtray (CWND * PWND, UINT UCALLBACKMESSAGE, LPCTSTR SZTOOL,

Hicon icon, uint uid, bool bhidden = false,

LPCTSTST SZBALLOONTIP = NULL, LPCTSTST SZBALLOONTITE = NULL, DWORD DWBALLOONICON = niif_none, uint uballoontimeout = 10);

Bool Create (CWND * PWND, UINT UCALLBACKMESSAGE, LPCTSTSTSTOOLTIP,

Hicon icon, uint uid, bool bhidden = false,

LPCTSTSTSZBALLOONTIP = NULL, LPCTSTS SZBALLOONTITE = NULL,

DWORD dwballoonicon = niif_none, uint uballoontimeout = 10);

The Non-MFC Version Includes An Additional Parameter (Parameter 1) That Represents the Applications Instance Handle.

Note That The Destructor Automatically Removes The icon from the TRAY.

pWndWindow where notification messages will be sent. May be NULLuCallbackMessageThe notification messages that will be sent to the parent windowszToolTipTooltip for the tray iconiconHandle to the icon to be displayeduIDTray icon IDbHiddenIf TRUE, the icon is initially hiddenszBalloonTip The balloon tip text (Windows 2000 only) szBalloonTitle THE Balloon Tip Title Dwballoonicon The Balloon Tip icon (Windows 2000 Only) Uballoontimeout The Balloon Tip Timeout (Windows 2000 Only)

IF The PWND Parameter Is Null The Function Csystemtray :: Ontraynotification Will Be Called WHENEVER The Icon Sends a Notification Message. See default message handling for more details.

Operations

Lresult ontrayNotification (WPARAM WID, LPARAM LEVENT) // Discussed Below

Void MoveToright () // Moves The icon to the far right of the TRAY,

// SO it is immediately to the left of the clock

Void Hideicon () // Hides But Does Not Totally Remove The icon

// from the tray.

Void Removeicon () // Removes the icon from the TRAY (icon can no

// longer be manipulate

Void showicon () // redisplays a prepviously hidden iconvoid addicon () // address the icon to the THE TRY

Void setfocus (// sets the focus to the icon (win2000 only)

Bool Showballoon (LPCTSTSTSTEXT, // Shows The Balloon Tip (Win2000 Only)

LPCTSTS SZTITLE = NULL,

DWORD dwicon = niif_none,

Uint utimeout = 10);

Bool SetTooltiptext (LPCTSTR PSZTIP) // Set Tooltip Text

Bool SetTooltiptext (Uint Nid) // Set Tooltip from Text Resource ID

CString GetTooltiptext () Const // Retrieve Tool Tip Text

Bool setNotificationWnd (CWND * PWND) // Self Explanatory

CWnd * getNotificationWnd () const

Bool setTargetWnd (CWND * PTARGETWND); // Change Or Retrieve The Window To

CWND * getTargetWnd () const; // send menu Commands to

Bool SetCallbackMessage (uint ucallbackmessage) // Self Explanator

Uint getCallbackMessage () Const;

Hicon geticon () const // get current TRAY icon

Bool Seticon // Change Tray icon. Returns False

// if unsuccessful

Bool Seticon (LPCTSTR LPSZICONNAME) // Same, Using Name of The icon Resource

Bool seticon (uint nidResource) // Same, use iCon Resource ID

Bool SetStandardon (LPCTSTR LPICONNAME) // loading icon from the

Bool SetStandardIn (uint nidresource) // Current Application

// set list of icons for animation

Bool seticonlist (uint uLirsticonid);

Bool SeticonList (Hicon * Phiconlist, Uint Nnumicons);

// Start Animation

Bool Animate (uint ndlaymilliseconds, int nnumseconds = -1);

Bool stepanimation (); // step to next icon

Bool StopaniMation (); // stop animation

Bool SetmenudeFault (Uint UItem, Bool Bbypos); // Set Default Menu Itemvoid getmenudeFault (Uint & UITEM, BOOL & BBYPOS); // Get Default Menu Item

Static void MinimiMisetTray (CWND * PWND);

Static void maximiseFromtray (CWND * PWND, CRECTTTO);

Static void maximiseFromtray (CWND * PWND, LPCREATESTRUCT LPCREATESTRUCT);

Virtual Void CustomizeMenu (cfenu *) // Customise the Context Menu Before It's

// displayed

SetStandardicon Can Also Take Any of The Following Values ​​(Not Available In Wince):

nIDResource Description IDI_APPLICATION Default application icon. IDI_ASTERISK Asterisk (used in informative messages). IDI_EXCLAMATION Exclamation point (used in warning messages). IDI_HAND Hand-shaped icon (used in serious warning messages). IDI_QUESTION Question mark (used in prompting messages). IDI_WINLOGO Windows Logo

. The default CSystemTray message notification handler searches and displays the menu with the same ID as the tray icon If you use this default handler then you can set the default menu item using SetMenuDefaultItem The parameters uItem and bByPos are the same as those used in.: : SetmenudefaultItem.

The Default Menu Item Code Was Controluted by Enrico Lelina.

Minimising An Application To The System TRAY

Two functions have been provided to allow you to easily "minimise" an application:

Static void MinimiMisetTray (CWND * PWND);

Static void maximiseFromtray (CWND * PWND);

WHERE PWND is The Window To Minimise or Maximise (Usually Your Main Application Window).

"Minimising to the system tray" means that the applications main window is minimised using the DrawAnimatedRects function to make it appear that it is collapsing into the system tray. The main applications window is then made invisible and the applications icon is removed from the task bar . to minimise an application to the system tray simply call MinimiseToTray. System tray minimisation was inspired by Santosh Rao.If an application has been minimised to the tray, then it can be maximised again by calling MaximiseFromTray. For example, if you have a CDialog derived class that you display in response to a user double-clicking on the tray icon (or selecting a menu item from the popup menu), then override the OnDestroy and OnShowWindow functions in your CDialog class and add the following lines:

Void CMYDIALOG :: ONDESTROY ()

{

CDIALOG :: ONDESTROY ();

Csystemtray :: minimiMisetTray (this);

}

Void CMYDIALOG :: OnShowWindow (Bool Bshow, uint nstatus)

{

CDIALOG :: OnShowWindow (BShow, NStatus);

IF (BSHOW)

Csystemtray :: MaximiseFromtray (this);

}

Icon Animation

Icon animation can be achieved by specifying a list of icons using SetIconList (...), with either a range of icon resource IDs, or an array of HICONs and the size of the array. And calling Animate (UINT nDelayMilliSeconds, int nNumSeconds) . The first parameter is the delay in milliseconds between each animation frame, and the second is the numer of seconds for which to animate the icon. If -1 is specified then animation will continue until stopAnimation () is called. icon animation was suggested by Joerg Koenig.

Default message Handling, DEFAULT MESSAGE

The parent window, on receiving a notification message, can redirect this message back to the tray icon for handling by calling CSystemTray :: OnTrayNotification (...). Alternatively, if the CSystemTray object was created with a NULL parent, then this function will be called whenver the icon sends a notification. The default implementation tries to find a menu with the same resource ID as the tray icon. If it finds a menu and the event received was a right mouse button up, then the submenu is displayed as a CONTEXT MENU. IF A Double Click Was Received, THE Message ID of First Item in The Submenu Is Sent Back to The Parent Window.Using The New Windows 2000 / IE5 Balloon Tips

The New Balloon Tips Rely on Shell32.dll To Be Version 5.0 or Later, and for the the_win32_ie to be defined as 0x0500 or higher in your source code. There is:

Assume that your users will have version 5.0 installed and add #define _WIN32_IE 0x0500 Do it properly and use DllGetVersion to get the version of Shell32.dll and adjust your code accordingly Thanks to Porgee for quoting the MSDN tip.:

Use the dllgetversion function to determine which shell32.dll version is installed on the system. If it is version 5.0 or greater, initialize the cbsize member with:

Nid.cbsize = sizeof (notifyicondata);

Setting cbSize to this value enables all the version 5.0 and 6.0 enhancements. For earlier versions, the size of the pre-6.0structure is given by the NOTIFYICONDATA_V2_SIZE constant and the pre-5.0 structure is given by the NOTIFYICONDATA_V1_SIZE constant. Initialize the cbSize member with :

Nid.cbsize = notifyicondata_v2_size;

Using this value for cbSize will allow your application to use NOTIFYICONDATA with earlier Shell32.dll versions, although without the version 6.0 enhancements.I currently use the lazy method. There is a define ASSUME_IE5_OR_ABOVE in the system tray header that determines whether or not version 5.0 OR Above Should Be Assumed Present. Comment this out for applications targeting shell32.dll Versions LESS THAN 5.0.

Example of use

.

#define WM_ICON_NOTIFY WM_APP 10

Csystemtray M_Trayicon

Add a Message Map Entry for the TRAY ICON NOTIFICATION:

Begin_MESSAGE_MAP (CMAINFRAME, CFRAMEWND)

...

ON_MESSAGE (WM_ICON_NOTIFY, ONTRAYNOTIFICATION)

END_MESSAGE_MAP ()

Create the icon (maybe in Your Oncreate):

IF (! m_trayicon.create (this, wm_icon_notify, strtooltip,

Hicon, IDR_POPUP_MENU)))

Return -1;

WHERE IDR_POPUP_MENU Is The id of a popup menu to display for the icon. You1n Need a Handler for the TRY ICON NOTIFICATION MESSAGE:

Lresult CMAINFRAME :: Ontraynotification (WPARAM WPARAM, LPARAM LPARAM)

{

// delegate all the work back to the default

// Implementation in csystemtray.

Return M_Trayicon.ontrayNotification (WPARAM, LPARAM);

}

THE MENU Used (idR_popup_menu) Looks Like The Following:

IDR_POPUP_MENU MENU PRELOAD DISCARDABLE

Begin

Popup "Popup_Menu"

Begin

Menuitem "& About ...", ID_APP_ABOUT

Menuitem Separator

Menuitem "& Options ...", ID_APP_OPTIONS

Menuitem Separator

Menuitem "E & XIT", ID_APP_EXIT

End

End

A single right click on the tray icon will bring up this menu, while a double click will send a ID_APP_ABOUT message back to the frame. (Note that in CE, ALT Left button will bring up the menu, and ALT Double Click will perform the default action) .Alternatively, you can m_TrayIcon.Create (NULL, ...) and leave out the message map entry for WM_ICON_NOTIFY. The default implementation of CSystemTray will take care of the rest.

Note on TRACKPOPUPMENU

Many people have had troubles using TrackPopupMenu. They have reported that the popup menu will often not disappear once the mouse is clicked outside of the menu, even though they have set the last parameter of TrackPopupMenu () as NULL. This is a Microsoft "feature ", and is by design. The Mind Boggles, Doesn't it?

Anyway - to workaround this "feature", one must set the current window as the foreground window before calling TrackPopupMenu This then causes a second problem -. Namely that the next time the menu is displayed it displays then immediately disappears To fix this problem,. You must make the currernt application active after the menu disappears. This can be done by sending a benign message such as wm_null to the current window.

SO - What Should Have Been A Simple:

TRACKPOPUPMENU (HSubmenu, TPM_RightButton, Pt.x, Pt.y, 0, HDLG, NULL);

Becomes

SetForegroundWindow (HDLG);

TRACKPOPUPMENU (HSubmenu, TPM_RightButton, Pt.x, Pt.y, 0, HDLG, NULL);

PostMessage (HDLG, WM_NULL, 0, 0);

Refer to kb article "PRB: MENUS for Notification Icons Don't Work Correctly" for more info.

History

I Updated The Class So It Would Work IN CE. A CE Demo Project Is Now Included.

Thomas Mooney helped make changes that allows the class to be used in an NT service. The problem occured when using CSystemTray in an application that runs as a service on NT. When NT starts, the application starts. Trouble is, there is no taskbar, NOSSTEM TRAY, NOWHERE TO PUT The Icon Until Someone Has Logged On. This Has Been fixed.michael Dun Added Windows 2000 Support - Namely Those Way Cool Balloon Tips.

.............................. ..

21 Sep 2000 -. Matthew Ellis has improved the minimise-to-tray functionality by providing an improved version of the GetTrayWndRect function that searches for the location of the system tray He has also provided a function GetDoWndAnimation that checks if the system has been set to SHOW WINDOW Animation (for minimise / maximise), and if not, no animation will be shown.

The. Also a Non-MFC Version.

Håkan Trygg Has Updated The Class with The Following:

Instead of always sending the menu messages to the Main window (AfxMainWnd) they get sent to another, specified window. It's called the target window. If there is no specified window then AfxMainWnd is used.

The New Functions Are

Bool setTargetWnd (CWND * PTARGETWND);

CWND * GetTargetWnd () Const;

Also: The Creation Flags of The THE ICON ARE Saved So That If The icon Needs To Be Recreated (Settings Change, Taskbar Recreated "THEN ICON WILL BE CREATED PREC).

16 Jun 2002 Added The Assume_IE5_ABOVE Define and fixed VC 7.0 Compile Errors.

3 Aug 2003 - Added a Bunch of Small Fixes As Well As The CustomizeMenu Method. Thanks, Treskunov for this and the fixes.håkan trygg Has Also methods added to hold and change the menu.

Bool SetMenutext (Uint UICMD, LPCTSTSTSTEXT);

Bool SetMenutext (Uint UIID);

Bool CHECKMENUITEM (Uint UICMD, Bool Bcheck);

Bool EnableMenuItem (Uint UICMD, BOOL BENABLE);

Bool DeleteMenu (UINT UICMD);

. The updated class files can be downloaded here They have not been merged into the main class yet simply becuase I have not had time to test - but I felt them important enough that I did not want to delay making them available.

转载请注明原文地址:https://www.9cbs.com/read-132770.html

New Post(0)