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

Delphi控件源码

开发平台:

Delphi

  1. {*****************************************************************}
  2. { SimpleTimer is a timer class. It has the same timer resolution  }
  3. { as TTimer, but it is more lightweight because it's derived from }
  4. { TObject in stead of TComponent. Furthermore, the same handle is }
  5. { shared between multiple instances of SimpleTimer.               }
  6. { This makes it ideal for developers who need a timer in their    }
  7. { own components or applications, but want to keep the resource   }
  8. { usage minimal.                                                  }
  9. {                                                                 }
  10. { The unit is freeware. Feel free to use and improve it.          }
  11. { I would be pleased to hear what you think.                      }
  12. {                                                                 }
  13. { Troels Jakobsen - delphiuser@get2net.dk                         }
  14. { Copyright (c) 2002                                              }
  15. {*****************************************************************}
  16. unit SimpleTimer;
  17. { Some methods have moved to the Classes unit in D6 and are thus deprecated.
  18.   Using the following compiler directives we handle that situation. }
  19. {$IFDEF VER140} {$DEFINE DELPHI_6} {$ENDIF}
  20. {$IFDEF VER150} {$DEFINE DELPHI_7} {$ENDIF}
  21. {$IFDEF DELPHI_6} {$DEFINE DELPHI_6_UP} {$ENDIF}
  22. {$IFDEF DELPHI_7} {$DEFINE DELPHI_6_UP} {$ENDIF}
  23. interface
  24. uses
  25.   Windows, Classes;
  26. type
  27.   TSimpleTimer = class(TObject)
  28.   private
  29.     FId: UINT;
  30.     FEnabled: Boolean;
  31.     FInterval: Cardinal;
  32.     FAutoDisable: Boolean;
  33.     FOnTimer: TNotifyEvent;
  34.     procedure SetEnabled(Value: Boolean);
  35.     procedure SetInterval(Value: Cardinal);
  36.     procedure SetOnTimer(Value: TNotifyEvent);
  37.     procedure Initialize(AInterval: Cardinal; AOnTimer: TNotifyEvent);
  38.   protected
  39.     function Start: Boolean;
  40.     function Stop(Disable: Boolean): Boolean;
  41.   public
  42.     constructor Create;
  43.     constructor CreateEx(AInterval: Cardinal; AOnTimer: TNotifyEvent);
  44.     destructor Destroy; override;
  45.     property Enabled: Boolean read FEnabled write SetEnabled;
  46.     property Interval: Cardinal read FInterval write SetInterval default 1000;
  47.     property AutoDisable: Boolean read FAutoDisable write FAutoDisable;
  48.     property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
  49.   end;
  50. function GetSimpleTimerCount: Cardinal;
  51. function GetSimpleTimerActiveCount: Cardinal;
  52. implementation
  53. uses
  54.   Messages{$IFNDEF DELPHI_6_UP}, Forms {$ENDIF};
  55. type
  56.   TSimpleTimerHandler = class(TObject)
  57.   private
  58.     RefCount: Cardinal;
  59.     ActiveCount: Cardinal;
  60.     FWindowHandle: HWND;
  61.     procedure WndProc(var Msg: TMessage);
  62.   public
  63.     constructor Create;
  64.     destructor Destroy; override;
  65.     procedure AddTimer;
  66.     procedure RemoveTimer;
  67.   end;
  68. var
  69.   SimpleTimerHandler: TSimpleTimerHandler = nil;
  70. function GetSimpleTimerCount: Cardinal;
  71. begin
  72.   if Assigned(SimpleTimerHandler) then
  73.     Result := SimpleTimerHandler.RefCount
  74.   else
  75.     Result := 0;
  76. end;
  77. function GetSimpleTimerActiveCount: Cardinal;
  78. begin
  79.   if Assigned(SimpleTimerHandler) then
  80.     Result := SimpleTimerHandler.ActiveCount
  81.   else
  82.     Result := 0;
  83. end;
  84. {--------------- TSimpleTimerHandler ------------------}
  85. constructor TSimpleTimerHandler.Create;
  86. begin
  87.   inherited Create;
  88. {$IFDEF DELPHI_6_UP}
  89.   FWindowHandle := Classes.AllocateHWnd(WndProc);
  90. {$ELSE}
  91.   FWindowHandle := AllocateHWnd(WndProc);
  92. {$ENDIF}
  93. end;
  94. destructor TSimpleTimerHandler.Destroy;
  95. begin
  96. {$IFDEF DELPHI_6_UP}
  97.   Classes.DeallocateHWnd(FWindowHandle);
  98. {$ELSE}
  99.   DeallocateHWnd(FWindowHandle);
  100. {$ENDIF}
  101.   inherited Destroy;
  102. end;
  103. procedure TSimpleTimerHandler.AddTimer;
  104. begin
  105.   Inc(RefCount);
  106. end;
  107. procedure TSimpleTimerHandler.RemoveTimer;
  108. begin
  109.   if RefCount > 0 then
  110.     Dec(RefCount);
  111. end;
  112. procedure TSimpleTimerHandler.WndProc(var Msg: TMessage);
  113. var
  114.   Timer: TSimpleTimer;
  115. begin
  116.   if Msg.Msg = WM_TIMER then
  117.   begin
  118. {$WARNINGS OFF}
  119.     Timer := TSimpleTimer(Msg.wParam);
  120. {$WARNINGS ON}
  121.     if Timer.FAutoDisable then
  122.       Timer.Stop(True);
  123.     // Call OnTimer event method if assigned
  124.     if Assigned(Timer.FOnTimer) then
  125.       Timer.FOnTimer(Timer);
  126.   end
  127.   else
  128.     Msg.Result := DefWindowProc(FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);
  129. end;
  130. {---------------- Container management ----------------}
  131. procedure AddTimer;
  132. begin
  133.   if not Assigned(SimpleTimerHandler) then
  134.     // Create new handler
  135.     SimpleTimerHandler := TSimpleTimerHandler.Create;
  136.   SimpleTimerHandler.AddTimer;
  137. end;
  138. procedure RemoveTimer;
  139. begin
  140.   if Assigned(SimpleTimerHandler) then
  141.   begin
  142.     SimpleTimerHandler.RemoveTimer;
  143.     if SimpleTimerHandler.RefCount = 0 then
  144.     begin
  145.       // Destroy handler
  146.       SimpleTimerHandler.Free;
  147.       SimpleTimerHandler := nil;
  148.     end;
  149.   end;
  150. end;
  151. {------------------ Callback method -------------------}
  152. {
  153. procedure TimerProc(hWnd: HWND; uMsg: UINT; idEvent: UINT; dwTime: DWORD); stdcall;
  154. var
  155.   Timer: TSimpleTimer;
  156. begin
  157. //  if uMsg = WM_TIMER then    // It's always WM_TIMER
  158.   begin
  159.     try
  160.       Timer := TSimpleTimer(idEvent);
  161.       if Assigned(Timer.FCallBackProc) then
  162.         Timer.FCallBackProc(Timer.FOwner);
  163.     except
  164.       // ???
  165.     end;
  166.   end;
  167. end;
  168. }
  169. {------------------- TSimpleTimer ---------------------}
  170. constructor TSimpleTimer.Create;
  171. begin
  172.   inherited Create;
  173.   Initialize(1000, nil);
  174. end;
  175. constructor TSimpleTimer.CreateEx(AInterval: Cardinal; AOnTimer: TNotifyEvent);
  176. begin
  177.   inherited Create;
  178.   Initialize(AInterval, AOnTimer);
  179. end;
  180. destructor TSimpleTimer.Destroy;
  181. begin
  182.   if FEnabled then
  183.     Stop(True);
  184.   RemoveTimer;               // Container management
  185.   inherited Destroy;
  186. end;
  187. procedure TSimpleTimer.Initialize(AInterval: Cardinal; AOnTimer: TNotifyEvent);
  188. begin
  189. {$WARNINGS OFF}
  190.   FId := UINT(Self);         // Use Self as id in call to SetTimer and callback method
  191. {$WARNINGS ON}
  192.   FAutoDisable := False;
  193.   FEnabled := False;
  194.   FInterval := AInterval;
  195.   SetOnTimer(AOnTimer);
  196.   AddTimer;                  // Container management
  197. end;
  198. procedure TSimpleTimer.SetEnabled(Value: Boolean);
  199. begin
  200.   if Value then
  201.     Start
  202.   else
  203.     Stop(True);
  204. end;
  205. procedure TSimpleTimer.SetInterval(Value: Cardinal);
  206. begin
  207.   if Value <> FInterval then
  208.   begin
  209.     FInterval := Value;
  210.     if FEnabled then
  211.       if FInterval <> 0 then
  212.         Start
  213.       else
  214.         Stop(False);
  215.   end;
  216. end;
  217. procedure TSimpleTimer.SetOnTimer(Value: TNotifyEvent);
  218. begin
  219.   FOnTimer := Value;
  220.   if (not Assigned(Value)) and (FEnabled) then
  221.     Stop(False);
  222. end;
  223. function TSimpleTimer.Start: Boolean;
  224. begin
  225.   if FInterval = 0 then
  226.   begin
  227.     Result := False;
  228.     Exit;
  229.   end;
  230.   if FEnabled then
  231.     Stop(True);
  232. //  Result := (SetTimer(SimpleTimerHandler.FWindowHandle, FId, FInterval, @TimerProc) <> 0);
  233.   Result := (SetTimer(SimpleTimerHandler.FWindowHandle, FId, FInterval, nil) <> 0);
  234.   if Result then
  235.   begin
  236.     FEnabled := True;
  237.     Inc(SimpleTimerHandler.ActiveCount);
  238.   end
  239. {  else
  240.     raise EOutOfResources.Create(SNoTimers); }
  241. end;
  242. function TSimpleTimer.Stop(Disable: Boolean): Boolean;
  243. begin
  244.   if Disable then
  245.     FEnabled := False;
  246.   Result := KillTimer(SimpleTimerHandler.FWindowHandle, FId);
  247.   if Result and (SimpleTimerHandler.ActiveCount > 0) then
  248.     Dec(SimpleTimerHandler.ActiveCount);
  249. end;
  250. initialization
  251. finalization
  252.   if Assigned(SimpleTimerHandler) then
  253.   begin
  254.     SimpleTimerHandler.Free;
  255.     SimpleTimerHandler := nil;
  256.   end;
  257. end.