home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 September / Chip_2001-09_cd1.bin / zkuste / delphi / kolekce / d6 / RX275D6.ZIP / Units / RxTimer.pas < prev    next >
Pascal/Delphi Source File  |  1999-10-12  |  7KB  |  272 lines

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