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

Delphi控件源码

开发平台:

Delphi

  1. {*******************************************************************}
  2. {                                                                   }
  3. {       Almediadev Visual Component Library                         }
  4. {       DynamicSkinForm                                             }
  5. {       Version 5.60                                                }
  6. {                                                                   }
  7. {       Copyright (c) 2000-2003 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 := True;
  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.         FIconVisible := True;
  217.         MinimizeToTray := True;
  218.         Application.ShowMainForm := False;
  219.         ShowWindow(Application.Handle, SW_HIDE);
  220.       end;
  221.   ModifyIcon;
  222.   SetIconVisible(FIconVisible);
  223. end;
  224. function TspTrayIcon.LoadDefaultIcon: Boolean;
  225. begin
  226.   Result := True;
  227. end;
  228. procedure TspTrayIcon.Notification(AComponent: TComponent;
  229.   Operation: TOperation);
  230. begin
  231.   inherited Notification(AComponent, Operation);
  232.   if (AComponent = FIconList) and (Operation = opRemove)
  233.   then
  234.     begin
  235.       FIconList := nil;
  236.     end;
  237.   if (AComponent = FPopupMenu) and (Operation = opRemove)
  238.   then
  239.     begin
  240.       FPopupMenu := nil;
  241.     end;
  242. end;
  243. procedure TspTrayIcon.HookApp;
  244. begin
  245.   OldAppProc := Pointer(GetWindowLong(Application.Handle, GWL_WNDPROC));
  246.   NewAppProc := MakeObjectInstance(HookAppProc);
  247.   SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(NewAppProc));
  248. end;
  249. procedure TspTrayIcon.UnhookApp;
  250. begin
  251.   if Assigned(OldAppProc)
  252.   then
  253.     SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(OldAppProc));
  254.   if Assigned(NewAppProc)
  255.   then
  256.     FreeObjectInstance(NewAppProc);
  257.   NewAppProc := nil;
  258.   OldAppProc := nil;
  259. end;
  260. procedure TspTrayIcon.HookAppProc(var Msg: TMessage);
  261. begin
  262.   case Msg.Msg of
  263.     WM_SIZE:
  264.       if Msg.wParam = SIZE_MINIMIZED
  265.       then
  266.         begin
  267.           if FMinimizeToTray then DoMinimizeToTray;
  268.         end;
  269.     WM_WINDOWPOSCHANGED:
  270.       begin
  271.         if SettingMDIForm
  272.         then
  273.           if Application.MainForm <> nil
  274.           then
  275.             begin
  276.               if (Application.MainForm.FormStyle = fsMDIForm) then
  277.               if FMinimizedOnStart then
  278.               ShowWindow(Application.Handle, SW_HIDE);
  279.               SettingMDIForm := False;
  280.             end;
  281.       end;
  282.   end;
  283.   if (Msg.Msg = WM_TASKBARCREATED) and FIconVisible then ShowIcon;
  284.   Msg.Result := CallWindowProc(OldAppProc, Application.Handle,
  285.                                Msg.Msg, Msg.wParam, Msg.lParam);
  286. end;
  287. procedure TspTrayIcon.HookForm;
  288. begin
  289.   if (Owner as TWinControl) <> nil
  290.   then
  291.     begin
  292.       OldWndProc := Pointer(GetWindowLong((Owner as TWinControl).Handle, GWL_WNDPROC));
  293.       NewWndProc := MakeObjectInstance(HookFormProc);
  294.       SetWindowLong((Owner as TWinControl).Handle, GWL_WNDPROC, LongInt(NewWndProc));
  295.     end;
  296. end;
  297. procedure TspTrayIcon.UnhookForm;
  298. begin
  299.   if ((Owner as TWinControl) <> nil) and (Assigned(OldWndProc))
  300.   then
  301.     SetWindowLong((Owner as TWinControl).Handle, GWL_WNDPROC, LongInt(OldWndProc));
  302.   if Assigned(NewWndProc)
  303.   then
  304.     FreeObjectInstance(NewWndProc);
  305.   NewWndProc := nil;
  306.   OldWndProc := nil;
  307. end;
  308. procedure TspTrayIcon.HookFormProc(var Msg: TMessage);
  309. begin
  310.   case Msg.Msg of
  311.     WM_SHOWWINDOW:
  312.      begin
  313.        if (Msg.lParam = 0) and (Msg.wParam = 1)
  314.        then
  315.          begin
  316.            ShowWindow(Application.Handle, SW_RESTORE);
  317.            SetForegroundWindow(Application.Handle);
  318.            SetForegroundWindow((Owner as TWinControl).Handle);
  319.          end;
  320.      end;
  321.     WM_ACTIVATE: begin
  322.        if Assigned(Screen.ActiveControl)
  323.        then
  324.         if (Msg.WParamLo = WA_ACTIVE) or (Msg.WParamLo = WA_CLICKACTIVE)
  325.         then
  326.           if Assigned(Screen.ActiveControl.Parent)
  327.           then
  328.             begin
  329.               if HWND(Msg.lParam) <> Screen.ActiveControl.Parent.Handle
  330.               then SetFocus(Screen.ActiveControl.Handle);
  331.             end
  332.         else
  333.           begin
  334.             if HWND(Msg.lParam) <> Screen.ActiveControl.Handle
  335.             then SetFocus(Screen.ActiveControl.Handle);
  336.           end;
  337.     end;
  338.   end;
  339.   Msg.Result := CallWindowProc(OldWndProc, (Owner as TWinControl).Handle,
  340.                 Msg.Msg, Msg.wParam, Msg.lParam);
  341. end;
  342. procedure TspTrayIcon.HandleIconMessage(var Msg: TMessage);
  343.   function ShiftState: TShiftState;
  344.   begin
  345.     Result := [];
  346.     if GetAsyncKeyState(VK_SHIFT) < 0
  347.     then Include(Result, ssShift);
  348.     if GetAsyncKeyState(VK_CONTROL) < 0
  349.     then Include(Result, ssCtrl);
  350.     if GetAsyncKeyState(VK_MENU) < 0
  351.     then Include(Result, ssAlt);
  352.   end;
  353. var
  354.   Pt: TPoint;
  355.   Shift: TShiftState;
  356.   I: Integer;
  357.   M: TMenuItem;
  358. begin
  359.   if Msg.Msg = WM_TRAYNOTIFY
  360.   then
  361.     begin
  362.       if FEnabled then
  363.         case Msg.lParam of
  364.            WM_MOUSEMOVE:
  365.              begin
  366.                Shift := ShiftState;
  367.                GetCursorPos(Pt);
  368.                MouseMove(Shift, Pt.X, Pt.Y);
  369.              end;
  370.            WM_LBUTTONDOWN:
  371.              begin
  372.                ClickTimer.Enabled := True;
  373.                Shift := ShiftState + [ssLeft];
  374.                GetCursorPos(Pt);
  375.                MouseDown(mbLeft, Shift, Pt.X, Pt.Y);
  376.                FClickStart := True;
  377.               if FPopupByLeftButton then PopupAtCursor;
  378.             end;
  379.            WM_RBUTTONDOWN:
  380.              begin
  381.                Shift := ShiftState + [ssRight];
  382.                GetCursorPos(Pt);
  383.                MouseDown(mbRight, Shift, Pt.X, Pt.Y);
  384.                PopupAtCursor;
  385.              end;
  386.            WM_MBUTTONDOWN:
  387.              begin
  388.                Shift := ShiftState + [ssMiddle];
  389.                GetCursorPos(Pt);
  390.                MouseDown(mbMiddle, Shift, Pt.X, Pt.Y);
  391.              end;
  392.            WM_LBUTTONUP:
  393.              begin
  394.                Shift := ShiftState + [ssLeft];
  395.                GetCursorPos(Pt);
  396.                if FClickStart then FClickReady := True;
  397.                if FClickStart and (not ClickTimer.Enabled)
  398.                then
  399.                  begin
  400.                    FClickStart := False;
  401.                    FClickReady := False;
  402.                     Click;
  403.                  end;
  404.                FClickStart := False;
  405.                MouseUp(mbLeft, Shift, Pt.X, Pt.Y);
  406.              end;
  407.            WM_RBUTTONUP:
  408.              begin
  409.                Shift := ShiftState + [ssRight];
  410.                GetCursorPos(Pt);
  411.                MouseUp(mbRight, Shift, Pt.X, Pt.Y);
  412.              end;
  413.            WM_MBUTTONUP:
  414.              begin
  415.                Shift := ShiftState + [ssMiddle];
  416.                GetCursorPos(Pt);
  417.                MouseUp(mbMiddle, Shift, Pt.X, Pt.Y);
  418.              end;
  419.            WM_LBUTTONDBLCLK:
  420.              begin
  421.                FClickReady := False;
  422.                IsDblClick := True;
  423.                DblClick;
  424.                M := nil;
  425.                if Assigned(FPopupMenu)
  426.                then
  427.                  if (FPopupMenu.AutoPopup) and (not FPopupByLeftButton)
  428.                  then
  429.                    for I := PopupMenu.Items.Count -1 downto 0 do
  430.                      if PopupMenu.Items[I].Default then M := PopupMenu.Items[I];
  431.                if M <> nil then M.Click;
  432.              end;
  433.         end;
  434.     end
  435.   else
  436.     case Msg.Msg of
  437.       WM_QUERYENDSESSION, WM_CLOSE, WM_QUIT,
  438.       WM_DESTROY, WM_NCDESTROY, WM_USERCHANGED:  Msg.Result := 1;
  439.     else
  440.       Msg.Result := DefWindowProc(IconData.Wnd, Msg.Msg, Msg.wParam, Msg.lParam);
  441.     end;
  442. end;
  443. procedure TspTrayIcon.SetIcon(Value: TIcon);
  444. begin
  445.   FIcon.Assign(Value);
  446.   ModifyIcon;
  447. end;
  448. procedure TspTrayIcon.SetIconVisible(Value: Boolean);
  449. begin
  450.   if Value then ShowIcon else HideIcon;
  451. end;
  452. procedure TspTrayIcon.SetDesignPreview(Value: Boolean);
  453. begin
  454.   FDesignPreview := Value;
  455.   SettingPreview := True;
  456.   SetIconVisible(Value);
  457.   SettingPreview := False;
  458. end;
  459. procedure TspTrayIcon.SetCycleIcons(Value: Boolean);
  460. begin
  461.   FCycleIcons := Value;
  462.   if Value then SetIconIndex(0);
  463.   AnimateTimer.Enabled := Value;
  464. end;
  465. procedure TspTrayIcon.SetAnimateTimerInterval(Value: Cardinal);
  466. begin
  467.   FAnimateTimerInterval := Value;
  468.   AnimateTimer.Interval := FAnimateTimerInterval;
  469. end;
  470. procedure TspTrayIcon.SetIconList(Value: TImageList);
  471. begin
  472.   FIconList := Value;
  473.   SetIconIndex(0);
  474. end;
  475. procedure TspTrayIcon.SetIconIndex(Value: Integer);
  476. begin
  477.   if FIconList <> nil
  478.   then
  479.     begin
  480.       FIconIndex := Value;
  481.       if Value >= FIconList.Count then FIconIndex := FIconList.Count - 1;
  482.       FIconList.GetIcon(FIconIndex, FIcon);
  483.     end
  484.   else
  485.     FIconIndex := 0;
  486.   ModifyIcon;
  487. end;
  488. procedure TspTrayIcon.SetHint(Value: String);
  489. begin
  490.   FHint := Value;
  491.   ModifyIcon;
  492. end;
  493. procedure TspTrayIcon.SetShowHint(Value: Boolean);
  494. begin
  495.   FShowHint := Value;
  496.   ModifyIcon;
  497. end;
  498. function TspTrayIcon.InitIcon: Boolean;
  499. var
  500.   B: Boolean;
  501. begin
  502.   Result := False;
  503.   B := True;
  504.   if (csDesigning in ComponentState)
  505.   then
  506.     begin
  507.       if SettingPreview then B := True else B := FDesignPreview
  508.     end;
  509.   if B
  510.   then
  511.     begin
  512.       IconData.hIcon := FIcon.Handle;
  513.       if (FHint <> '') and (FShowHint)
  514.       then
  515.         StrLCopy(IconData.szTip, PChar(FHint), SizeOf(IconData.szTip) - 1)
  516.       else
  517.         IconData.szTip := '';
  518.       Result := True;
  519.     end;
  520. end;
  521. function TspTrayIcon.ShowIcon: Boolean;
  522. begin
  523.   Result := False;
  524.   if not SettingPreview then FIconVisible := True;
  525.   if (csDesigning in ComponentState)
  526.   then
  527.     begin
  528.       if SettingPreview and InitIcon
  529.       then Result := Shell_NotifyIcon(NIM_ADD, @IconData);
  530.     end
  531.   else
  532.     if InitIcon then Result := Shell_NotifyIcon(NIM_ADD, @IconData);
  533. end;
  534. function TspTrayIcon.HideIcon: Boolean;
  535. begin
  536.   Result := False;
  537.   if not SettingPreview then FIconVisible := False;
  538.   if (csDesigning in ComponentState)
  539.   then
  540.     begin
  541.       if SettingPreview and InitIcon
  542.       then Result := Shell_NotifyIcon(NIM_DELETE, @IconData);
  543.     end
  544.   else
  545.     if InitIcon then Result := Shell_NotifyIcon(NIM_DELETE, @IconData);
  546. end;
  547. function TspTrayIcon.ModifyIcon: Boolean;
  548. begin
  549.   Result := False;
  550.   if InitIcon then Result := Shell_NotifyIcon(NIM_MODIFY, @IconData);
  551. end;
  552. procedure TspTrayIcon.TimerCycle(Sender: TObject);
  553. begin
  554.   if Assigned(FIconList)
  555.   then
  556.     begin
  557.       FIconList.GetIcon(FIconIndex, FIcon);
  558.       CycleIcon;
  559.       ModifyIcon;
  560.       if FIconIndex < FIconList.Count-1
  561.       then
  562.         SetIconIndex(FIconIndex+1)
  563.       else
  564.         SetIconIndex(0);
  565.     end;
  566. end;
  567. function TspTrayIcon.BitmapToIcon(const Bitmap: TBitmap;
  568.   const Icon: TIcon; MaskColor: TColor): Boolean;
  569. var
  570.   BitmapImageList: TImageList;
  571. begin
  572.   BitmapImageList := TImageList.CreateSize(16, 16);
  573.   try
  574.     Result := False;
  575.     BitmapImageList.AddMasked(Bitmap, MaskColor);
  576.     BitmapImageList.GetIcon(0, Icon);
  577.     Result := True;
  578.   finally
  579.     BitmapImageList.Free;
  580.   end;
  581. end;
  582. function TspTrayIcon.Refresh: Boolean;
  583. begin
  584.   Result := ModifyIcon;
  585. end;
  586. procedure TspTrayIcon.PopupAtCursor;
  587. var
  588.   CursorPos: TPoint;
  589. begin
  590.   if Assigned(PopupMenu)
  591.   then
  592.     if PopupMenu.AutoPopup
  593.     then
  594.       if GetCursorPos(CursorPos)
  595.       then
  596.         begin
  597.           Application.ProcessMessages;
  598.           SetForegroundWindow(Handle);
  599.           if Owner is TWinControl then
  600.            SetForegroundWindow((Owner as TWinControl).Handle);
  601.           PopupMenu.PopupComponent := Self;
  602.           PopupMenu.Popup(CursorPos.X, CursorPos.Y);
  603.           if Owner is TWinControl then
  604.           PostMessage((Owner as TWinControl).Handle, WM_NULL, 0, 0);
  605.         end;
  606. end;
  607. procedure TspTrayIcon.Click;
  608. begin
  609.   if Assigned(FOnClick) then FOnClick(Self);
  610. end;
  611. procedure TspTrayIcon.DblClick;
  612. begin
  613.   if Assigned(FOnDblClick) then FOnDblClick(Self);
  614. end;
  615. procedure TspTrayIcon.MouseDown(Button: TMouseButton; Shift: TShiftState;
  616.   X, Y: Integer);
  617. begin
  618.   if Assigned(FOnMouseDown) then FOnMouseDown(Self, Button, Shift, X, Y);
  619. end;
  620. procedure TspTrayIcon.MouseUp(Button: TMouseButton; Shift: TShiftState;
  621.   X, Y: Integer);
  622. begin
  623.   if Assigned(FOnMouseUp) then FOnMouseUp(Self, Button, Shift, X, Y);
  624. end;
  625. procedure TspTrayIcon.MouseMove(Shift: TShiftState; X, Y: Integer);
  626. begin
  627.   if Assigned(FOnMouseMove) then FOnMouseMove(Self, Shift, X, Y);
  628. end;
  629. procedure TspTrayIcon.CycleIcon;
  630. var
  631.   NextIconIndex: Integer;
  632. begin
  633.   NextIconIndex := 0;
  634.   if FIconList <> nil then
  635.     if FIconIndex < FIconList.Count then
  636.       NextIconIndex := FIconIndex +1;
  637.   if Assigned(FOnCycle) then
  638.     FOnCycle(Self, NextIconIndex);
  639. end;
  640. procedure TspTrayIcon.DoMinimizeToTray;
  641. begin
  642.   HideMainForm;
  643.   IconVisible := True;
  644. end;
  645. procedure TspTrayIcon.TimerClick(Sender: TObject);
  646. begin
  647.   ClickTimer.Enabled := False;
  648.   if (not IsDblClick)
  649.   then
  650.     if FClickReady
  651.     then
  652.       begin
  653.         FClickReady := False;
  654.         Click;
  655.       end;
  656.   IsDblClick := False;
  657. end;
  658. procedure TspTrayIcon.ShowMainForm;
  659. begin
  660.   if Owner is TWinControl then
  661.     if Application.MainForm <> nil
  662.     then
  663.       begin
  664.         ShowWindow(Application.Handle, SW_RESTORE);
  665.         Application.MainForm.Visible := True;
  666.         if Application.MainForm.WindowState = wsMinimized
  667.         then Application.MainForm.WindowState := wsNormal;
  668.       end;
  669. end;
  670. procedure TspTrayIcon.HideMainForm;
  671. begin
  672.   if Owner is TWinControl
  673.   then
  674.     if Application.MainForm <> nil
  675.     then
  676.       begin
  677.         Application.MainForm.Visible := False;
  678.         ShowWindow(Application.Handle, SW_HIDE);
  679.       end;
  680. end;
  681. end.