看看这个控件的源码<br><br>{ TTrayIcon VCL. Version 1.3<br><br> Requires: Delphi 2.0 32 bit.<br><br> Function: Adds an icon to the Windows 95 Tool Tray and<br> has events to respond to mouse clicks.<br><br> This component is based on the TToolIcon VCL that was written by<br> Derek Stutsman (dereks@metronet.com). He based his component on<br> TWinControl, so it showed up as a clear, blank, resizable window at<br> design time and also had more properties than the component actually<br> needed. This made it really hard to find on a busy form sometimes.<br><br> I changed it so it would be based on TComponent so that it was readily<br> visible at design time and also did not cover anything at run-time.<br> The additional Top, left, width, etc. properties are also no longer<br> necessary. I added a ShowDesigning property so that you could test<br> it at design time, but then turn it off so that TWO icons weren't shown<br> on the tool tray when developing and testing.<br><br> One strange anomaly that I worked around but don't know why it happens -<br> if a ToolTip is not specified, then at run-time the icon shows up as<br> blank. If a ToolTip is specified, everything works fine. To fix this,<br> I set up another windows message that set the tool tip if it was blank -<br> this ensures proper operation at all times, but I don't know why this<br> is necessary. If you can figure it out, send me some mail and let me<br> know! (4/17/96 note - still no solution for this!)<br><br> This is freeware (as was the original). If you make cool changes to it,<br> please send them to me.<br><br> Enjoy!<br><br> Pete Ness<br> Compuserve ID: 102347,710<br> Internet: 102347.710@compuserve.com<br> http://ourworld.compuserve.com/homepages/peteness<br><br> Release history:<br><br> 3/8/96 - Version 1.0<br> Release by Derek Stutsman of TToolIcon version 1.0<br><br> 3/12/96 - Version 1.1<br><br> Changed as outlined above by me (Pete Ness) and renamed to TTrayIcon.<br><br> 3/29/96 - Version 1.2<br> Add default window handling to allow closing when Win95 shutdown.<br> Previously, you had to manually close your application before closing<br> Windows 95.<br><br> 4/17/96 - Version 1.3<br> Added a PopupMenu property to automatically handle right clicking on<br> the tray icon.<br> Fixed bug that would not allow you to instantiate a TTrayIcon instance<br> at run-time.<br> Added an example program to show how to do some of the things I've<br> gotten the most questions on.<br> This version is available from my super lame web page - see above for<br> the address.<br><br> }<br><br><br><br>unit TrayIcon;<br><br>interface<br><br>uses<br> SysUtils, Windows, Messages, Classes, Graphics, Controls, ShellAPI, Forms, menus;<br><br>const WM_TOOLTRAYICON = WM_USER+1;<br> WM_RESETTOOLTIP = WM_USER+2;<br><br>type<br><br> TTrayIcon = class(TComponent)<br><br> private<br><br> { Field Variables }<br><br> IconData: TNOTIFYICONDATA;<br> fIcon : TIcon;<br> fToolTip : String;<br> fWindowHandle : HWND;<br> fActive : boolean;<br> fShowDesigning : Boolean;<br><br> { Events }<br><br> fOnClick : TNotifyEvent;<br> fOnDblClick : TNotifyEvent;<br> fOnRightClick : TMouseEvent;<br> fPopupMenu : TPopupMenu;<br><br> function AddIcon : boolean;<br> function ModifyIcon : boolean;<br> function DeleteIcon : boolean;<br><br> procedure SetActive(Value : boolean);<br> procedure SetShowDesigning(Value : boolean);<br> procedure SetIcon(Value : TIcon);<br> procedure SetToolTip(Value : String);<br> procedure WndProc(var msg : TMessage);<br><br> procedure FillDataStructure;<br> procedure DoRightClick( Sender : TObject ); <br><br> protected<br><br> public<br><br> constructor create(aOwner : TComponent); override;<br> destructor destroy; override;<br><br> published<br><br> property Active : boolean read fActive write SetActive;<br> property ShowDesigning : boolean read fShowDesigning write SetShowDesigning;<br> property Icon : TIcon read fIcon write SetIcon;<br> property ToolTip : string read fTooltip write SetToolTip;<br><br> property OnClick : TNotifyEvent read FOnClick write FOnClick;<br> property OnDblClick : TNotifyEvent read FOnDblClick write FOnDblClick;<br> property OnRightClick : TMouseEvent read FOnRightClick write FonRightClick;<br> property PopupMenu : TPopupMenu read fPopupMenu write fPopupMenu;<br><br> end;<br><br>procedure Register;<br><br>implementation<br><br>{$R TrayIcon.res}<br><br>procedure TTrayIcon.SetActive(Value : boolean);<br>begin<br> if value <> fActive then begin<br> fActive := Value;<br> if not (csdesigning in ComponentState) then begin<br> if Value then begin<br> AddIcon;<br> end else begin<br> DeleteIcon;<br> end;<br> end;<br> end;<br>end;<br><br>procedure TTrayIcon.SetShowDesigning(Value : boolean);<br>begin<br> if csdesigning in ComponentState then begin<br> if value <> fShowDesigning then begin<br> fShowDesigning := Value;<br> if Value then begin<br> AddIcon;<br> end else begin<br> DeleteIcon;<br> end;<br> end;<br> end;<br>end;<br><br>procedure TTrayIcon.SetIcon(Value : Ticon);<br>begin<br> if Value <> fIcon then<br> begin<br> fIcon.Assign(value);<br> ModifyIcon;<br> end;<br>end;<br><br>procedure TTrayIcon.SetToolTip(Value : string);<br>begin<br><br> // This routine ALWAYS re-sets the field value and re-loads the<br> // icon. This is so the ToolTip can be set blank when the component<br> // is first loaded. If this is changed, the icon will be blank on<br> // the tray when no ToolTip is specified.<br><br> if length( Value ) > 62 then<br> Value := copy(Value,1,62);<br> fToolTip := value;<br> ModifyIcon;<br><br>end;<br><br>constructor TTrayIcon.create(aOwner : Tcomponent);<br>begin<br> inherited create(aOwner);<br> FWindowHandle := AllocateHWnd( WndProc );<br> FIcon := TIcon.Create;<br>end;<br><br>destructor TTrayIcon.destroy;<br>begin<br><br> if (not (csDesigning in ComponentState) and fActive)<br> or ((csDesigning in ComponentState) and fShowDesigning) then<br> DeleteIcon;<br><br> FIcon.Free;<br> DeAllocateHWnd( FWindowHandle );<br> inherited destroy;<br><br>end;<br><br>procedure TTrayIcon.FillDataStructure;<br>begin<br><br> with IconData do begin<br><br> cbSize := sizeof(TNOTIFYICONDATA);<br> wnd := FWindowHandle;<br> uID := 0; // is not passed in with message so make it 0<br> uFlags := NIF_MESSAGE + NIF_ICON + NIF_TIP;<br> hIcon := fIcon.Handle;<br> StrPCopy(szTip,fToolTip);<br> uCallbackMessage := WM_TOOLTRAYICON;<br><br> end;<br><br>end;<br><br>function TTrayIcon.AddIcon : boolean;<br>begin<br> FillDataStructure;<br> result := Shell_NotifyIcon(NIM_ADD,@IconData);<br><br> // For some reason, if there is no tool tip set up, then the icon<br> // doesn't display. This fixes that.<br><br> if fToolTip = '' then<br> PostMessage( fWindowHandle, WM_RESETTOOLTIP,0,0 );<br><br>end;<br><br>function TTrayIcon.ModifyIcon : boolean;<br>begin<br><br> FillDataStructure;<br> if fActive then<br> result := Shell_NotifyIcon(NIM_MODIFY,@IconData)<br> else<br> result := True;<br><br>end;<br><br>procedure TTrayIcon.DoRightClick( Sender : TObject );<br>var MouseCo: Tpoint;<br>begin<br><br> GetCursorPos(MouseCo);<br><br> if assigned( fPopupMenu ) then begin<br> SetForegroundWindow( Application.Handle );<br> Application.ProcessMessages; <br> fPopupmenu.Popup( Mouseco.X, Mouseco.Y );<br> end;<br><br> if assigned( FOnRightClick ) then<br> begin<br> FOnRightClick(self,mbRight,[],MouseCo.x,MouseCo.y);<br> end;<br>end;<br><br>function TTrayIcon.DeleteIcon : boolean;<br>begin<br> result := Shell_NotifyIcon(NIM_DELETE,@IconData);<br>end;<br><br>procedure TTrayIcon.WndProc(var msg : TMessage);<br>begin<br> with msg do<br> if (msg = WM_RESETTOOLTIP) then<br> SetToolTip( fToolTip )<br> else if (msg = WM_TOOLTRAYICON) then begin<br> case lParam of<br> WM_LBUTTONDBLCLK : if assigned (FOnDblClick) then FOnDblClick(self);<br> WM_LBUTTONUP : if assigned(FOnClick)then FOnClick(self);<br> WM_RBUTTONUP : DoRightClick(self);<br> end;<br> end<br> else // Handle all messages with the default handler<br> Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam);<br><br>end;<br><br>procedure Register;<br>begin<br> RegisterComponents('Win95', [TTrayIcon]);<br>end;<br><br>end.<br>