VrThreads.pas
上传用户:hbszzs
上传日期:2008-08-20
资源大小:628k
文件大小:9k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {*****************************************************}
  2. {                                                     }
  3. {     Varian Component Workshop                       }
  4. {                                                     }
  5. {     Varian Software NL (c) 1996-2000                }
  6. {     All Rights Reserved                             }
  7. {                                                     }
  8. {*****************************************************}
  9. unit VrThreads;
  10. interface
  11. uses
  12.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  13.   VrTypes, VrClasses, VrControls;
  14. {$I VRLIB.INC}
  15. type
  16.   TVrTimerType = (ttThread, ttSystem);
  17.   TVrTimer = class(TVrComponent)
  18.   private
  19.     FEnabled: Boolean;
  20.     FInterval: Cardinal;
  21.     FOnTimer: TNotifyEvent;
  22.     FWindowHandle: HWND;
  23.     FSyncEvent: Boolean;
  24.     FTimerType: TVrTimerType;
  25.     FTimerThread: TThread;
  26.     FPriority: TThreadPriority;
  27.     FAllocated: Boolean;
  28.     procedure SetTimerType(Value: TVrTimerType);
  29.     procedure SetPriority(Value: TThreadPriority);
  30.     procedure SetEnabled(Value: Boolean);
  31.     procedure SetInterval(Value: Cardinal);
  32.     procedure CreateTimer;
  33.     procedure DestroyTimer;
  34.     procedure UpdateTimer;
  35.     procedure WndProc(var Msg: TMessage);
  36.   protected
  37.     procedure Loaded; override;
  38.     procedure Timer; dynamic;
  39.   public
  40.     constructor Create(AOwner: TComponent); override;
  41.     destructor Destroy; override;
  42.   published
  43.     property Enabled: Boolean read FEnabled write SetEnabled default True;
  44.     property Interval: Cardinal read FInterval write SetInterval default 1000;
  45.     property SyncEvent: Boolean read FSyncEvent write FSyncEvent default True;
  46.     property TimerType: TVrTimerType read FTimerType write SetTimerType default ttThread;
  47.     property Priority: TThreadPriority read FPriority write SetPriority default tpNormal;
  48.     property OnTimer: TNotifyEvent read FOnTimer write FOnTimer;
  49.   end;
  50.   TVrThread = class;
  51.   TVrSystemThread = class(TThread)
  52.   private
  53.     FOwner: TVrThread;
  54.     FOnExecute: TNotifyEvent;
  55.   protected
  56.     procedure CallExecute;
  57.     procedure Execute; override;
  58.   public
  59.     constructor Create(AOwner: TVrThread; Enabled: Boolean);
  60.     property OnExecute: TNotifyEvent read FOnExecute write FOnExecute;
  61.   end;
  62.   TVrThread = class(TVrComponent)
  63.   private
  64.     FEnabled: Boolean;
  65.     FSyncEvent: Boolean;
  66.     FPriority: TThreadPriority;
  67.     FOnExecute: TNotifyEvent;
  68.     FSystemThread: TVrSystemThread;
  69.     procedure SetEnabled(Value: Boolean);
  70.     procedure SetPriority(Value: TThreadPriority);
  71.     procedure ExecuteEvent(Sender: TObject);
  72.   protected
  73.     procedure UpdateThreadParams;
  74.     procedure Loaded; override;
  75.   public
  76.     constructor Create(AOwner: TComponent); override;
  77.     destructor Destroy; override;
  78.   published
  79.     property Enabled: Boolean read FEnabled write SetEnabled default True;
  80.     property Priority: TThreadPriority read FPriority write SetPriority default tpNormal;
  81.     property SyncEvent: Boolean read FSyncEvent write FSyncEvent default True;
  82.     property OnExecute: TNotifyEvent read FOnExecute write FOnExecute;
  83.   end;
  84. implementation
  85. { TVrTimerThread }
  86. type
  87.   TVrTimerThread = class(TThread)
  88.   private
  89.     FOwner: TVrTimer;
  90.     FEvent: THandle;
  91.     FInterval: Cardinal;
  92.   protected
  93.     procedure Execute; override;
  94.   public
  95.     constructor Create(Timer: TVrTimer; Enabled: Boolean);
  96.     destructor Destroy; override;
  97.     procedure Reset;
  98.   end;
  99. constructor TVrTimerThread.Create(Timer: TVrTimer; Enabled: Boolean);
  100. begin
  101.   FOwner := Timer;
  102.   FInterval := 1000;
  103.   FEvent := CreateEvent(nil, False, False, nil);
  104.   inherited Create(not Enabled);
  105. end;
  106. destructor TVrTimerThread.Destroy;
  107. begin
  108.   CloseHandle(FEvent);
  109.   inherited;
  110. end;
  111. procedure TVrTimerThread.Reset;
  112. begin
  113.   while Suspended do Resume;
  114.   Terminate;
  115.   SetEvent(FEvent);
  116. end;
  117. procedure TVrTimerThread.Execute;
  118. begin
  119.   while not Terminated do
  120.     case WaitForSingleObject(FEvent, FInterval) of
  121.       WAIT_OBJECT_0:;
  122.       WAIT_TIMEOUT:
  123.         if (not Terminated) and (not Application.Terminated) then
  124.           with FOwner do
  125.           begin
  126.             if (FSyncEvent) then
  127.               Synchronize(Timer) else Timer;
  128.           end;
  129.     end;
  130. end;
  131. { TVrTimer }
  132. constructor TVrTimer.Create(AOwner: TComponent);
  133. begin
  134.   inherited Create(AOwner);
  135.   FEnabled := True;
  136.   FInterval := 1000;
  137.   FSyncEvent := True;
  138.   FTimerType := ttThread;
  139.   FPriority := tpNormal;
  140.   FAllocated := false;
  141. end;
  142. destructor TVrTimer.Destroy;
  143. begin
  144.   FEnabled := False;
  145.   FOnTimer := nil;
  146.   DestroyTimer;
  147.   inherited Destroy;
  148. end;
  149. procedure TVrTimer.Loaded;
  150. begin
  151.   inherited Loaded;
  152.   UpdateTimer;
  153. end;
  154. procedure TVrTimer.WndProc(var Msg: TMessage);
  155. begin
  156.   with Msg do
  157.     if Msg = WM_TIMER then Timer
  158.     else Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam);
  159. end;
  160. procedure TVrTimer.CreateTimer;
  161. begin
  162.   if TimerType = ttThread then
  163.     FTimerThread := TVrTimerThread.Create(Self, False)
  164.   else FWindowHandle := AllocateHWnd(WndProc);
  165.   FAllocated := True;
  166. end;
  167. procedure TVrTimer.DestroyTimer;
  168. begin
  169.   if FAllocated then
  170.   begin
  171.     if TimerType = ttThread then
  172.     begin
  173.       TVrTimerThread(FTimerThread).Reset;
  174.       FTimerThread.Free;
  175.     end
  176.     else
  177.      begin
  178.        KillTimer(FWindowHandle, 1);
  179.        DeallocateHWnd(FWindowHandle);
  180.      end;
  181.      FAllocated := false;
  182.   end;
  183. end;
  184. procedure TVrTimer.UpdateTimer;
  185. begin
  186.   if (csDesigning in ComponentState) then Exit;
  187.   if (not FAllocated) then CreateTimer;
  188.   if TimerType = ttThread then
  189.   begin
  190.     if not FTimerThread.Suspended then FTimerThread.Suspend;
  191.     TVrTimerThread(FTimerThread).FInterval := FInterval;
  192.     if (FInterval <> 0) and FEnabled and Assigned(FOnTimer) then
  193.     begin
  194.       FTimerThread.Priority := FPriority;
  195.       while FTimerThread.Suspended do FTimerThread.Resume;
  196.     end;
  197.   end
  198.   else
  199.   begin
  200.     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('No timer resources left.');
  204.   end;
  205. end;
  206. procedure TVrTimer.SetEnabled(Value: Boolean);
  207. begin
  208.   if FEnabled <> Value then
  209.   begin
  210.     FEnabled := Value;
  211.     if Value then UpdateTimer;
  212.   end;
  213. end;
  214. procedure TVrTimer.SetInterval(Value: Cardinal);
  215. begin
  216.   if FInterval <> Value then
  217.   begin
  218.     FInterval := Value;
  219.     if Enabled then UpdateTimer;
  220.   end;
  221. end;
  222. procedure TVrTimer.SetTimerType(Value: TVrTimerType);
  223. begin
  224.   if FTimerType <> Value then
  225.   begin
  226.     DestroyTimer;
  227.     FTimerType := Value;
  228.     if Enabled then UpdateTimer;
  229.   end;
  230. end;
  231. procedure TVrTimer.SetPriority(Value: TThreadPriority);
  232. begin
  233.   if FPriority <> Value then
  234.   begin
  235.     FPriority := Value;
  236.     if (TimerType = ttThread) and (Enabled) then UpdateTimer;
  237.   end;
  238. end;
  239. procedure TVrTimer.Timer;
  240. begin
  241.   if (FEnabled) and Assigned(FOnTimer) then
  242.   begin
  243.     try
  244.       FOnTimer(Self);
  245.     except
  246.       Application.HandleException(Self);
  247.     end;
  248.   end;
  249. end;
  250. { TVrSystemThread }
  251. constructor TVrSystemThread.Create(AOwner: TVrThread; Enabled: Boolean);
  252. begin
  253.   FOwner := AOwner;
  254.   inherited Create(not Enabled);
  255. end;
  256. procedure TVrSystemThread.Execute;
  257.   function ThreadClosed: Boolean;
  258.   begin
  259.     Result := Terminated or (FOwner = nil);
  260.   end;
  261. begin
  262.   while not Terminated do
  263.   begin
  264.     if (FOwner.FEnabled) and (not Application.Terminated) then
  265.       with FOwner do
  266.         if SyncEvent then Synchronize(CallExecute)
  267.         else CallExecute;
  268.   end;
  269. end;
  270. procedure TVrSystemThread.CallExecute;
  271. begin
  272.   if Assigned(FOnExecute) then FOnExecute(Self);
  273. end;
  274. { TVrThread }
  275. constructor TVrThread.Create(AOwner: TComponent);
  276. begin
  277.   inherited Create(AOwner);
  278.   FEnabled := True;
  279.   FPriority := tpNormal;
  280.   FSyncEvent := True;
  281.   FSystemThread := TVrSystemThread.Create(Self, false);
  282.   FSystemThread.OnExecute := ExecuteEvent;
  283. end;
  284. destructor TVrThread.Destroy;
  285. begin
  286.   FSystemThread.OnExecute := nil;
  287.   while FSystemThread.Suspended do
  288.     FSystemThread.Resume;
  289.   FSystemThread.Terminate;
  290.   FSystemThread.Free;
  291.   inherited Destroy;
  292. end;
  293. procedure TVrThread.Loaded;
  294. begin
  295.   inherited Loaded;
  296.   UpdateThreadParams;
  297. end;
  298. procedure TVrThread.UpdateThreadParams;
  299. begin
  300.   if (csDesigning in ComponentState) then Exit;
  301.   if not FSystemThread.Suspended then FSystemThread.Suspend;
  302.   if Enabled then
  303.   begin
  304.     FSystemThread.Priority := FPriority;
  305.     while FSystemThread.Suspended do FSystemThread.Resume;
  306.   end;
  307. end;
  308. procedure TVrThread.SetEnabled(Value: Boolean);
  309. begin
  310.   if FEnabled <> Value then
  311.   begin
  312.     FEnabled := Value;
  313.     UpdateThreadParams;
  314.   end;
  315. end;
  316. procedure TVrThread.SetPriority(Value: TThreadPriority);
  317. begin
  318.   if FPriority <> Value then
  319.   begin
  320.     FPriority := Value;
  321.     UpdateThreadParams;
  322.   end;
  323. end;
  324. procedure TVrThread.ExecuteEvent(Sender: TObject);
  325. begin
  326.   if Enabled and Assigned(FOnExecute) then
  327.   begin
  328.     try
  329.       FOnExecute(Self);
  330.     except
  331.       Application.HandleException(Self);
  332.     end;
  333.   end;
  334. end;
  335. end.