The New TTrayIcon Component in BDS 2006.
When I first encountered tray icons back in the days of Windows 95, I
thought they were rather neat, but of limited usefulness. How many
applications could really make effective use of this concept? Well, many
years later, it turns out that quite a few applications can and do. There
are currently no fewer than eight such icons in my system tray right now,
and many people have even more.
There have been numerous tray icon components floating around for years
from various sources, but with the release of BDS 2006, Borland has
finally included their very own TTrayIcon component. The basic operation
is straight-forward and you can be up and running within minutes.
Getting started
TTrayIcon is found under the Additional section of the Tool Palette. Add
the component to the form, set the visible property to true, run your
application, and congratulate yourself on a job well done. This is what we
get paid the big bucks for.
Of course, while the tray icon looks nice, we have to put in a little
more effort to get it to actually do something. See the sample
project
for a demo of the tray icon in action.
Peek a boo
A standard function for a tray icon is to allow the user to hide and
restore an application. This is a great way to keep utility apps close at
hand, yet out of the way.
To hide your application just use the Hide method of each visible form in
your application. This will automatically remove your application's icon
from the Windows task switcher as well as the task bar.
Application.Minimize can optionally be called as well, but note that it
will result in an animation of the form being minimized to the task bar
rather than to the system tray.
It's important that you hide the forms from the top-most form down to the
bottom-most form, and restore the forms in the opposite order. This will
ensure that the Z-order is preserved when restoring your application.
This is critical when dealing with modal dialog boxes. The simples way to
ensure that the correct order is used is to iterate forward through the
Screen.Forms array when hiding your application, and iterating backward
when restoring. For example, to hide them all:
var
k: integer;
begin
application.Minimize;
for k := 0 to Screen.FormCount - 1 do begin
Screen.Forms[k].Hide;
end;
end;
To restore the application, add the following code to the tray icon's
OnClick event handler.
var
k: integer;
begin
for k := Screen.FormCount - 1 downto 0 do begin
Screen.Forms[k].Show;
end;
application.Restore;
application.BringToFront;
end;
In the sample project I used a button to hide the application, but it's a
much more natural experience if you hide the application in response to
the TApplicationEvents component's OnMinimize event. Some applications
require a double click to restore an application rather than a single
click, but performing a double click within a 16 pixel square area
requires a certain dexterity that not everyone has. In fact, you may want
to consider using a global hotkey as an additional way of restoring the
application. Make sure that the user can customize the shortcut in case
of conflicts with other applications.
What's on the menu?
Adding a menu to the tray icon is even easier than hiding and restoring
your application. Add a TPopupMenu component to the form and assign it to
the tray icon's PopupMenu property. Add the relevant menu items and their
associated event handlers and away you go. I was worried that there might
be problems trying to close the application when a modal child form was
displayed, but this seems to work just fine.
Note that in BDS 2006 Update 1 the TTrayIcon does not correctly set it's
PopupMenu property to nil when the associated component is deleted. To
avoid access violations and other general weirdness, be sure to clear the
PopupMenu property before deleting the TPopupMenu component.
Pretty pictures
By default the tray icon will use the application's icon, but this can
overridden by either loading an icon into the Icon property, or by
assigning a TImageList instance to the Icons property and setting an
appropriate value for the IconIndex property.
If you're using an ImageList you can animate the icons by setting the
Animate property to true. This will cause each icon in the image list to
be displayed in turn. How rapidly it changes is controlled by the
AnimateInterval property.
Hints
Hints are easy. Assign some text to the Hint property and that text will
appear when the user pauses the mouse over the tray icon. If the Hint
property is empty then the application's Title as set in Project - Options
- Application - Title will be displayed. Windows limits the length of the
hint to 127 characters. If you have some text assigned to the Hint
property, and then assign a blank string to it, you may find that Window
still displays the old text. This appears to be a issue with Windows
rather than with Delphi.
99 red balloons
Sorry, you'll have to settle for yellow balloons. A balloon hint is best
used to alert the user to a non-critical event.
Multiple applications can display balloon hints and Windows will ensure
each will get displayed one at a time for a minimum length of time. Once
a balloon is visible a user can click on it to make it disappear. If a
user doesn't click on it the balloon will disappear automatically after
it times out - assuming that a user is active on the system. If the
computer is idle, then the balloon will remain visible until the user
starts using the computer again. The timeout can be set by the
application but Windows enforces minimum and maximum values which are
typically set to 10 and 30 seconds.
If multiple applications display balloons then Windows will leave about a
two second gap between displaying balloons. If a single application
displays two balloon in rapid succession, the first hint will immediately
be replaced by the second hint.
Of course, your balloons might not be displayed at all if the user has
disabled them in the registry by setting the EnableBalloonTips value to 0
in:
HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerAdvanced
With these things in mind, let's get down to displaying a balloon. The
relevant properties are BalloonFlags, BalloonHint, BalloonTimeout, and
BalloonTitle.
BalloonFlags shows the usual icons that you see in message boxes - Error,
Info, and Warning. BalloonHint contains the actual text within the
balloon and BalloonTitle is used for the caption of the balloon. The
BalloonHint is limited to 255 characters and the BalloonTitle is limited
to 63 characters. The BalloonTimeout tells Windows how long to wait (in
milliseconds) before hiding the balloon automatically. As mentioned
earlier the acceptable range is usually 10 to 30 seconds. Call the
ShowBalloonHint procedure to actually display the balloon.
If you wish to manually hide a balloon hint rather than letting it time
out, change the BalloonHint to an empty string and call ShowBalloonHint.
The appearance of balloon hints can vary from system to system. For
example, here's a balloon hint from the demo program running under Windows
2000:
and under Windows 2003:
Conclusion
A tray icon is a great tool, but don't get carried away with it. Always
give users the option of disabling the tray icon and in particular the
balloon hints.
See the sample
project
for a demonstration of the TTrayIcon in action.