试试这个控件吧,应该有你想要的功能<br><br><br>unit TrayIcon;<br><br>interface<br><br>uses<br> Windows, Messages, Forms, SysUtils, ImgList, Controls, Menus, ExtCtrls, Dialogs,<br> ScktComp, ComCtrls,StdCtrls, Buttons, Classes, Shellapi, Graphics;//, DesignEditors,<br>// DesignIntf; //, DsgnIntf;<br>{ Windows, Messages, SysUtils, Classes, Graphics, Forms, Menus,<br> shellAPI, StdCtrls, ExtCtrls, Controls, ComCtrls, Buttons;<br> }<br>type<br> ENotifyIconError = class(Exception);<br><br>{ TAboutTrayIcon = class(TPropertyEditor)<br> public<br> procedure Edit; override;<br> function GetAttributes: TPropertyAttributes; override;<br> function GetValue: string; override;<br> end; }<br><br> TTrayIcon = class(TComponent)<br> private<br>// FAbout: TAboutTrayIcon;<br> FDefaultIcon: THandle;<br> FIcon: TIcon;<br> FHideTask: boolean;<br> FHint: string;<br> FIconVisible: boolean;<br> FPopupMenu: TPopupMenu;<br> FOnClick: TNotifyEvent;<br> FOnDblClick: TNotifyEvent;<br> FNoShowClick: boolean;<br> FTimer: TTimer;<br> Tnd: TNotifyIconData;<br> procedure SetIcon(Value: TIcon);<br> procedure SetHideTask(value: boolean);<br> procedure SetHint(Value: string);<br> procedure SetIconVisible(Value: boolean);<br> procedure SetPopupMenu(Value: TPopupMenu);<br> procedure SendTrayMessage(Msg: DWORD; Flags: UINT);<br> function ActiveIconhandle: THandle;<br> procedure OnButtonTimer(Sender: TObject);<br> protected<br> procedure Loaded; override;<br> procedure LoadDefaultIcon; virtual;<br> procedure Notification(AComponent: TComponent;<br> Operation: TOperation); override;<br> public<br> constructor Create(AOwner: TComponent); override;<br> destructor Destroy; override;<br> published<br>// property About: TAboutTrayIcon read FAbout write FAbout;<br> property Icon: TIcon read FIcon write SetIcon;<br> property HideTask: boolean read FHideTask write SethideTask default false;<br> property Hint: string read FHint write SetHint;<br> property IconVisible: boolean read FIconVisible write SetIconVisible<br> default false;<br> property PopupMenu: TPOpupMenu read FPopupMenu write SetPopupMenu;<br> property OnClick: TNotifyEvent read FOnClick write FOnClick;<br> property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick;<br> end;<br><br>procedure Register;<br><br>implementation<br><br>// TIconmanager -----------------------------------------------<br>// This class creates a hiden window which handles and routes<br>// tray icon messages.<br>type<br> TIconManager = class<br> private<br> FHWindow: HWnd;<br> procedure TrayWndProc(var Message: TMessage);<br> public<br> constructor Create;<br> destructor Destroy; override;<br> property HWindow: HWnd read FHWindow write FHWindow;<br> end;<br><br>var<br> IconMgr: TIconManager;<br> DDGM_TRAYICON: Cardinal;<br><br>constructor TIconManager.Create;<br>begin<br> FHWindow:=AllocateHWnd(TrayWndProc);<br>end;<br><br>destructor TIconManager.Destroy;<br>begin<br> if FHWindow <> 0 then DeallocateHWnd(FHWindow);<br> inherited Destroy;<br>end;<br><br>// This allows us to handle all tray callback messages<br>// form within the context of the component<br>procedure TIconManager.TrayWndProc(var Message: TMessage);<br>var<br> pt: TPoint;<br> TheIcon: TTrayIcon;<br>begin<br> with Message do begin<br> // if it's the tray callback message<br> if Msg = DDGM_TRAYICON then begin<br> TheIcon:=TTrayIcon(WParam);<br> case lParam of<br> // Enable timer on first mouse down.<br> // OnClick will be fired by OnTimer method, provided<br> // double Click had not occured<br> WM_LBUTTONDOWN: TheIcon.FTimer.Enabled:=true;<br> // Set no click flag on double click. This will supress<br> // the single click.<br> WM_LBUTTONDBLCLK: begin<br> TheIcon.FNoShowClick:=true;<br> if Assigned(TheIcon.FOnDblClick) then<br> TheIcon.FOnDblClick(self);<br> end;<br> WM_RBUTTONDOWN: begin<br> if Assigned(TheIcon.FPopupMenu) then begin<br> // Call to SetForeGroundWindow is required by API<br> SetForeGroundWindow(IconMgr.HWindow);<br> // Popup local menu at the cursor position<br> GetCursorPos(pt);<br> TheIcon.FPopupMenu.Popup(pt.x, pt.y);<br> // Message post required by API for force task switch<br> PostMessage(IconMgr.HWindow, WM_USER, 0, 0);<br> end;<br> end;<br> end;<br> end<br> else<br> // If isn't a tray callback message, then call DefWindowProc<br> result:=DefWindowProc(FHWindow, Msg, wParam, lParam);<br> end;<br>end;<br><br><br>// TTrayIcon --------------------------------------------------<br>constructor TTrayIcon.Create(AOwner: TComponent);<br>begin<br> inherited Create(AOwner);<br> FIcon:=TIcon.Create;<br> FTimer:=TTimer.Create(self);<br> with FTimer do begin<br> Enabled:=false;<br> Interval:=GetDoubleClickTime;<br> OnTimer:=OnButtonTimer;<br> end;<br> // Keep default windows icon handy...<br> LoadDefaultIcon;<br>end;<br><br>destructor TTrayIcon.Destroy;<br>begin<br> if FIconVisible then SetIconVisible(false); // Destroy icon<br> FIcon.Free;<br> FTimer.Free;<br> inherited Destroy;<br>end;<br><br>// Return handle of active icon<br>function TTrayIcon.ActiveIconhandle: THandle;<br>begin<br> // if no icon is loaded, then return default icon.<br> if FIcon.Handle <> 0 then<br> result:=FIcon.Handle<br> else<br> result:=FDefaultIcon;<br>end;<br><br>// Loads default windows icon to keep it handy.<br>// This will allow the component to use the windows logo icon<br>// as the default when no icon is selected in the icon property.<br>procedure TTrayIcon.LoadDefaultIcon;<br>begin<br> FDefaultIcon:=LoadIcon(0, IDI_WINLOGO);<br>end;<br><br>// Called after component is loaded from stream<br>procedure TTrayIcon.Loaded;<br>begin<br> inherited Loaded;<br> // If icon is supposed to be visible, create it.<br> if FIconVisible then<br> SendTrayMessage(NIM_ADD, NIF_MESSAGE or NIF_ICON or NIF_TIP);<br>end;<br><br>procedure TTrayIcon.Notification(AComponent: TComponent;<br> Operation: TOperation);<br>begin<br> inherited Notification(AComponent, Operation);<br> if (Operation = opRemove) and (AComponent = PopupMenu) then<br> PopupMenu := nil;<br>end;<br><br>// Timer used to keep track of time between two clicks of a<br>// double click. This delays the first click long enough to<br>// ensure that a double click hasn't occured. The whole<br>// point of these gymnastics is to allow the component to<br>// recieve OnClicks and OnDblClicks independently. <br>procedure TTrayIcon.OnButtonTimer(Sender: TObject);<br>begin<br> // disable timer because we only want it to fire once.<br> FTimer.Enabled:=false;<br> // If double click has not occured, then fire single click.<br> if (not FNoShowClick) and Assigned(FOnClick) then<br> FOnClick(self);<br> FNoShowclick:=false; // Reset flag<br>end;<br><br>// This method wraps up the call to the API's Shell_NotifyIcon<br>procedure TTrayIcon.SendTrayMessage(Msg: DWORD; Flags: UINT);<br>begin<br> // Fill up record with appropriate values<br> with Tnd do begin<br> cbSize:=SizeOf(Tnd);<br> StrPLCopy(szTip, PChar(FHint), SizeOf(szTip));<br> uFlags:=Flags;<br> uID:=UINT(self);<br> Wnd:=IconMgr.HWindow;<br> uCallbackMessage:=DDGM_TRAYICON;<br> hIcon:=ActiveIconHandle;<br> end;<br> Shell_NotifyIcon(Msg, @Tnd);<br>end;<br><br>// Write method for HideTask property<br>procedure TTrayIcon.SetHideTask(Value: boolean);<br>const<br> // Flags to show application normal or hide it<br> ShowArray: array [boolean] of integer = (sw_ShowNormal, sw_Hide);<br>begin<br> if FHideTask <> Value then begin<br> FHideTask:=Value;<br> // Don't do anything in design mode<br> if not (csDesigning in ComponentState) then<br> ShowWindow(Application.Handle, ShowArray[FHideTask]);<br> end;<br>end;<br><br>// Set method for Hint property<br>procedure TTrayIcon.SetHint(Value: string);<br>begin<br> if FHint <> Value then begin<br> FHint:=Value;<br> if FIconVisible then // Change hint on iocn on notification tray<br> SendTrayMessage(NIM_MODIFY, NIF_TIP);<br> end;<br>end;<br><br>// Set method for Icon property<br>procedure TTrayIcon.SetIcon(Value: TIcon);<br>begin<br> FIcon.Assign(Value); // Set new icon<br> if FIconVisible then // Change icon on notification tray<br> SendTrayMessage(NIM_MODIFY, NIF_ICON);<br>end;<br><br>// write method fo IconVisible property<br>procedure TTrayIcon.SetIconVisible(Value: boolean);<br>const<br> // Flags to add or delete a tray-notification icon<br> MsgArray: array[boolean] of DWORD = (NIM_DELETE, NIM_ADD);<br>begin<br> if FIconVisible <> Value then begin<br> FIconVisible:=Value;<br> // Set Icon as appropriate<br> SendTrayMessage(MsgArray[Value], NIF_MESSAGE or NIF_ICON or NIF_TIP);<br> end;<br>end;<br><br>// Write method for PopupMenu property<br>procedure TTrayIcon.SetPopupMenu(Value: TPopupMenu);<br>begin<br> FPopupMenu:=Value;<br> if Value <> nil then<br> Value.FreeNotification(self);<br>end;<br><br>// TAboutTrayIcon ---------------------------------------------<br>{<br>procedure TAboutTrayIcon.Edit;<br>begin<br> Application.MessageBox('Tray Notification Component V1.0'+#13#10#13#10+<br> ' This Component is Freeware'+#13#10#13#10+<br> ' By Lee James 2000',<br> 'About TrayIcon...',<br> MB_ICONINFORMATION+MB_OK);<br>end;<br><br>function TAboutTrayIcon.GetAttributes: TPropertyAttributes;<br>begin<br> Result := [paMultiSelect, paDialog, paReadOnly];<br>end;<br><br>function TAboutTrayIcon.GetValue: string;<br>begin<br> Result := '(about)';<br>end;<br>}<br><br>// register component --------------------------------<br>procedure Register;<br>begin<br> RegisterComponents('Samples', [TTrayIcon]);<br>// RegisterPropertyEditor(TypeInfo(TAboutTrayIcon), TTrayIcon,<br>// 'About', TAboutTrayIcon);<br>end;<br><br>const<br> // String to indentify registered window message<br> TrayMsgStr = 'DDG.TrayNotifyIconMsg';<br><br>initialization<br> // Get a unique windows message ID for tray callback<br> DDGM_TRAYICON:=RegisterWindowMessage(TrayMsgStr);<br> IconMgr:=TIconManager.Create;<br><br>finalization<br> IconMgr.Free;<br><br>end.<br>