home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 June / Chip_2002-06_cd1.bin / zkuste / delphi / kolekce / d6 / rxlibsetup.exe / {app} / units / RxTimer.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2002-02-19  |  7.0 KB  |  274 lines

  1. {*******************************************************}
  2. {                                                       }
  3. {         Delphi VCL Extensions (RX)                    }
  4. {                                                       }
  5. {         Copyright (c) 2001,2002 SGB Software          }
  6. {         Copyright (c) 1997, 1998 Fedor Koshevnikov,   }
  7. {                        Igor Pavluk and Serge Korolev  }
  8. {                                                       }
  9. {*******************************************************}
  10.  
  11.  
  12. unit RxTimer;
  13.  
  14. interface
  15.  
  16. {$I RX.INC}
  17.  
  18. uses {$IFDEF WIN32} Windows, {$ELSE} WinTypes, WinProcs, {$ENDIF}
  19.   Messages, SysUtils, Classes, Controls;
  20.  
  21. type
  22.  
  23. { TRxTimer }
  24.  
  25.   TRxTimer = class(TComponent)
  26.   private
  27.     FEnabled: Boolean;
  28.     FInterval: Cardinal;
  29.     FOnTimer: TNotifyEvent;
  30.     FWindowHandle: HWND;
  31. {$IFDEF WIN32}
  32.     FSyncEvent: Boolean;
  33.     FThreaded: Boolean;
  34.     FTimerThread: TThread;
  35.     FThreadPriority: TThreadPriority;
  36.     procedure SetThreaded(Value: Boolean);
  37.     procedure SetThreadPriority(Value: TThreadPriority);
  38. {$ENDIF}
  39.     procedure SetEnabled(Value: Boolean);
  40.     procedure SetInterval(Value: Cardinal);
  41.     procedure SetOnTimer(Value: TNotifyEvent);
  42.     procedure UpdateTimer;
  43.     procedure WndProc(var Msg: TMessage);
  44.   protected
  45.     procedure Timer; dynamic;
  46.   public
  47.     constructor Create(AOwner: TComponent); override;
  48.     destructor Destroy; override;
  49. {$IFDEF WIN32}
  50.     procedure Synchronize(Method: TThreadMethod);
  51. {$ENDIF}
  52.   published
  53.     property Enabled: Boolean read FEnabled write SetEnabled default True;
  54.     property Interval: Cardinal read FInterval write SetInterval default 1000;
  55. {$IFDEF WIN32}
  56.     property SyncEvent: Boolean read FSyncEvent write FSyncEvent default True;
  57.     property Threaded: Boolean read FThreaded write SetThreaded default True;
  58.     property ThreadPriority: TThreadPriority read FThreadPriority write
  59.       SetThreadPriority default tpNormal;
  60. {$ENDIF}
  61.     property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
  62.   end;
  63.  
  64. implementation
  65.  
  66. uses Forms, Consts, VCLUtils;
  67.  
  68. {$IFDEF WIN32}
  69.  
  70. { TTimerThread }
  71.  
  72. type
  73.   TTimerThread = class(TThread)
  74.   private
  75.     FOwner: TRxTimer;
  76.     FInterval: Cardinal;
  77.     FException: Exception;
  78.     procedure HandleException;
  79.   protected
  80.     procedure Execute; override;
  81.   public
  82.     constructor Create(Timer: TRxTimer; Enabled: Boolean);
  83.   end;
  84.  
  85. constructor TTimerThread.Create(Timer: TRxTimer; Enabled: Boolean);
  86. begin
  87.   FOwner := Timer;
  88.   inherited Create(not Enabled);
  89.   FInterval := 1000;
  90.   FreeOnTerminate := True;
  91. end;
  92.  
  93. procedure TTimerThread.HandleException;
  94. begin
  95.   if not (FException is EAbort) then begin
  96.     if Assigned(Application.OnException) then
  97.       Application.OnException(Self, FException)
  98.     else
  99.       Application.ShowException(FException);
  100.   end;
  101. end;
  102.  
  103. procedure TTimerThread.Execute;
  104.  
  105.   function ThreadClosed: Boolean;
  106.   begin
  107.     Result := Terminated or Application.Terminated or (FOwner = nil);
  108.   end;
  109.  
  110. begin
  111.   repeat
  112.     if not ThreadClosed then
  113.       if SleepEx(FInterval, False) = 0 then begin
  114.         if not ThreadClosed and FOwner.FEnabled then
  115.           with FOwner do
  116.             if SyncEvent then Synchronize(Timer)
  117.             else
  118.               try
  119.                 Timer;
  120.               except
  121.                 on E: Exception do begin
  122.                   FException := E;
  123.                   HandleException;
  124.                 end;
  125.               end;
  126.       end;
  127.   until Terminated;
  128. end;
  129.  
  130. {$ENDIF}
  131.  
  132. { TRxTimer }
  133.  
  134. constructor TRxTimer.Create(AOwner: TComponent);
  135. begin
  136.   inherited Create(AOwner);
  137.   FEnabled := True;
  138.   FInterval := 1000;
  139. {$IFDEF WIN32}
  140.   FSyncEvent := True;
  141.   FThreaded := True;
  142.   FThreadPriority := tpNormal;
  143.   FTimerThread := TTimerThread.Create(Self, False);
  144. {$ELSE}
  145.   FWindowHandle := AllocateHWnd(WndProc);
  146. {$ENDIF}
  147. end;
  148.  
  149. destructor TRxTimer.Destroy;
  150. begin
  151.   Destroying;
  152.   FEnabled := False;
  153.   FOnTimer := nil;
  154. {$IFDEF WIN32}
  155.   {TTimerThread(FTimerThread).FOwner := nil;}
  156.   while FTimerThread.Suspended do FTimerThread.Resume;
  157.   FTimerThread.Terminate;
  158.   {if not SyncEvent then FTimerThread.WaitFor;}
  159.   if FWindowHandle <> 0 then begin
  160. {$ENDIF}
  161.     KillTimer(FWindowHandle, 1);
  162.     Classes.DeallocateHWnd(FWindowHandle);
  163. {$IFDEF WIN32}
  164.   end;
  165. {$ENDIF}
  166.   inherited Destroy;
  167. end;
  168.  
  169. procedure TRxTimer.WndProc(var Msg: TMessage);
  170. begin
  171.   with Msg do
  172.     if Msg = WM_TIMER then
  173.       try
  174.         Timer;
  175.       except
  176.         Application.HandleException(Self);
  177.       end
  178.     else Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam);
  179. end;
  180.  
  181. procedure TRxTimer.UpdateTimer;
  182. begin
  183. {$IFDEF WIN32}
  184.   if FThreaded then begin
  185.     if FWindowHandle <> 0 then begin
  186.       KillTimer(FWindowHandle, 1);
  187.       Classes.DeallocateHWnd(FWindowHandle);
  188.       FWindowHandle := 0;
  189.     end;
  190.     if not FTimerThread.Suspended then FTimerThread.Suspend;
  191.     TTimerThread(FTimerThread).FInterval := FInterval;
  192.     if (FInterval <> 0) and FEnabled and Assigned(FOnTimer) then begin
  193.       FTimerThread.Priority := FThreadPriority;
  194.       while FTimerThread.Suspended do FTimerThread.Resume;
  195.     end;
  196.   end
  197.   else begin
  198.     if not FTimerThread.Suspended then FTimerThread.Suspend;
  199.     if FWindowHandle = 0 then FWindowHandle := Classes.AllocateHWnd(WndProc)
  200.     else KillTimer(FWindowHandle, 1);
  201.     if (FInterval <> 0) and FEnabled and Assigned(FOnTimer) then
  202.       if SetTimer(FWindowHandle, 1, FInterval, nil) = 0 then
  203.         raise EOutOfResources.Create(ResStr(SNoTimers));
  204.   end;
  205. {$ELSE}
  206.   KillTimer(FWindowHandle, 1);
  207.   if (FInterval <> 0) and FEnabled and Assigned(FOnTimer) then
  208.     if SetTimer(FWindowHandle, 1, FInterval, nil) = 0 then
  209.       raise EOutOfResources.Create(ResStr(SNoTimers));
  210. {$ENDIF}
  211. end;
  212.  
  213. procedure TRxTimer.SetEnabled(Value: Boolean);
  214. begin
  215.   if Value <> FEnabled then begin
  216.     FEnabled := Value;
  217.     UpdateTimer;
  218.   end;
  219. end;
  220.  
  221. procedure TRxTimer.SetInterval(Value: Cardinal);
  222. begin
  223.   if Value <> FInterval then begin
  224.     FInterval := Value;
  225.     UpdateTimer;
  226.   end;
  227. end;
  228.  
  229. {$IFDEF WIN32}
  230.  
  231. procedure TRxTimer.SetThreaded(Value: Boolean);
  232. begin
  233.   if Value <> FThreaded then begin
  234.     FThreaded := Value;
  235.     UpdateTimer;
  236.   end;
  237. end;
  238.  
  239. procedure TRxTimer.SetThreadPriority(Value: TThreadPriority);
  240. begin
  241.   if Value <> FThreadPriority then begin
  242.     FThreadPriority := Value;
  243.     if FThreaded then UpdateTimer;
  244.   end;
  245. end;
  246.  
  247. procedure TRxTimer.Synchronize(Method: TThreadMethod);
  248. begin
  249.   if (FTimerThread <> nil) then begin
  250.     with TTimerThread(FTimerThread) do begin
  251.       if Suspended or Terminated then Method
  252.       else TTimerThread(FTimerThread).Synchronize(Method);
  253.     end;
  254.   end
  255.   else Method;
  256. end;
  257.  
  258. {$ENDIF}
  259.  
  260. procedure TRxTimer.SetOnTimer(Value: TNotifyEvent);
  261. begin
  262.   if Assigned(FOnTimer) <> Assigned(Value) then begin
  263.     FOnTimer := Value;
  264.     UpdateTimer;
  265.   end else FOnTimer := Value;
  266. end;
  267.  
  268. procedure TRxTimer.Timer;
  269. begin
  270.   if FEnabled and not (csDestroying in ComponentState) and
  271.     Assigned(FOnTimer) then FOnTimer(Self);
  272. end;
  273.  
  274. end.