spTrayIcon.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:21k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {*******************************************************************}
  2. {                                                                   }
  3. {       Almediadev Visual Component Library                         }
  4. {       DynamicSkinForm                                             }
  5. {       Version 4.98                                                }
  6. {                                                                   }
  7. {       Copyright (c) 2000-2002 Almediadev                          }
  8. {       ALL RIGHTS RESERVED                                         }
  9. {                                                                   }
  10. {       Home:  http://www.almdev.com                                }
  11. {       Support: support@almdev.com                                 }
  12. {                                                                   }
  13. {*******************************************************************}
  14. unit spTrayIcon;
  15. {$P+,S-,W-,R-}
  16. {$WARNINGS OFF}
  17. {$HINTS OFF}
  18. interface
  19. uses
  20.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  21.   Menus, ShellApi, ExtCtrls, SkinMenus;
  22. const
  23.   WM_TRAYNOTIFY = WM_USER + 1024;
  24.   IconID = 1;
  25. var
  26.   WM_TASKBARCREATED: Cardinal;
  27. type
  28.   TNotifyIconDataEx = record
  29.     cbSize: DWORD;
  30.     Wnd: HWND;
  31.     uID: UINT;
  32.     uFlags: UINT;
  33.     uCallbackMessage: UINT;
  34.     hIcon: HICON;
  35.     szTip: array[0..127] of AnsiChar;   
  36.     dwState: DWORD;
  37.     dwStateMask: DWORD;
  38.     szInfo: array[0..255] of AnsiChar;
  39.     uTimeout: UINT; 
  40.     szInfoTitle: array[0..63] of AnsiChar;
  41.     dwInfoFlags: DWORD;
  42.   end;
  43.   TCycleEvent = procedure(Sender: TObject; NextIndex: Integer) of object;
  44.   TspTrayIcon = class(TComponent)
  45.   private
  46.     FEnabled: Boolean;
  47.     FIcon: TIcon;
  48.     FIconVisible: Boolean;
  49.     FHint: String;
  50.     FShowHint: Boolean;
  51.     FPopupMenu: TspSkinPopupMenu;
  52.     FPopupByLeftButton: Boolean;
  53.     FOnClick,
  54.     FOnDblClick: TNotifyEvent;
  55.     FOnCycle: TCycleEvent;
  56.     FOnMouseDown,
  57.     FOnMouseUp: TMouseEvent;
  58.     FOnMouseMove: TMouseMoveEvent;
  59.     FMinimizedOnStart: Boolean;
  60.     FMinimizeToTray: Boolean;
  61.     FClickStart: Boolean;
  62.     FClickReady: Boolean;
  63.     AnimateTimer: TTimer;
  64.     ClickTimer: TTimer;
  65.     IsDblClick: Boolean;
  66.     FIconIndex: Integer;
  67.     FDesignPreview: Boolean;
  68.     SettingPreview: Boolean;
  69.     SettingMDIForm: Boolean;           
  70.     FIconList: TImageList;
  71.     FCycleIcons: Boolean;
  72.     FAnimateTimerInterval: Cardinal;
  73.     OldAppProc, NewAppProc: Pointer;
  74.     OldWndProc, NewWndProc: Pointer;
  75.     FWindowHandle: HWND;               
  76.     procedure SetDesignPreview(Value: Boolean);
  77.     procedure SetCycleIcons(Value: Boolean);
  78.     procedure SetAnimateTimerInterval(Value: Cardinal);
  79.     procedure TimerCycle(Sender: TObject);
  80.     procedure TimerClick(Sender: TObject);
  81.     procedure HandleIconMessage(var Msg: TMessage);
  82.     function InitIcon: Boolean;
  83.     procedure SetIcon(Value: TIcon);
  84.     procedure SetIconVisible(Value: Boolean);
  85.     procedure SetIconList(Value: TImageList);
  86.     procedure SetIconIndex(Value: Integer);
  87.     procedure SetHint(Value: String);
  88.     procedure SetShowHint(Value: Boolean);
  89.     procedure PopupAtCursor;
  90.     // Hook methods
  91.     procedure HookApp;
  92.     procedure UnhookApp;
  93.     procedure HookAppProc(var Msg: TMessage);
  94.     procedure HookForm;
  95.     procedure UnhookForm;
  96.     procedure HookFormProc(var Msg: TMessage);
  97.   protected
  98.     IconData: TNotifyIconDataEx;       
  99.     procedure Loaded; override;
  100.     function LoadDefaultIcon: Boolean; virtual;
  101.     function ShowIcon: Boolean; virtual;
  102.     function HideIcon: Boolean; virtual;
  103.     function ModifyIcon: Boolean; virtual;
  104.     procedure Click; dynamic;
  105.     procedure DblClick; dynamic;
  106.     procedure CycleIcon; dynamic;
  107.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  108.       X, Y: Integer); dynamic;
  109.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
  110.       X, Y: Integer); dynamic;
  111.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); dynamic;
  112.     procedure DoMinimizeToTray; dynamic;
  113.     procedure Notification(AComponent: TComponent; Operation: TOperation);
  114.       override;
  115.   public
  116.     property Handle: HWND read IconData.Wnd;
  117.     property WindowHandle: HWND read FWindowHandle;
  118.     constructor Create(AOwner: TComponent); override;
  119.     destructor Destroy; override;
  120.     function Refresh: Boolean;
  121.     function BitmapToIcon(const Bitmap: TBitmap; const Icon: TIcon;
  122.       MaskColor: TColor): Boolean;
  123.     procedure ShowMainForm;
  124.     procedure HideMainForm;
  125.   published
  126.     property DesignPreview: Boolean read FDesignPreview
  127.       write SetDesignPreview default False;
  128.     property IconList: TImageList read FIconList write SetIconList;
  129.     property CycleIcons: Boolean read FCycleIcons write SetCycleIcons
  130.       default False;
  131.     property AnimateTimerInterval: Cardinal read FAnimateTimerInterval
  132.       write SetAnimateTimerInterval;
  133.     property Enabled: Boolean read FEnabled write FEnabled default True;
  134.     property Hint: String read FHint write SetHint;
  135.     property ShowHint: Boolean read FShowHint write SetShowHint
  136.       default True;
  137.     property Icon: TIcon read FIcon write SetIcon stored True;
  138.     property IconVisible: Boolean read FIconVisible write SetIconVisible
  139.       default True;
  140.     property IconIndex: Integer read FIconIndex write SetIconIndex;
  141.     property PopupMenu: TspSkinPopupMenu read FPopupMenu write FPopupMenu;
  142.     property PopupByLeftButton: Boolean read FPopupByLeftButton write FPopupByLeftButton
  143.       default False;
  144.     property MinimizedOnStart: Boolean read FMinimizedOnStart write FMinimizedOnStart
  145.       default False;
  146.     property MinimizeToTray: Boolean read FMinimizeToTray write FMinimizeToTray
  147.       default False;         
  148.     property OnClick: TNotifyEvent read FOnClick write FOnClick;
  149.     property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick;
  150.     property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;
  151.     property OnMouseUp: TMouseEvent read FOnMouseUp write FOnMouseUp;
  152.     property OnMouseMove: TMouseMoveEvent read FOnMouseMove write FOnMouseMove;
  153.     property OnCycle: TCycleEvent read FOnCycle write FOnCycle;
  154.   end;
  155. implementation
  156. constructor TspTrayIcon.Create(AOwner: TComponent);
  157. begin
  158.   inherited Create(AOwner);
  159.   SettingMDIForm := True;
  160.   FIconVisible := False;
  161.   FEnabled := True;
  162.   FShowHint := True;         
  163.   SettingPreview := False;
  164.   WM_TASKBARCREATED := RegisterWindowMessage('TaskbarCreated');
  165.   FIcon := TIcon.Create;
  166.   IconData.cbSize := SizeOf(TNotifyIconDataEx);
  167.   IconData.wnd := AllocateHWnd(HandleIconMessage);
  168.   IconData.uId := IconID;
  169.   IconData.uFlags := NIF_ICON + NIF_MESSAGE + NIF_TIP;
  170.   IconData.uCallbackMessage := WM_TRAYNOTIFY;
  171.   FWindowHandle := GetWindowLong(IconData.wnd, GWL_HWNDPARENT);
  172.   AnimateTimer := TTimer.Create(Self);
  173.   AnimateTimer.Enabled := False;
  174.   AnimateTimer.Interval := FAnimateTimerInterval;
  175.   AnimateTimer.OnTimer := TimerCycle;
  176.   ClickTimer := TTimer.Create(Self);
  177.   ClickTimer.Enabled := False;
  178.   ClickTimer.Interval := GetDoubleClickTime;
  179.   ClickTimer.OnTimer := TimerClick;
  180.   if not (csDesigning in ComponentState)
  181.   then
  182.     begin
  183.       if FIcon.Handle = 0
  184.       then
  185.         if LoadDefaultIcon
  186.         then
  187.           FIcon.Handle := Application.Icon.Handle;
  188.       HookApp;
  189.       if Owner is TWinControl then HookForm;
  190.     end;
  191. end;
  192. destructor TspTrayIcon.Destroy;
  193. begin
  194.   SetIconVisible(False);
  195.   SetDesignPreview(False);
  196.   FIcon.Free;
  197.   DeallocateHWnd(IconData.Wnd);
  198.   AnimateTimer.Free;
  199.   ClickTimer.Free;
  200.   if not (csDesigning in ComponentState)
  201.   then
  202.     begin
  203.       UnhookApp;
  204.       if Owner is TWinControl then UnhookForm;
  205.     end;
  206.   inherited Destroy;
  207. end;
  208. procedure TspTrayIcon.Loaded;
  209. begin
  210.   inherited Loaded;
  211.   if Owner is TWinControl
  212.   then
  213.     if (FMinimizedOnStart) and not (csDesigning in ComponentState)
  214.     then
  215.       begin
  216.         Application.ShowMainForm := False;
  217.         ShowWindow(Application.Handle, SW_HIDE);
  218.       end;
  219.   ModifyIcon;
  220.   SetIconVisible(FIconVisible);
  221. end;
  222. function TspTrayIcon.LoadDefaultIcon: Boolean;
  223. begin
  224.   Result := True;
  225. end;
  226. procedure TspTrayIcon.Notification(AComponent: TComponent;
  227.   Operation: TOperation);
  228. begin
  229.   inherited Notification(AComponent, Operation);
  230.   if (AComponent = FIconList) and (Operation = opRemove)
  231.   then
  232.     begin
  233.       FIconList := nil;
  234.     end;
  235.   if (AComponent = FPopupMenu) and (Operation = opRemove)
  236.   then
  237.     begin
  238.       FPopupMenu := nil;
  239.     end;
  240. end;
  241. procedure TspTrayIcon.HookApp;
  242. begin
  243.   OldAppProc := Pointer(GetWindowLong(Application.Handle, GWL_WNDPROC));
  244.   NewAppProc := MakeObjectInstance(HookAppProc);
  245.   SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(NewAppProc));
  246. end;
  247. procedure TspTrayIcon.UnhookApp;
  248. begin
  249.   if Assigned(OldAppProc)
  250.   then
  251.     SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(OldAppProc));
  252.   if Assigned(NewAppProc)
  253.   then
  254.     FreeObjectInstance(NewAppProc);
  255.   NewAppProc := nil;
  256.   OldAppProc := nil;
  257. end;
  258. procedure TspTrayIcon.HookAppProc(var Msg: TMessage);
  259. begin
  260.   case Msg.Msg of
  261.     WM_SIZE:
  262.       if Msg.wParam = SIZE_MINIMIZED
  263.       then
  264.         begin
  265.           if FMinimizeToTray then DoMinimizeToTray;
  266.         end;
  267.     WM_WINDOWPOSCHANGED:
  268.       begin
  269.         if SettingMDIForm
  270.         then
  271.           if Application.MainForm <> nil
  272.           then
  273.             begin
  274.               if (Application.MainForm.FormStyle = fsMDIForm) then
  275.               if FMinimizedOnStart then
  276.               ShowWindow(Application.Handle, SW_HIDE);
  277.               SettingMDIForm := False;
  278.             end;
  279.       end;
  280.   end;
  281.   if (Msg.Msg = WM_TASKBARCREATED) and FIconVisible then ShowIcon;
  282.   Msg.Result := CallWindowProc(OldAppProc, Application.Handle,
  283.                                Msg.Msg, Msg.wParam, Msg.lParam);
  284. end;
  285. procedure TspTrayIcon.HookForm;
  286. begin
  287.   if (Owner as TWinControl) <> nil
  288.   then
  289.     begin
  290.       OldWndProc := Pointer(GetWindowLong((Owner as TWinControl).Handle, GWL_WNDPROC));
  291.       NewWndProc := MakeObjectInstance(HookFormProc);
  292.       SetWindowLong((Owner as TWinControl).Handle, GWL_WNDPROC, LongInt(NewWndProc));
  293.     end;
  294. end;
  295. procedure TspTrayIcon.UnhookForm;
  296. begin
  297.   if ((Owner as TWinControl) <> nil) and (Assigned(OldWndProc))
  298.   then
  299.     SetWindowLong((Owner as TWinControl).Handle, GWL_WNDPROC, LongInt(OldWndProc));
  300.   if Assigned(NewWndProc)
  301.   then
  302.     FreeObjectInstance(NewWndProc);
  303.   NewWndProc := nil;
  304.   OldWndProc := nil;
  305. end;
  306. procedure TspTrayIcon.HookFormProc(var Msg: TMessage);
  307. begin
  308.   case Msg.Msg of
  309.     WM_SHOWWINDOW:
  310.      begin
  311.        if (Msg.lParam = 0) and (Msg.wParam = 1)
  312.        then
  313.          begin
  314.            ShowWindow(Application.Handle, SW_RESTORE);
  315.            SetForegroundWindow(Application.Handle);
  316.            SetForegroundWindow((Owner as TWinControl).Handle);
  317.          end;
  318.      end;
  319.     WM_ACTIVATE: begin
  320.        if Assigned(Screen.ActiveControl)
  321.        then
  322.         if (Msg.WParamLo = WA_ACTIVE) or (Msg.WParamLo = WA_CLICKACTIVE)
  323.         then
  324.           if Assigned(Screen.ActiveControl.Parent)
  325.           then
  326.             begin
  327.               if HWND(Msg.lParam) <> Screen.ActiveControl.Parent.Handle
  328.               then SetFocus(Screen.ActiveControl.Handle);
  329.             end
  330.         else
  331.           begin
  332.             if HWND(Msg.lParam) <> Screen.ActiveControl.Handle
  333.             then SetFocus(Screen.ActiveControl.Handle);
  334.           end;
  335.     end;
  336.   end;
  337.   Msg.Result := CallWindowProc(OldWndProc, (Owner as TWinControl).Handle,
  338.                 Msg.Msg, Msg.wParam, Msg.lParam);
  339. end;
  340. procedure TspTrayIcon.HandleIconMessage(var Msg: TMessage);
  341.   function ShiftState: TShiftState;
  342.   begin
  343.     Result := [];
  344.     if GetAsyncKeyState(VK_SHIFT) < 0
  345.     then Include(Result, ssShift);
  346.     if GetAsyncKeyState(VK_CONTROL) < 0
  347.     then Include(Result, ssCtrl);
  348.     if GetAsyncKeyState(VK_MENU) < 0
  349.     then Include(Result, ssAlt);
  350.   end;
  351. var
  352.   Pt: TPoint;
  353.   Shift: TShiftState;
  354.   I: Integer;
  355.   M: TMenuItem;
  356. begin
  357.   if Msg.Msg = WM_TRAYNOTIFY
  358.   then
  359.     begin
  360.       if FEnabled then
  361.         case Msg.lParam of
  362.            WM_MOUSEMOVE:
  363.              begin
  364.                Shift := ShiftState;
  365.                GetCursorPos(Pt);
  366.                MouseMove(Shift, Pt.X, Pt.Y);
  367.              end;
  368.            WM_LBUTTONDOWN:
  369.              begin
  370.                ClickTimer.Enabled := True;
  371.                Shift := ShiftState + [ssLeft];
  372.                GetCursorPos(Pt);
  373.                MouseDown(mbLeft, Shift, Pt.X, Pt.Y);
  374.                FClickStart := True;
  375.               if FPopupByLeftButton then PopupAtCursor;
  376.             end;
  377.            WM_RBUTTONDOWN:
  378.              begin
  379.                Shift := ShiftState + [ssRight];
  380.                GetCursorPos(Pt);
  381.                MouseDown(mbRight, Shift, Pt.X, Pt.Y);
  382.                PopupAtCursor;
  383.              end;
  384.            WM_MBUTTONDOWN:
  385.              begin
  386.                Shift := ShiftState + [ssMiddle];
  387.                GetCursorPos(Pt);
  388.                MouseDown(mbMiddle, Shift, Pt.X, Pt.Y);
  389.              end;
  390.            WM_LBUTTONUP:
  391.              begin
  392.                Shift := ShiftState + [ssLeft];
  393.                GetCursorPos(Pt);
  394.                if FClickStart then FClickReady := True;
  395.                if FClickStart and (not ClickTimer.Enabled)
  396.                then
  397.                  begin
  398.                    FClickStart := False;
  399.                    FClickReady := False;
  400.                     Click;
  401.                  end;
  402.                FClickStart := False;
  403.                MouseUp(mbLeft, Shift, Pt.X, Pt.Y);
  404.              end;
  405.            WM_RBUTTONUP:
  406.              begin
  407.                Shift := ShiftState + [ssRight];
  408.                GetCursorPos(Pt);
  409.                MouseUp(mbRight, Shift, Pt.X, Pt.Y);
  410.              end;
  411.            WM_MBUTTONUP:
  412.              begin
  413.                Shift := ShiftState + [ssMiddle];
  414.                GetCursorPos(Pt);
  415.                MouseUp(mbMiddle, Shift, Pt.X, Pt.Y);
  416.              end;
  417.            WM_LBUTTONDBLCLK:
  418.              begin
  419.                FClickReady := False;
  420.                IsDblClick := True;
  421.                DblClick;
  422.                M := nil;
  423.                if Assigned(FPopupMenu)
  424.                then
  425.                  if (FPopupMenu.AutoPopup) and (not FPopupByLeftButton)
  426.                  then
  427.                    for I := PopupMenu.Items.Count -1 downto 0 do
  428.                      if PopupMenu.Items[I].Default then M := PopupMenu.Items[I];
  429.                if M <> nil then M.Click;
  430.              end;
  431.         end;
  432.     end
  433.   else
  434.     case Msg.Msg of
  435.       WM_QUERYENDSESSION, WM_CLOSE, WM_QUIT,
  436.       WM_DESTROY, WM_NCDESTROY, WM_USERCHANGED:  Msg.Result := 1;
  437.     else
  438.       Msg.Result := DefWindowProc(IconData.Wnd, Msg.Msg, Msg.wParam, Msg.lParam);
  439.     end;
  440. end;
  441. procedure TspTrayIcon.SetIcon(Value: TIcon);
  442. begin
  443.   FIcon.Assign(Value);
  444.   ModifyIcon;
  445. end;
  446. procedure TspTrayIcon.SetIconVisible(Value: Boolean);
  447. begin
  448.   if Value then ShowIcon else HideIcon;
  449. end;
  450. procedure TspTrayIcon.SetDesignPreview(Value: Boolean);
  451. begin
  452.   FDesignPreview := Value;
  453.   SettingPreview := True;
  454.   SetIconVisible(Value);
  455.   SettingPreview := False;
  456. end;
  457. procedure TspTrayIcon.SetCycleIcons(Value: Boolean);
  458. begin
  459.   FCycleIcons := Value;
  460.   if Value then SetIconIndex(0);
  461.   AnimateTimer.Enabled := Value;
  462. end;
  463. procedure TspTrayIcon.SetAnimateTimerInterval(Value: Cardinal);
  464. begin
  465.   FAnimateTimerInterval := Value;
  466.   AnimateTimer.Interval := FAnimateTimerInterval;
  467. end;
  468. procedure TspTrayIcon.SetIconList(Value: TImageList);
  469. begin
  470.   FIconList := Value;
  471.   SetIconIndex(0);
  472. end;
  473. procedure TspTrayIcon.SetIconIndex(Value: Integer);
  474. begin
  475.   if FIconList <> nil
  476.   then
  477.     begin
  478.       FIconIndex := Value;
  479.       if Value >= FIconList.Count then FIconIndex := FIconList.Count - 1;
  480.       FIconList.GetIcon(FIconIndex, FIcon);
  481.     end
  482.   else
  483.     FIconIndex := 0;
  484.   ModifyIcon;
  485. end;
  486. procedure TspTrayIcon.SetHint(Value: String);
  487. begin
  488.   FHint := Value;
  489.   ModifyIcon;
  490. end;
  491. procedure TspTrayIcon.SetShowHint(Value: Boolean);
  492. begin
  493.   FShowHint := Value;
  494.   ModifyIcon;
  495. end;
  496. function TspTrayIcon.InitIcon: Boolean;
  497. var
  498.   B: Boolean;
  499. begin
  500.   Result := False;
  501.   B := True;
  502.   if (csDesigning in ComponentState)
  503.   then
  504.     begin
  505.       if SettingPreview then B := True else B := FDesignPreview
  506.     end;
  507.   if B
  508.   then
  509.     begin
  510.       IconData.hIcon := FIcon.Handle;
  511.       if (FHint <> '') and (FShowHint)
  512.       then
  513.         StrLCopy(IconData.szTip, PChar(FHint), SizeOf(IconData.szTip) - 1)
  514.       else
  515.         IconData.szTip := '';
  516.       Result := True;
  517.     end;
  518. end;
  519. function TspTrayIcon.ShowIcon: Boolean;
  520. begin
  521.   Result := False;
  522.   if not SettingPreview then FIconVisible := True;
  523.   if (csDesigning in ComponentState)
  524.   then
  525.     begin
  526.       if SettingPreview and InitIcon
  527.       then Result := Shell_NotifyIcon(NIM_ADD, @IconData);
  528.     end
  529.   else
  530.     if InitIcon then Result := Shell_NotifyIcon(NIM_ADD, @IconData);
  531. end;
  532. function TspTrayIcon.HideIcon: Boolean;
  533. begin
  534.   Result := False;
  535.   if not SettingPreview then FIconVisible := False;
  536.   if (csDesigning in ComponentState)
  537.   then
  538.     begin
  539.       if SettingPreview and InitIcon
  540.       then Result := Shell_NotifyIcon(NIM_DELETE, @IconData);
  541.     end
  542.   else
  543.     if InitIcon then Result := Shell_NotifyIcon(NIM_DELETE, @IconData);
  544. end;
  545. function TspTrayIcon.ModifyIcon: Boolean;
  546. begin
  547.   Result := False;
  548.   if InitIcon then Result := Shell_NotifyIcon(NIM_MODIFY, @IconData);
  549. end;
  550. procedure TspTrayIcon.TimerCycle(Sender: TObject);
  551. begin
  552.   if Assigned(FIconList)
  553.   then
  554.     begin
  555.       FIconList.GetIcon(FIconIndex, FIcon);
  556.       CycleIcon;
  557.       ModifyIcon;
  558.       if FIconIndex < FIconList.Count-1
  559.       then
  560.         SetIconIndex(FIconIndex+1)
  561.       else
  562.         SetIconIndex(0);
  563.     end;
  564. end;
  565. function TspTrayIcon.BitmapToIcon(const Bitmap: TBitmap;
  566.   const Icon: TIcon; MaskColor: TColor): Boolean;
  567. var
  568.   BitmapImageList: TImageList;
  569. begin
  570.   BitmapImageList := TImageList.CreateSize(16, 16);
  571.   try
  572.     Result := False;
  573.     BitmapImageList.AddMasked(Bitmap, MaskColor);
  574.     BitmapImageList.GetIcon(0, Icon);
  575.     Result := True;
  576.   finally
  577.     BitmapImageList.Free;
  578.   end;
  579. end;
  580. function TspTrayIcon.Refresh: Boolean;
  581. begin
  582.   Result := ModifyIcon;
  583. end;
  584. procedure TspTrayIcon.PopupAtCursor;
  585. var
  586.   CursorPos: TPoint;
  587. begin
  588.   if Assigned(PopupMenu)
  589.   then
  590.     if PopupMenu.AutoPopup
  591.     then
  592.       if GetCursorPos(CursorPos)
  593.       then
  594.         begin
  595.           Application.ProcessMessages;
  596.           SetForegroundWindow(Handle);
  597.           if Owner is TWinControl then
  598.            SetForegroundWindow((Owner as TWinControl).Handle);
  599.           PopupMenu.PopupComponent := Self;
  600.           PopupMenu.Popup(CursorPos.X, CursorPos.Y);
  601.           if Owner is TWinControl then
  602.           PostMessage((Owner as TWinControl).Handle, WM_NULL, 0, 0);
  603.         end;
  604. end;
  605. procedure TspTrayIcon.Click;
  606. begin
  607.   if Assigned(FOnClick) then FOnClick(Self);
  608. end;
  609. procedure TspTrayIcon.DblClick;
  610. begin
  611.   if Assigned(FOnDblClick) then FOnDblClick(Self);
  612. end;
  613. procedure TspTrayIcon.MouseDown(Button: TMouseButton; Shift: TShiftState;
  614.   X, Y: Integer);
  615. begin
  616.   if Assigned(FOnMouseDown) then FOnMouseDown(Self, Button, Shift, X, Y);
  617. end;
  618. procedure TspTrayIcon.MouseUp(Button: TMouseButton; Shift: TShiftState;
  619.   X, Y: Integer);
  620. begin
  621.   if Assigned(FOnMouseUp) then FOnMouseUp(Self, Button, Shift, X, Y);
  622. end;
  623. procedure TspTrayIcon.MouseMove(Shift: TShiftState; X, Y: Integer);
  624. begin
  625.   if Assigned(FOnMouseMove) then FOnMouseMove(Self, Shift, X, Y);
  626. end;
  627. procedure TspTrayIcon.CycleIcon;
  628. var
  629.   NextIconIndex: Integer;
  630. begin
  631.   NextIconIndex := 0;
  632.   if FIconList <> nil then
  633.     if FIconIndex < FIconList.Count then
  634.       NextIconIndex := FIconIndex +1;
  635.   if Assigned(FOnCycle) then
  636.     FOnCycle(Self, NextIconIndex);
  637. end;
  638. procedure TspTrayIcon.DoMinimizeToTray;
  639. begin
  640.   HideMainForm;
  641.   IconVisible := True;
  642. end;
  643. procedure TspTrayIcon.TimerClick(Sender: TObject);
  644. begin
  645.   ClickTimer.Enabled := False;
  646.   if (not IsDblClick)
  647.   then
  648.     if FClickReady
  649.     then
  650.       begin
  651.         FClickReady := False;
  652.         Click;
  653.       end;
  654.   IsDblClick := False;
  655. end;
  656. procedure TspTrayIcon.ShowMainForm;
  657. begin
  658.   if Owner is TWinControl then
  659.     if Application.MainForm <> nil
  660.     then
  661.       begin
  662.         ShowWindow(Application.Handle, SW_RESTORE);
  663.         Application.MainForm.Visible := True;
  664.         if Application.MainForm.WindowState = wsMinimized
  665.         then Application.MainForm.WindowState := wsNormal;
  666.       end;
  667. end;
  668. procedure TspTrayIcon.HideMainForm;
  669. begin
  670.   if Owner is TWinControl
  671.   then
  672.     if Application.MainForm <> nil
  673.     then
  674.       begin
  675.         Application.MainForm.Visible := False;
  676.         ShowWindow(Application.Handle, SW_HIDE);
  677.       end;
  678. end;
  679. end.