Tray Icons 

www.madshi.net

With madKernel you can manage tray icons (see API "Shell_NotifyIcon") of any application. This kind of functionality is totally undocumented, but works well from win95 to winXP. A single tray icon is encapsulated in the "ITrayIcon" interface, a group of tray icons is wrapped up in the "ITrayIcons" interface. See also the ITrayIcon Reference and the ITrayIcons Reference.

type
  ITrayIcon  = interface (IBasic)           ['{4BFE6700-C522-11D3-A530-00005A180D69}'];
  ITrayIcons = interface (ICustomBasicList) ['{4BFE6701-C522-11D3-A530-00005A180D69}'];

There are two ways to get an ITrayIcons instance, namely either by calling IProcess.TrayIcons or by calling the function "TrayIcons", which enumerates all tray icons of your application or all tray icons of all processes system wide. Currently the only way to get an ITrayIcon instance is to use the ITrayIcons.Items property. The method "RefreshItems" looks for new, deleted or changed tray icons.

function TrayIcons (systemWide: boolean = true) : ITrayIcons;

property ITrayIcons.Items [index: integer] : ITrayIcon;

function ITrayIcons.RefreshItems : boolean;

// Example:
MessageBox(0, pchar('we have ' + IntToStr(TrayIcons.ItemCount) + ' tray icons'), 'info', 0);;

Each tray icon has an application defined identifier:

function ITrayIcon.ID : cardinal;

Which window is responsible to handle the messages of this tray icon? And which private message number is used? You can get and also set those values. This way you can even take over control of other process' tray icons.

property ITrayIcon.Window  : IWindow;
property ITrayIcon.Message : cardinal;

// Example:
MessageBox(0, pchar(TrayIcons[0].Window.OwnerProcess.ExeFile), 'the first tray icon belongs to', 0);

Which hint is shown for this tray icon? Which graphical icon does it show? The "ImageIndex" property only makes sense in connection with the ITrayIcons.ImageList property:

property ITrayIcon.Hint       : string;
property ITrayIcon.ImageIndex : integer;
property ITrayIcon.Icon       : cardinal;

property ITrayIcons.ImageList : cardinal;

// Example:
MessageBox(0, pchar('"' + TrayIcons[0].Hint + '"'), 'the first tray icon''s hint is', 0);

Which position/size does the tray icon have on screen?

property ITrayIcon.Rect : TRect;

You can simulate tray icon mouse events:

procedure ITrayIcon.MouseMove;
procedure ITrayIcon.MouseClick (right: boolean = true; double: boolean = false);

// Example:
TrayIcons[0].MouseClick;  // single right click on the first tray icon

You can access the visibility change of the tray icons by using the following methods. A hidden tray icon is automatically shown again in the moment when the ITrayIcon instance gets freed. That means the visibility is only changed temporarily.

property ITrayIcon.Visible : boolean;
function ITrayIcon.Hide    : boolean;
function ITrayIcon.Show    : boolean;

// Example:
with TrayIcons[0] do begin
  Hide;
  MessageBox(0, 'first tray icon is temporarily hidden now', 'info', 0);
  Show;
end;

In order to delete this tray icon completely use:

function ITrayIcon.Delete : boolean;

// Example:
TrayIcons[0].Delete;  // delete the first tray icon

The following ITrayIcons methods are more or less identical to the ITrayIcon methods with the same name. It's just that if you call the ITrayIcons methods, they are called for all tray icons in the list.

function ITrayIcons.Hide : boolean;
function ITrayIcons.Show : boolean;

function ITrayIcons.Delete : boolean;

// Example:
TrayIcons.Delete;  // delete all tray icons (ouch)

Does this ITrayIcons instance only enumerate tray icons of a specific process?

property ITrayIcons.OwnerProcess : IProcess;