给个VERY BIG(可以COPY使用的) 的给你,慢慢看吧! 呵呵 :)!(可记得要给分哦![8D])<br>unit CoolTrayIcon;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,<br> Menus, ShellApi, ExtCtrls;<br><br>const<br> { Define user-defined message sent by the trayicon. We avoid low user-defined<br> messages that are used by Windows itself (eg. WM_USER+1 = DM_SETDEFID). }<br> WM_TRAYNOTIFY = WM_USER + 1024;<br> // Constant used for recreating trayicon on system traybar recover<br> IconID = 1;<br> // Constants used for balloon hint feature<br> WM_RESETTOOLTIP = WM_USER + 1025;<br> NIIF_NONE = $00000000;<br> NIIF_INFO = $00000001;<br> NIIF_WARNING = $00000002;<br> NIIF_ERROR = $00000003;<br> NIF_INFO = $00000010;<br><br>var<br> WM_TASKBARCREATED: Cardinal;<br><br>type<br> { You can use the TNotifyIconData record structure defined in shellapi.pas.<br> However, WinME, Win2000, and WinXP have expanded this structure. We define<br> a similar structure, TNotifyIconDataEx. }<br> TNotifyIconDataEx = record<br> cbSize: DWORD;<br> Wnd: HWND;<br> uID: UINT;<br> uFlags: UINT;<br> uCallbackMessage: UINT;<br> hIcon: HICON;<br>// szTip: array[0..63] of AnsiChar;<br> szTip: array[0..127] of AnsiChar; // 0..63 of WideChar in stead?<br> dwState: DWORD;<br> dwStateMask: DWORD;<br> szInfo: array[0..255] of AnsiChar;<br> uTimeout: UINT; // union with uVersion: UINT;<br> szInfoTitle: array[0..63] of AnsiChar;<br> dwInfoFlags: DWORD;<br> end;<br><br> TBalloonHintIcon = (bitNone, bitInfo, bitWarning, bitError);<br> TBalloonHintTimeOut = 10..60; // Windows defines 10-60 secs. as min-max<br><br> TCycleEvent = procedure(Sender: TObject; NextIndex: Integer) of object;<br><br> TCoolTrayIcon = class(TComponent)<br> private<br> FEnabled: Boolean;<br> FIcon: TIcon;<br> FIconVisible: Boolean;<br> FHint: String;<br> FShowHint: Boolean;<br> FPopupMenu: TPopupMenu;<br> FLeftPopup: Boolean;<br> FOnClick,<br> FOnDblClick: TNotifyEvent;<br> FOnCycle: TCycleEvent;<br> FOnMouseDown,<br> FOnMouseUp: TMouseEvent;<br> FOnMouseMove: TMouseMoveEvent;<br> FStartMinimized: Boolean;<br> FMinimizeToTray: Boolean;<br> FClickStart: Boolean;<br> CycleTimer: TTimer; // For icon cycling<br> FIconIndex: Integer; // Current index in imagelist<br> FDesignPreview: Boolean;<br> SettingPreview: Boolean; // Internal status flag<br> SettingMDIForm: Boolean; // Internal status flag<br> FIconList: TImageList;<br> FCycleIcons: Boolean;<br> FCycleInterval: Cardinal;<br> OldAppProc, NewAppProc: Pointer; // Procedure variables<br> OldWndProc, NewWndProc: Pointer; // Procedure variables<br> FWindowHandle: HWND; // Window handle (not general handle)<br> procedure SetCycleIcons(Value: Boolean);<br> procedure SetDesignPreview(Value: Boolean);<br> procedure SetCycleInterval(Value: Cardinal);<br> procedure TimerCycle(Sender: TObject);<br> procedure HandleIconMessage(var Msg: TMessage);<br> function InitIcon: Boolean;<br> procedure SetIcon(Value: TIcon);<br> procedure SetIconVisible(Value: Boolean);<br> procedure SetIconList(Value: TImageList);<br> procedure SetIconIndex(Value: Integer);<br> procedure SetHint(Value: String);<br> procedure SetShowHint(Value: Boolean);<br> procedure PopupAtCursor;<br> procedure HookApp;<br> procedure UnhookApp;<br> procedure HookAppProc(var Msg: TMessage);<br> procedure HookParent;<br> procedure UnhookParent;<br> procedure HookWndProc(var Msg: TMessage);<br> protected<br> IconData: TNotifyIconDataEx; // Data of the tray icon wnd.<br> procedure Loaded; override;<br> function ShowIcon: Boolean; virtual;<br> function HideIcon: Boolean; virtual;<br> function ModifyIcon: Boolean; virtual;<br> procedure Click; dynamic;<br> procedure DblClick; dynamic;<br> procedure CycleIcon; dynamic;<br> procedure MouseDown(Button: TMouseButton; Shift: TShiftState;<br> X, Y: Integer); dynamic;<br> procedure MouseUp(Button: TMouseButton; Shift: TShiftState;<br> X, Y: Integer); dynamic;<br> procedure MouseMove(Shift: TShiftState; X, Y: Integer); dynamic;<br> procedure DoMinimizeToTray; dynamic;<br> procedure Notification(AComponent: TComponent; Operation: TOperation);<br> override;<br> public<br>{$IFDEF DFS_CPPB_3_UP}<br> property Handle: HWND read IconData.hWnd;<br>{$ELSE}<br> property Handle: HWND read IconData.Wnd;<br>{$ENDIF}<br> property WindowHandle: HWND read FWindowHandle;<br> constructor Create(AOwner: TComponent); override;<br> destructor Destroy; override;<br> procedure ShowMainForm;<br> procedure HideMainForm;<br> function Refresh: Boolean;<br> function ShowBalloonHint(Title: String; Text: String; IconType: TBalloonHintIcon;<br> TimeoutSecs: TBalloonHintTimeOut): Boolean;<br> function BitmapToIcon(const Bitmap: TBitmap; const Icon: TIcon;<br> MaskColor: TColor): Boolean;<br> published<br> // Properties:<br> property DesignPreview: Boolean read FDesignPreview<br> write SetDesignPreview default False;<br> property IconList: TImageList read FIconList write SetIconList;<br> property CycleIcons: Boolean read FCycleIcons write SetCycleIcons<br> default False;<br> property CycleInterval: Cardinal read FCycleInterval<br> write SetCycleInterval;<br> property Enabled: Boolean read FEnabled write FEnabled default True;<br> property Hint: String read FHint write SetHint;<br> property ShowHint: Boolean read FShowHint write SetShowHint<br> default True;<br> property Icon: TIcon read FIcon write SetIcon stored True;<br> property IconVisible: Boolean read FIconVisible write SetIconVisible<br> default True;<br> property IconIndex: Integer read FIconIndex write SetIconIndex;<br> property PopupMenu: TPopupMenu read FPopupMenu write FPopupMenu;<br> property LeftPopup: Boolean read FLeftPopup write FLeftPopup<br> default False;<br> property StartMinimized: Boolean read FStartMinimized write FStartMinimized<br> default False; // Main form minimized on app. start-up?<br> property MinimizeToTray: Boolean read FMinimizeToTray write FMinimizeToTray<br> default False; // Minimize main form to tray when minimizing?<br> // Events:<br> property OnClick: TNotifyEvent read FOnClick write FOnClick;<br> property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick;<br> property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;<br> property OnMouseUp: TMouseEvent read FOnMouseUp write FOnMouseUp;<br> property OnMouseMove: TMouseMoveEvent read FOnMouseMove write FOnMouseMove;<br> property OnCycle: TCycleEvent read FOnCycle write FOnCycle;<br> end;<br><br>procedure Register;<br><br>implementation<br><br>{--------------------- TCoolTrayIcon ----------------------}<br><br>constructor TCoolTrayIcon.Create(AOwner: TComponent);<br>begin<br> inherited Create(AOwner);<br> SettingMDIForm := True;<br> FIconVisible := True; // Visible by default<br> FEnabled := True; // Enabled by default<br> FShowHint := True; // Show hint by default<br> SettingPreview := False;<br><br> // Use the TaskbarCreated message available from Win98/IE4+<br> WM_TASKBARCREATED := RegisterWindowMessage('TaskbarCreated');<br><br> FIcon := TIcon.Create;<br> IconData.cbSize := SizeOf(TNotifyIconDataEx);<br> // IconData.wnd points to procedure to receive callback messages from the icon<br> IconData.wnd := AllocateHWnd(HandleIconMessage);<br> // Add an id for the tray icon<br> IconData.uId := IconID;<br> // We want icon, message handling, and tooltips by default<br> IconData.uFlags := NIF_ICON + NIF_MESSAGE + NIF_TIP;<br> // Message to send to IconData.wnd when event occurs<br> IconData.uCallbackMessage := WM_TRAYNOTIFY;<br><br> FWindowHandle := GetWindowLong(IconData.wnd, GWL_HWNDPARENT);<br><br> CycleTimer := TTimer.Create(Self);<br> CycleTimer.Enabled := False;<br> CycleTimer.Interval := FCycleInterval;<br> CycleTimer.OnTimer := TimerCycle;<br><br> // Hook into the app.'s message handling<br> if not (csDesigning in ComponentState) then<br> HookApp;<br><br> // Hook into the main form's message handling<br> if not (csDesigning in ComponentState) then<br> HookParent;<br>end;<br><br><br>destructor TCoolTrayIcon.Destroy;<br>begin<br> SetIconVisible(False); // Remove the icon from the tray<br> FIcon.Free; // Free the icon<br> DeallocateHWnd(IconData.Wnd); // Free the tray window<br> CycleTimer.Free;<br> // It is important to unhook any hooked processes<br> if not (csDesigning in ComponentState) then<br> UnhookApp;<br> if not (csDesigning in ComponentState) then<br> UnhookParent;<br> inherited Destroy;<br>end;<br><br><br>procedure TCoolTrayIcon.Loaded;<br>{ This method is called when all properties of the component have been<br> initialized. The method SetIconVisible must be called here, after the<br> tray icon (FIcon) has loaded itself. Otherwise, the tray icon will<br> be blank (no icon image). }<br>begin<br> inherited Loaded; // Always call inherited Loaded first<br> if (FStartMinimized) and not (csDesigning in ComponentState) then<br> begin<br> Application.ShowMainForm := False;<br> ShowWindow(Application.Handle, SW_HIDE);<br> end;<br> ModifyIcon;<br> SetIconVisible(FIconVisible);<br>end;<br><br><br>procedure TCoolTrayIcon.Notification(AComponent: TComponent;<br> Operation: TOperation);<br>begin<br> inherited Notification(AComponent, Operation);<br> { Check if either the imagelist or the popup menu is about<br> to be deleted }<br> if (AComponent = IconList) and (Operation = opRemove) then<br> begin<br> FIconList := nil;<br> IconList := nil;<br> end;<br> if (AComponent = PopupMenu) and (Operation = opRemove) then<br> begin<br> FPopupMenu := nil;<br> PopupMenu := nil;<br> end;<br>end;<br><br><br>{ For MinimizeToTray to work, we need to know when the form is minimized<br> (happens when either the application or the main form minimizes).<br> The straight-forward way is to make TCoolTrayIcon trap the<br> Application.OnMinimize event. However, if you also make use of this<br> event in the application, the OnMinimize code used by TCoolTrayIcon<br> is discarded.<br> The solution is to hook into the app.'s message handling (via HookApp).<br> You can then catch any message that goes through the app. and still<br> use the OnMinimize event. }<br><br>procedure TCoolTrayIcon.HookApp;<br>begin<br> // Hook the application<br> OldAppProc := Pointer(GetWindowLong(Application.Handle, GWL_WNDPROC));<br> NewAppProc := MakeObjectInstance(HookAppProc);<br> SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(NewAppProc));<br>end;<br><br><br>procedure TCoolTrayIcon.UnhookApp;<br>begin<br> if Assigned(OldAppProc) then<br> SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(OldAppProc));<br> if Assigned(NewAppProc) then<br> FreeObjectInstance(NewAppProc);<br> NewAppProc := nil;<br> OldAppProc := nil;<br>end;<br><br><br>{ All app. messages pass through HookAppProc. You can override the<br> messages by not passing them along to Windows (via CallWindowProc). }<br><br>procedure TCoolTrayIcon.HookAppProc(var Msg: TMessage);<br>begin<br> case Msg.Msg of<br><br> WM_SIZE:<br> // Handle MinimizeToTray by capturing app's minimize events<br> if Msg.wParam = SIZE_MINIMIZED then<br> begin<br> if FMinimizeToTray then<br> DoMinimizeToTray;<br> { You could insert a call to a custom minimize event here, but it<br> would behave exactly like Application.OnMinimize, so I see no<br> need for it. }<br> end;<br><br> WM_WINDOWPOSCHANGED: begin<br> { Handle MDI forms (MDI children cause app. to be redisplayed on<br> taskbar. We hide it again. This may cause a quick flicker (?)). }<br> if SettingMDIForm then<br> if Application.MainForm <> nil then <br> begin<br> if Application.MainForm.FormStyle = fsMDIForm then<br> if FStartMinimized then<br> ShowWindow(Application.Handle, SW_HIDE);<br> SettingMDIForm := False; // So we only do this once<br> end;<br> end;<br><br> end; <br><br> { Show the tray icon if the taskbar has been re-created after an<br> Explorer crash. }<br> if Msg.Msg = WM_TASKBARCREATED then<br> if FIconVisible then<br> ShowIcon;<br><br> // Pass the message on<br> Msg.Result := CallWindowProc(OldAppProc, Application.Handle,<br> Msg.Msg, Msg.wParam, Msg.lParam);<br>end;<br><br><br>{ You can hook into the main form (or any other window) just as easily<br> as hooking into the app., allowing you to handle any message that<br> window processes.<br> This is necessary in order to properly handle when the user minimizes<br> the form using the TASKBAR icon. }<br><br>procedure TCoolTrayIcon.HookParent;<br>begin<br> if (Owner as TWinControl) <> nil then<br> begin<br> // Hook the parent window<br> OldWndProc := Pointer(GetWindowLong((Owner as TWinControl).Handle, GWL_WNDPROC));<br> NewWndProc := MakeObjectInstance(HookWndProc);<br> SetWindowLong((Owner as TWinControl).Handle, GWL_WNDPROC, LongInt(NewWndProc));<br> end;<br>end;<br><br><br>procedure TCoolTrayIcon.UnhookParent;<br>begin<br> if ((Owner as TWinControl) <> nil) and Assigned(OldWndProc) then<br> SetWindowLong((Owner as TWinControl).Handle, GWL_WNDPROC, LongInt(OldWndProc));<br> if Assigned(NewWndProc) then<br> FreeObjectInstance(NewWndProc);<br> NewWndProc := nil;<br> OldWndProc := nil;<br>end;<br><br>{ All main form messages pass through HookWndProc. You can override the<br> messages by not passing them along to Windows (via CallWindowProc).<br> You should be careful with the graphical messages, though. }<br><br>procedure TCoolTrayIcon.HookWndProc(var Msg: TMessage);<br>begin<br> case Msg.Msg of<br><br> WM_SHOWWINDOW: begin<br> if (Msg.lParam = 0) and (Msg.wParam = 1) then<br> begin<br> // Show the taskbar icon (Windows may have shown it already)<br> ShowWindow(Application.Handle, SW_RESTORE);<br> // Bring the taskbar icon and the main form to the foreground<br> SetForegroundWindow(Application.Handle);<br> SetForegroundWindow((Owner as TWinControl).Handle);<br> end;<br> end;<br>{<br> WM_WINDOWPOSCHANGED: begin<br> // Bring any modal forms owned by the main form to the foreground<br> if Assigned(Screen.ActiveControl) then<br> SetFocus(Screen.ActiveControl.Handle);<br> end;<br>}<br> WM_ACTIVATE: begin<br> // Bring any modal forms owned by the main form to the foreground<br> if Assigned(Screen.ActiveControl) then<br> if (Msg.WParamLo = WA_ACTIVE) or (Msg.WParamLo = WA_CLICKACTIVE) then<br> if Assigned(Screen.ActiveControl.Parent) then<br> begin<br> // Control on modal form is active<br> if HWND(Msg.lParam) <> Screen.ActiveControl.Parent.Handle then<br> SetFocus(Screen.ActiveControl.Handle);<br> end<br> else<br> begin<br> // Modal form itself is active<br> if HWND(Msg.lParam) <> Screen.ActiveControl.Handle then<br> SetFocus(Screen.ActiveControl.Handle);<br> end;<br> end;<br><br> end;<br> // Pass the message on<br> Msg.Result := CallWindowProc(OldWndProc, (Owner as TWinControl).Handle,<br> Msg.Msg, Msg.wParam, Msg.lParam);<br>end;<br><br><br>{ HandleIconMessage handles messages that go to the shell notification<br> window (tray icon) itself. Most messages are passed through WM_TRAYNOTIFY.<br> In these cases use lParam to get the actual message, eg. WM_MOUSEMOVE.<br> The method sends the usual Delphi events for the mouse messages. It also<br> interpolates the OnClick event when the user clicks the left button, and<br> makes the menu (if any) popup on left and right mouse down events. }<br><br>procedure TCoolTrayIcon.HandleIconMessage(var Msg: TMessage);<br><br> function ShiftState: TShiftState;<br> // Return the state of the shift, ctrl, and alt keys<br> begin<br> Result := [];<br> if GetAsyncKeyState(VK_SHIFT) < 0 then<br> Include(Result, ssShift);<br> if GetAsyncKeyState(VK_CONTROL) < 0 then<br> Include(Result, ssCtrl);<br> if GetAsyncKeyState(VK_MENU) < 0 then<br> Include(Result, ssAlt);<br> end;<br><br>var<br> Pt: TPoint;<br> Shift: TShiftState;<br> I: Integer;<br> M: TMenuItem;<br>begin<br> if Msg.Msg = WM_TRAYNOTIFY then<br> // Take action if a message from the icon comes through<br> begin<br> case Msg.lParam of<br><br> WM_MOUSEMOVE:<br> if FEnabled then<br> begin<br> Shift := ShiftState;<br> GetCursorPos(Pt);<br> MouseMove(Shift, Pt.X, Pt.Y);<br> end;<br><br> WM_LBUTTONDOWN:<br> if FEnabled then<br> begin<br> Shift := ShiftState + [ssLeft];<br> GetCursorPos(Pt);<br> MouseDown(mbLeft, Shift, Pt.X, Pt.Y);<br> FClickStart := True;<br> if FLeftPopup then<br> PopupAtCursor;<br> end;<br><br> WM_RBUTTONDOWN:<br> if FEnabled then<br> begin<br> Shift := ShiftState + [ssRight];<br> GetCursorPos(Pt);<br> MouseDown(mbRight, Shift, Pt.X, Pt.Y);<br> PopupAtCursor;<br> end;<br><br> WM_MBUTTONDOWN:<br> if FEnabled then<br> begin<br> Shift := ShiftState + [ssMiddle];<br> GetCursorPos(Pt);<br> MouseDown(mbMiddle, Shift, Pt.X, Pt.Y);<br> end;<br><br> WM_LBUTTONUP:<br> if FEnabled then<br> begin<br> Shift := ShiftState + [ssLeft];<br> GetCursorPos(Pt);<br> if FClickStart then // Then WM_LBUTTONDOWN was called before<br> begin<br> FClickStart := False;<br> Click; // We have a click<br> end;<br> MouseUp(mbLeft, Shift, Pt.X, Pt.Y);<br> end;<br><br> WM_RBUTTONUP:<br> if FEnabled then<br> begin<br> Shift := ShiftState + [ssRight];<br> GetCursorPos(Pt);<br> MouseUp(mbRight, Shift, Pt.X, Pt.Y);<br> end;<br><br> WM_MBUTTONUP:<br> if FEnabled then<br> begin<br> Shift := ShiftState + [ssMiddle];<br> GetCursorPos(Pt);<br> MouseUp(mbMiddle, Shift, Pt.X, Pt.Y);<br> end;<br><br> WM_LBUTTONDBLCLK:<br> if FEnabled then<br> begin<br> DblClick;<br> { Handle default menu items. But only if LeftPopup is false,<br> or it will conflict with the popupmenu, when it is called<br> by a click event. }<br> M := nil;<br> if Assigned(FPopupMenu) then<br> if (FPopupMenu.AutoPopup) and (not FLeftPopup) then<br> for I := PopupMenu.Items.Count -1 downto 0 do<br> begin<br> if PopupMenu.Items.Default then<br> M := PopupMenu.Items;<br> end;<br> if M <> nil then<br> M.Click;<br> end;<br> end;<br> end<br><br> else // Messages that didn't go through the icon<br> case Msg.Msg of<br> { Windows sends us a WM_QUERYENDSESSION message when it prepares<br> for shutdown. Msg.Result must not return 0, or the system will<br> be unable to shut down. }<br> WM_QUERYENDSESSION: begin<br>//showmessage('WM_QUERYENDSESSION');<br>// PostQuitMessage(0);<br> Msg.Result := 1;<br> end;<br>{<br> WM_DESTROY: begin<br>showmessage('WM_DESTROY');<br> PostQuitMessage(0);<br> Msg.Result := 0;<br> end;<br>}<br>{<br> WM_ENDSESSION: begin<br>//showmessage('WM_ENDSESSION');<br> Msg.Result := 0;<br> end;<br>}<br> else // Handle all other messages with the default handler<br> Msg.Result := DefWindowProc(IconData.Wnd, Msg.Msg, Msg.wParam, Msg.lParam);<br> end;<br>end;<br><br><br>procedure TCoolTrayIcon.SetIcon(Value: TIcon);<br>begin<br> FIcon.Assign(Value);<br> ModifyIcon;<br>end;<br><br><br>procedure TCoolTrayIcon.SetIconVisible(Value: Boolean);<br>begin<br> if Value then<br> ShowIcon<br> else<br> HideIcon;<br>end;<br><br><br>procedure TCoolTrayIcon.SetDesignPreview(Value: Boolean);<br>begin<br> FDesignPreview := Value;<br> SettingPreview := True; // Raise flag<br> SetIconVisible(Value);<br> SettingPreview := False; // Clear flag<br>end;<br><br><br>procedure TCoolTrayIcon.SetCycleIcons(Value: Boolean);<br>begin<br> FCycleIcons := Value;<br> if Value then<br> SetIconIndex(0);<br> CycleTimer.Enabled := Value;<br>end;<br><br><br>procedure TCoolTrayIcon.SetCycleInterval(Value: Cardinal);<br>begin<br> FCycleInterval := Value;<br> CycleTimer.Interval := FCycleInterval;<br>end;<br><br><br>procedure TCoolTrayIcon.SetIconList(Value: TImageList);<br>begin<br> FIconList := Value;<br>{<br> // Set CycleIcons = false if IconList is nil<br> if Value = nil then<br> SetCycleIcons(False);<br>}<br> SetIconIndex(0);<br>end;<br><br><br>procedure TCoolTrayIcon.SetIconIndex(Value: Integer);<br>begin<br> if FIconList <> nil then<br> begin<br> FIconIndex := Value;<br> if Value >= FIconList.Count then<br> FIconIndex := FIconList.Count -1;<br> FIconList.GetIcon(FIconIndex, FIcon);<br> end<br> else<br> FIconIndex := 0;<br><br> ModifyIcon;<br>end;<br><br><br>procedure TCoolTrayIcon.SetHint(Value: String);<br>begin<br> FHint := Value;<br> ModifyIcon;<br>end;<br><br><br>procedure TCoolTrayIcon.SetShowHint(Value: Boolean);<br>begin<br> FShowHint := Value;<br> ModifyIcon;<br>end;<br><br><br>function TCoolTrayIcon.InitIcon: Boolean;<br>// Set icon and tooltip<br>var<br> ok: Boolean;<br>begin<br> Result := False;<br> ok := True;<br> if (csDesigning in ComponentState) {or<br> (csLoading in ComponentState)} then<br> begin<br> if SettingPreview then<br> ok := True<br> else<br> ok := FDesignPreview<br> end;<br><br> if ok then<br> begin<br> IconData.hIcon := FIcon.Handle;<br> if (FHint <> '') and (FShowHint) then<br> StrLCopy(IconData.szTip, PChar(FHint), SizeOf(IconData.szTip)-1)<br> // StrLCopy must be used since szTip is only 64 bytes<br> else<br> IconData.szTip := '';<br> Result := True;<br> end;<br>end;<br><br><br>function TCoolTrayIcon.ShowIcon: Boolean;<br>// Add/show the icon on the tray<br>begin<br> Result := False;<br> if not SettingPreview then<br> FIconVisible := True;<br> begin<br> if (csDesigning in ComponentState) {or<br> (csLoading in ComponentState)} then<br> begin<br> if SettingPreview then<br> if InitIcon then<br> Result := Shell_NotifyIcon(NIM_ADD, @IconData);<br> end<br> else<br> if InitIcon then<br> Result := Shell_NotifyIcon(NIM_ADD, @IconData);<br> end;<br>end;<br><br><br>function TCoolTrayIcon.HideIcon: Boolean;<br>// Remove/hide the icon from the tray<br>begin<br> Result := False;<br> if not SettingPreview then<br> FIconVisible := False;<br> begin<br> if (csDesigning in ComponentState) {or<br> (csLoading in ComponentState)} then<br> begin<br> if SettingPreview then<br> if InitIcon then<br> Result := Shell_NotifyIcon(NIM_DELETE, @IconData);<br> end<br> else<br> if InitIcon then<br> Result := Shell_NotifyIcon(NIM_DELETE, @IconData);<br> end;<br>end;<br><br><br>function TCoolTrayIcon.ModifyIcon: Boolean;<br>// Change icon or tooltip if icon already placed<br>begin<br> Result := False;<br> if InitIcon then<br> Result := Shell_NotifyIcon(NIM_MODIFY, @IconData);<br>end;<br><br><br>procedure TCoolTrayIcon.TimerCycle(Sender: TObject);<br>begin<br> if Assigned(FIconList) then<br> begin<br> FIconList.GetIcon(FIconIndex, FIcon);<br> CycleIcon; // Call event method<br> ModifyIcon;<br><br> if FIconIndex < FIconList.Count-1 then<br> SetIconIndex(FIconIndex+1)<br> else<br> SetIconIndex(0);<br> end;<br>end;<br><br><br>procedure TCoolTrayIcon.ShowMainForm;<br>begin<br> if Application.MainForm <> nil then<br> begin<br> // Show application's TASKBAR icon (not the traybar icon)<br> ShowWindow(Application.Handle, SW_RESTORE);<br>// ShowWindow(Application.Handle, SW_SHOWNORMAL);<br>// Application.Restore;<br> // Show the form itself<br> Application.MainForm.Visible := True;<br>// ShowWindow((Owner as TWinControl).Handle, SW_RESTORE);<br> end;<br>end;<br><br><br>procedure TCoolTrayIcon.HideMainForm;<br>begin<br> if Application.MainForm <> nil then<br> begin<br> // Hide the form itself (and thus any child windows)<br> Application.MainForm.Visible := False;<br> { Hide application's TASKBAR icon (not the traybar icon).<br> Do this AFTER the mainform is hidden, or any child windows<br> will redisplay the taskbar icon if they are visible. }<br> ShowWindow(Application.Handle, SW_HIDE);<br> end;<br>end;<br><br><br>function TCoolTrayIcon.ShowBalloonHint(Title: String; Text: String;<br> IconType: TBalloonHintIcon; TimeoutSecs: TBalloonHintTimeOut): Boolean;<br>// Show balloon hint. Return false if error.<br>const<br> aBalloonIconTypes: array[TBalloonHintIcon] of Byte =<br> (NIIF_NONE, NIIF_INFO, NIIF_WARNING, NIIF_ERROR);<br>begin<br> if FEnabled then<br> begin<br> // Remove old balloon hint<br> with IconData do<br> begin<br> uFlags := uFlags or NIF_INFO;<br> StrPCopy(szInfo, '');<br> end;<br> ModifyIcon;<br> // Display new balloon hint<br> with IconData do<br> begin<br> uFlags := uFlags or NIF_INFO;<br> StrPCopy(szInfo, Text);<br> StrPCopy(szInfoTitle, Title);<br> uTimeout := TimeoutSecs * 1000;<br> dwInfoFlags := aBalloonIconTypes[IconType];<br> end;<br> Result := ModifyIcon;<br> { Remove NIF_INFO before next call to ModifyIcon (or else the balloon hint<br> will redisplay itself) }<br> with IconData do<br> uFlags := NIF_ICON + NIF_MESSAGE + NIF_TIP;<br> end<br> else<br> Result := True;<br>end;<br><br><br>function TCoolTrayIcon.BitmapToIcon(const Bitmap: TBitmap;<br> const Icon: TIcon; MaskColor: TColor): Boolean;<br>{ Render an icon from a 16x16 bitmap. Return false if error.<br> MaskColor is a color that will be rendered transparently. Use clNone for<br> no transparency. }<br>var<br> BitmapImageList: TImageList;<br>begin<br> BitmapImageList := TImageList.CreateSize(16, 16);<br> try<br> Result := False;<br> BitmapImageList.AddMasked(Bitmap, MaskColor);<br> BitmapImageList.GetIcon(0, Icon);<br> Result := True;<br> finally<br> BitmapImageList.Free;<br> end;<br>end;<br><br><br>function TCoolTrayIcon.Refresh: Boolean;<br>// Refresh the icon<br>begin<br> Result := ModifyIcon;<br>end;<br><br><br>procedure TCoolTrayIcon.PopupAtCursor;<br>var<br> CursorPos: TPoint;<br>begin<br> if Assigned(PopupMenu) then<br> if PopupMenu.AutoPopup then<br> if GetCursorPos(CursorPos) then<br> begin<br> { Win98 (but not Win95/WinNT) seems to empty a popup menu before<br> closing it. This is a problem when the menu is about to display<br> while it already is active (two click-events in succession). The<br> menu will flicker annoyingly. Calling ProcessMessages fixes this. }<br> Application.ProcessMessages;<br><br> { Bring the main form or its modal dialog to the foreground.<br> This also ensures the popup menu closes after it loses focus. }<br> SetForegroundWindow((Owner as TWinControl).Handle);<br>{<br>This seems unnecessary(?):<br> if Screen.ActiveControl <> nil then<br> if (Screen.ActiveControl.Owner is TWinControl) then<br> SetForegroundWindow((Screen.ActiveControl.Owner as TWinControl).Handle);<br>}<br> // Now make the menu pop up<br> PopupMenu.PopupComponent := Self;<br> PopupMenu.Popup(CursorPos.X, CursorPos.Y);<br> // Post an empty message to make the popup menu disappear<br> PostMessage((Owner as TWinControl).Handle, WM_NULL, 0, 0);<br> end;<br>end;<br><br><br>procedure TCoolTrayIcon.Click;<br>begin<br> // Execute user-assigned method<br> if Assigned(FOnClick) then<br> FOnClick(Self);<br>end;<br><br><br>procedure TCoolTrayIcon.DblClick;<br>begin<br> // Execute user-assigned method<br> if Assigned(FOnDblClick) then<br> FOnDblClick(Self);<br>end;<br><br><br>procedure TCoolTrayIcon.MouseDown(Button: TMouseButton; Shift: TShiftState;<br> X, Y: Integer);<br>begin<br> // Execute user-assigned method<br> if Assigned(FOnMouseDown) then<br> FOnMouseDown(Self, Button, Shift, X, Y);<br>end;<br><br><br>procedure TCoolTrayIcon.MouseUp(Button: TMouseButton; Shift: TShiftState;<br> X, Y: Integer);<br>begin<br> // Execute user-assigned method<br> if Assigned(FOnMouseUp) then<br> FOnMouseUp(Self, Button, Shift, X, Y);<br>end;<br><br><br>procedure TCoolTrayIcon.MouseMove(Shift: TShiftState; X, Y: Integer);<br>begin<br> // Execute user-assigned method<br> if Assigned(FOnMouseMove) then<br> FOnMouseMove(Self, Shift, X, Y);<br>end;<br><br><br>procedure TCoolTrayIcon.CycleIcon;<br>var<br> NextIconIndex: Integer;<br>begin<br> // Execute user-assigned method<br> NextIconIndex := 0;<br> if FIconList <> nil then<br> if FIconIndex < FIconList.Count then<br> NextIconIndex := FIconIndex +1;<br><br> if Assigned(FOnCycle) then<br> FOnCycle(Self, NextIconIndex);<br>end;<br><br><br>procedure TCoolTrayIcon.DoMinimizeToTray;<br>begin<br> // Override this method to change automatic tray minimizing behavior<br> HideMainForm;<br> IconVisible := True;<br>end;<br><br><br>procedure Register;<br>begin<br> RegisterComponents('Custom', [TCoolTrayIcon]);<br>end;<br><br>end.<br>