{********************************************************** ****
* How can I create a TRAY icon? *
Fortunately, Creating An Application That Runs in The System TRAY IS PRETTY EASY -
Only One (API) Function, Shell_Notifyicon, IS NEEDED TO Accomplish The Task.
The Function is defined in the shellapi unit and request two parameters.
THE FIRST Parameter (dwmessage) Specifies the action to be taken.
This Parameter Can Be One of the Following Values:
NIM_ADD: Adds an icon to the status area.
NIM_DELETE: DELETES An icon from The Status Area.
NIM_MODIFY: Modifies an icon in the status area.
* To Display An icon in The System Tray, Call Shell_notifyicon with
The Nim_Add Flag.
* Any Time You want to change the icon, Tooltip text,
ETC, You Can Call Shell_Notifyicon with Nim_Modify.
* Before Your Program Terminates, Call Shell_notifyicon with nim_delete
To Clear Your icon from the system tray.
THE Second Parameter (PNID) IS A Pointer To a TNotifyicondata Structure
Holding the information about the icon.
The TNOTIFYICONDATA STRUCTURE CONTAINS The FOLLOWING Elements:
CBSIZE: Passes The size of the notifyicondata data type.
Data Type: DWORD.
HWnd: Handle of the window Used to receive the notification message.
Data Type: hwnd.
Uid: Identifier of The icon in The Status Area.
Data Type: uint.
Uflags: array of flags That Indicate Which of the Other Members Contain
Valid Data.
Data Type: uint.
Value: Any Combination of the Following Constants To Indicate That
The Member of this structure is valid and will be used:
Nif_ICON: Passing this flag indeicates That the value for the
HiCon Will Be The icon That Appears in the taskbar status area.
Nif_Message: Passing this flag indeicates That the ucallbackmessage
Value Will Be Used As the Callback Message.nif_tip: Passing this flag indeicates That The value of sztip will
Be buy as the tooltip for the icon in the taskbar status area.
UcallbackMessage: Identifier of The Notification Message Sent to the NOTINGIFICATION MESSAGE SENT TO
Window That Is Used to Receive The Messages.
Data Type: uint.
Hicon: Handle of the icon tria is displayed in the taskbar status area.
Data Type: Hicon.
Sztip: String to be used as the tooltip text.
Data Type: fixed-length Ansichar 64 bytes long.
*********************************************************** ***}
Unit
Trayicon
;
Interface
{
A Component to make it it..................
Install this Component in the delphi IDE (Component, Install Component)
And Drop it on a form, and the application automaticly
Becomes a tray icon. This Means That When a Application IS
Minimized, IT Does Not minimize to a Normal Taskbar icon, But
To The Little System Tray on The Side of the Taskbar. a popup
Menu Is Available from The System TRAY ICON, AND YOOL Application
Can Process Mouse Events as The User Moves The Mouse Over
The System TRAY ICON, CLICKS on The icon, ETC.
Copyright? 1996 Tempest Software. All Rights Reserved.
You May Use this Software in An Application Without Fee or Royalty,
Provided this Copyright Notice Remains Intact.
}
Uses
Windows
,
Messages
,
Shellapi
,
Sysutils
,
Classes
,
Graphics
,
CONTROLS
,
Forms
,
Dialogs
,
Menus
;
{
This Message is Sent To The Special, Hidden Window for Shell
Notification Messages. Only Derived Classes Might NEED TO
Know About it.
}
Const
WM_CALLBACK_MESSAGE
=
WM_USER
1
;
Type
TTRAYICON
=
Class
(
Tcomponent
)
Private
FDATA
:
TNotifyicondata
;
Ficon
:
Ticon
;
Fhint
:
String
;
Fpopupmenu
:
TPopupmenu
;
Fclicked
:
Boolean
;
Fonclick
:
TNOTIFYEVENT
;
Fondblclick
:
TNOTIFYEVENT
;
FONMINIMIZE
:
TNOTIFYEVENT
;
Fonmousemove
:
TMOUSEMOVEEVENT
;
FONMOUSEDOWN
:
TMOUSEEVENT
;
FONMOUSEUP
:
TMOUSEEVENT
;
FonRestore
:
TNOTIFYEVENT
;
protected
Procedure
SetHint
(
Const
Hint
:
String
);
Virtual
;
Procedure
Seticon
(
Icon
:
Ticon
);
Virtual
;
Procedure
Appminimize
(
Sender
:
TOBJECT
);
Procedure
AppRestore
(
Sender
:
TOBJECT
);
Procedure
Domenu
;
Virtual
;
Procedure
Click
;
Virtual
;
Procedure
DBLClick
;
Virtual
;
Procedure
Endsession
;
Virtual
;
Procedure
Domousemove
(
Shift
:
TshiftState
;
X
,
Y
:
Integer
);
Virtual
;
Procedure
Domousedown
(
Button
:
TMOUSEBUTTON
;
Shift
:
TshiftState
;
X
,
Y
:
Integer
);
Virtual
;
Procedure
Domouseup
(
Button
:
TMOUSEBUTTON
;
Shift
:
TshiftState
;
X
,
Y
:
Integer
);
Virtual
;
Procedure
OnMessage
(
VAR
MSG
:
TMESSAGE
);
Virtual
;
Procedure
Changed
;
Virtual
;
Property
Data
:
TNotifyicondata
reta
FDATA
;
public
Constructor
Create
(
Owner
:
Tcomponent
);
Override
;
Destructor
DESTROY
;
Override
;
Procedure
Minimize
;
Virtual
;
Procedure
RESTORE
;
Virtual
;
Published
Property
Hint
:
String
reta
Fhint
Write
SetHint
;
Property
Icon
:
Ticon
reta
Ficon
Write
Seticon
;
Property
Popupmenu
:
TPopupmenu
reta
Fpopupmenu
Write
Fpopupmenu
;
Property
Onclick
:
TNOTIFYEVENT
reta
Fonclick
Write
Fonclick
;
Property
Ondblclick
:
TNOTIFYEVENT
reta
Fondblclick
Write
Fondblclick
;
Property
Onminimize
:
TNOTIFYEVENT
reta
FONMINIMIZE
Write
FONMINIMIZE
;
Property
OnMousemove
:
TMOUSEMOVEEVENT
reta
Fonmousemove
Write
Fonmousemove
;
Property
OnMouseDown
:
TMOUSEEVENT
reta
FONMOUSEDOWN
Write
FONMOUSEDOWN
;
Property
OnMouseup
:
TMOUSEEVENT
reta
FONMOUSEUP
Write
FONMOUSEUP
;
Property
OnRestore
:
TNOTIFYEVENT
reta
FonRestore
Write
FonRestore
;
end
;
Procedure
Register
;
IMPLEMentation
{
Create The Component. At Run-Time, Automatic Or Add A TRY ICON
WITH A Callback to a hidden window. Use the application icon and title.
}
Constructor
TTRAYICON
.
Create
(
Owner
:
Tcomponent
);
Begin
inherited
Create
(
Owner
);
Ficon
: =
Ticon
.
Create
;
Ficon
.
ASSIGN
(
Application
.
Icon
);
IF
NOT
(
csdesigning
in
ComponentState
)
THEN
Begin
Fillchar
(
FDATA
,
Sizeof
(
FDATA
),
0
);
FDATA
.
CBSIZE
: =
Sizeof
(
FDATA
);
FDATA
.
WND
: =
Allocatehwnd
(
OnMessage
);
// Handle to get Notification MESSAGE
FDATA
.
Hicon
: =
Icon
.
Handle
;
// icon to display
STRPLCOPY
(
FDATA
.
SZTIP
,
Application
.
Title
,
Sizeof
(
FDATA
.
SZTIP
)
-
1
);
FDATA
.
Uflags
: =
NIF_ICON
oral
Nif_message
;
IF
Application
.
Title
<>
'' '
THEN
FDATA
.
Uflags
: =
FDATA
.
Uflags
oral
Nif_tip
;
FDATA
.
UcallbackMessage
: =
WM_CALLBACK_MESSAGE
;
IF
NOT
Shell_notifyicon
(
NIM_ADD
,
@
FDATA
)
THEN
// Add IT
Raise
EoutofResources
.
Create
(
'Cannot Create Shell NOTIFICATION ICON'
);
{
Replace the Application's Minimize and Restore Handlers with
Special Ons for the TRAY. The Trayicon Component Has ITS OWN
Onminimize and onRestore Events That The User CAN SET.
}
Application
.
ONMINIMIZE: =
Appminimize
;
Application
.
OnRestore
: =
AppRestore
;
end
;
end
;
{REMOVE The icon from the system tray.
Destructor
TTRAYICON
.
DESTROY
;
Begin
Ficon
.
Free
;
IF
NOT
(
csdesigning
in
ComponentState
)
THEN
Shell_notifyicon
(
NIM_DELETE
,
@
FDATA
);
inherited
DESTROY
;
end
;
{WHENEVER ANY Information Changes, Update The System Tray.
Procedure
TTRAYICON
.
Changed
;
Begin
IF
NOT
(
csdesigning
in
ComponentState
)
THEN
Shell_notifyicon
(
NIM_MODIFY
,
@
FDATA
);
end
;
{When the application is minimized, minimize to the system tray.
Procedure
TTRAYICON
.
Appminimize
(
Sender
:
TOBJECT
);
Begin
Minimize
end
;
{When Restoring from the system tray, restore the application.
Procedure
TTRAYICON
.
AppRestore
(
Sender
:
TOBJECT
);
Begin
RESTORE
end
;
{
Message handler for the hidden shell notification window.
MOST Messages Use WM_Callback_Message As the MSG ID, with WITH
WParam as the id of the shell notify icon data. Lparam IS
A Message ID for the actual message, E.G., WM_MOUSEMOVE.
Another Important Message IS WM_ENDSESSION, TELLING THE
Shell Notify Icon To Delete Itself, So Windows Can Shut Down.
Send The Usual Delphi Events for the Mouse Messages. Also
Interpolate the Onclick Event WHEN THE USER CLICKS THE
Left button, and popup the menu, if there is one, for
Right Click Events.
}
Procedure
TTRAYICON
.
OnMessage
(
VAR
MSG
:
TMESSAGE
);
{Return the state of the shift keys.}
FUNCTION
ShiftState
:
TshiftState
;
Begin
Result
: =
[];
IF
GetKeyState
(
VK_SHIFT
)
<
0
THEN
Include
(
Result
,
Ssshift
);
IF
GetKeyState
(
VK_Control
)
<
0
THEN
Include
(
Result
,
Ssctrl
);
IF
GetKeyState
(
VK_MENU
)
<
0
THEN
Include
(
Result
,
Ssalt
);
end
;
VAR
PT
:
TPOINT
;
Shift
:
TshiftState
;
Begin
Case
MSG
.
MSG
Of
WM_QUERYENDSession
:
MSG
.
Result
: =
1
;
WM_ENDSESSION
:
IF
TWMENDSESSION
(
MSG
).
Endsession
THEN
Endsession
;
WM_CALLBACK_MESSAGE
:
Case
MSG
.
lparam
Of
WM_MOUSEMOVE
:
Begin
Shift
: =
ShiftState
;
Getcursorpos
(
PT
);
Domousemove
(
Shift
,
PT
.
X
,
PT
.
Y
);
end
;
WM_LBUTTONDOWN
:
Begin
Shift
: =
ShiftState
[
SSLEFT
];
Getcursorpos
(
PT
);
Domousedown
(
Mbleft
,
Shift
,
PT
.
X
,
PT
.
Y
);
Fclicked
: =
True
;
end
;
WM_LBUTTONUP
:
Begin
Shift
: =
ShiftState
[
SSLEFT
];
Getcursorpos
(
PT
);
IF
Fclicked
THEN
Begin
Fclicked
: =
False
;
Click
;
end
;
Domouseup
(
Mbleft
,
Shift
,
PT
.
X
,
PT
.
Y
);
end
;
WM_LBUTTONDBLCLK
:
DBLClick
;
WM_RBUTTONDOWN
:
Begin
Shift
: =
ShiftState
[
Sright
];
Getcursorpos
(
PT
);
Domousedown
(
Mbright
,
Shift
,
PT
.
X
,
PT
.
Y
);
Domenu
;
end
;
WM_RBUTTONUP
:
Begin
Shift
: =
ShiftState
[
Sright
];
Getcursorpos
(
PT
);
Domouseup
(
Mbright
,
Shift
,
PT
.
X
,
PT
.
Y
);
end
;
WM_RBUTTONDBLCLK
:
DBLClick
;
WM_MBUTTONDOWN
:
Begin
Shift
: =
ShiftState
[
SSMIDDLE
];
Getcursorpos
(
PT
);
Domousedown
(
MBMIDDLE
,
Shift
,
PT
.
X
,
PT
.
Y
);
end
;
WM_MBUTTONUP
:
Begin
Shift
: =
ShiftState
[
SSMIDDLE
];
Getcursorpos
(
PT
);
Domouseup
(
MBMIDDLE
,
Shift
,
PT
.
X
,
PT
.
Y
);
end
;
WM_MBUTTONDBLCLK
:
DBLClick
;
end
;
end
;
end
;
{Set a new hint, which is the Tool Tip for the shell icon.}
Procedure
TTRAYICON
.
SetHint
(
Const
Hint
:
String
);
Begin
IF
Fhint
<>
Hint
THEN
Begin
Fhint
: =
Hint
;
STRPLCOPY
(
FDATA
.
SZTIP
,
Hint
,
Sizeof
(
FDATA
.
SZTIP
)
-
1
);
IF
Hint
<>
'' '
THEN
FDATA
.
Uflags
: =
FDATA
.
Uflags
oral
Nif_tip
Else
FDATA
.
Uflags
: =
FDATA
.
Uflags
and
NOT
Nif_tip
;
Changed
;
end
;
end
;
{Set a new icon. Update the system tray.
Procedure
TTRAYICON
.
Seticon
(
Icon
:
Ticon
);
Begin
IF
Ficon
<>
Icon
THEN
Begin
Ficon
.
ASSIGN
(
Icon
);
FDATA
.
Hicon
: =
Icon
.
Handle
;
Changed
;
end
;
end
;
{
When the user right clicks the icon, call donnu.
If there is a popup menu, and if the window is minimize,
.
}
Procedure
TTRAYICON
.
Domenu
;
VAR
PT
:
TPOINT
;
Begin
IF
(
Fpopupmenu
<>
NIL
)
and
NOT
IswindowVisible
(
Application
.
Handle
)
THEN
Begin
Getcursorpos
(
PT
);
Fpopupmenu
.
Popup
(
PT
.
X
,
PT
.
Y
);
end
;
end
;
Procedure
TTRAYICON
.
Click
;
Begin
IF
Assigned
(
Fonclick
)
THEN
Fonclick
(
Self
);
end
;
Procedure
TTRAYICON
.
DBLClick
;
Begin
IF
Assigned
(
Fondblclick
)
THEN
Fondblclick
(
Self
);
end
;
Procedure
TTRAYICON
.
Domousemove
(
Shift
:
TshiftState
;
X
,
Y
:
Integer
);
Begin
IF
Assigned
(
Fonmousemove
)
THEN
Fonmousemove
(
Self
,
Shift
,
X
,
Y
);
end
;
Procedure
TTRAYICON
.
Domousedown
(
Button
:
TMOUSEBUTTON
;
Shift
:
TshiftState
;
X
,
Y
:
Integer
);
Begin
IF
Assigned
(
FONMOUSEDOWN)
THEN
FONMOUSEDOWN
(
Self
,
Button
,
Shift
,
X
,
Y
);
end
;
Procedure
TTRAYICON
.
Domouseup
(
Button
:
TMOUSEBUTTON
;
Shift
:
TshiftState
;
X
,
Y
:
Integer
);
Begin
IF
Assigned
(
FONMOUSEUP
)
THEN
FONMOUSEUP
(
Self
,
Button
,
Shift
,
X
,
Y
);
end
;
{
When the Application Minimizes, Hide IT, So Only the icon
In The System TRAY IS VISIBLE.
}
Procedure
TTRAYICON
.
Minimize
;
Begin
Showwindow
(
Application
.
Handle
,
SW_HIDE
);
IF
Assigned
(
FONMINIMIZE
)
THEN
FONMINIMIZE
(
Self
);
end
;
{
RESTORE The Application By Making ITS Window Visible Again,
Which is a little weird sinces window is invisible, having
No Height or Width, But That's What Determines WHether The Button
Appears on the taskbar.
}
Procedure
TTRAYICON
.
RESTORE
;
Begin
Showwindow
(
Application
.
Handle
,
SW_RESTORE
);
IF
Assigned
(
FonRestore
)
THEN
FonRestore
(
Self
);
end
;
{Allow Windows to EXIT BY DELETING The shell Notify icon.}
Procedure
TTRAYICON
.
Endsession
;
Begin
Shell_notifyicon
(
NIM_DELETE
,
@
FDATA
);
end
;
Procedure
Register
;
Begin
Registercomponents
(
'Tempest'
,
[
TTRAYICON
]);
end
;
end
.
Excerpt from: http://blog.9cbs.net/safef8/archive/2005/01/24/26654.aspx