home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 December / Chip_2002-12_cd1.bin / zkuste / delphi / kompon / d234567 / COOLTRAY.ZIP / SimpleTimer.pas < prev    next >
Pascal/Delphi Source File  |  2002-10-04  |  6KB  |  224 lines

  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.  
  17. unit SimpleTimer;
  18.  
  19. { Some methods have moved to the Classes unit in D6 and are thus deprecated.
  20.   Using the following compiler directives we handle that situation. }
  21. {$IFDEF VER140} {$DEFINE DELPHI_6} {$ENDIF}
  22. {$IFDEF VER150} {$DEFINE DELPHI_7} {$ENDIF}
  23. {$IFDEF DELPHI_6} {$DEFINE DELPHI_6_UP} {$ENDIF}
  24. {$IFDEF DELPHI_7} {$DEFINE DELPHI_6_UP} {$ENDIF}
  25.  
  26. interface
  27.  
  28. uses
  29.   Windows, Classes;
  30.  
  31. type
  32.   TSimpleTimerCallBackProc = procedure(AOwner: TComponent); stdcall;
  33.  
  34.   TSimpleTimer = class(TObject)
  35.   private
  36.     FOwner: TComponent;
  37.     FId: UINT;
  38.     FActive: Boolean;
  39.     FInterval: Cardinal;
  40.     FCallBackProc: TSimpleTimerCallBackProc;
  41.   public
  42.     constructor Create(AOwner: TComponent; CallBackProc: TSimpleTimerCallBackProc);
  43.     destructor Destroy; override;
  44.     function Start(MilliSecs: Cardinal): Boolean;
  45.     function Stop: Boolean;
  46.     property Owner: TComponent read FOwner;
  47.     property Active: Boolean read FActive;
  48.   end;
  49.  
  50.  
  51. implementation
  52.  
  53. uses
  54.   Messages{$IFNDEF DELPHI_6_UP}, Forms {$ENDIF};
  55.  
  56. type
  57.   TSimpleTimerHandler = class(TObject)
  58.   private
  59.     RefCount: 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.  
  69. var
  70.   SimpleTimerHandler: TSimpleTimerHandler = nil;
  71.  
  72. {--------------- TSimpleTimerHandler ------------------}
  73.  
  74. constructor TSimpleTimerHandler.Create;
  75. begin
  76.   inherited Create;
  77. {$IFDEF DELPHI_6_UP}
  78.   FWindowHandle := Classes.AllocateHWnd(WndProc);
  79. {$ELSE}
  80.   FWindowHandle := AllocateHWnd(WndProc);
  81. {$ENDIF}
  82. end;
  83.  
  84.  
  85. destructor TSimpleTimerHandler.Destroy;
  86. begin
  87. {$IFDEF DELPHI_6_UP}
  88.   Classes.DeallocateHWnd(FWindowHandle);
  89. {$ELSE}
  90.   DeallocateHWnd(FWindowHandle);
  91. {$ENDIF}
  92.   inherited Destroy;
  93. end;
  94.  
  95.  
  96. procedure TSimpleTimerHandler.AddTimer;
  97. begin
  98.   Inc(RefCount);
  99. end;
  100.  
  101.  
  102. procedure TSimpleTimerHandler.RemoveTimer;
  103. begin
  104.   if RefCount > 0 then
  105.     Dec(RefCount);
  106. end;
  107.  
  108.  
  109. procedure TSimpleTimerHandler.WndProc(var Msg: TMessage);
  110. var
  111.   Timer: TSimpleTimer;
  112. begin
  113.   if Msg.Msg = WM_TIMER then
  114.   begin
  115. {$WARNINGS OFF}
  116.     Timer := TSimpleTimer(Msg.wParam);
  117. {$WARNINGS ON}
  118.     if Assigned(Timer.FCallBackProc) then
  119.       Timer.FCallBackProc(Timer.FOwner);
  120.   end
  121.   else
  122.     Msg.Result := DefWindowProc(FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);
  123. end;
  124.  
  125. {---------------- Container management ----------------}
  126.  
  127. procedure AddTimer;
  128. begin
  129.   if not Assigned(SimpleTimerHandler) then
  130.     // Create new handler
  131.     SimpleTimerHandler := TSimpleTimerHandler.Create;
  132.   SimpleTimerHandler.AddTimer;
  133. end;
  134.  
  135.  
  136. procedure RemoveTimer;
  137. begin
  138.   if Assigned(SimpleTimerHandler) then
  139.   begin
  140.     SimpleTimerHandler.RemoveTimer;
  141.     if SimpleTimerHandler.RefCount = 0 then
  142.     begin
  143.       // Destroy handler
  144.       SimpleTimerHandler.Free;
  145.       SimpleTimerHandler := nil;
  146.     end;
  147.   end;
  148. end;
  149.  
  150. {------------------ Callback method -------------------}
  151. {
  152. procedure TimerProc(hWnd: HWND; uMsg: UINT; idEvent: UINT; dwTime: DWORD); stdcall;
  153. var
  154.   Timer: TSimpleTimer;
  155. begin
  156. //  if uMsg = WM_TIMER then    // It's always WM_TIMER
  157.   begin
  158.     try
  159.       Timer := TSimpleTimer(idEvent);
  160.       if Assigned(Timer.FCallBackProc) then
  161.         Timer.FCallBackProc(Timer.FOwner);
  162.     except
  163.       // ???
  164.     end;
  165.   end;
  166. end;
  167. }
  168. {------------------- TSimpleTimer ---------------------}
  169.  
  170. constructor TSimpleTimer.Create(AOwner: TComponent; CallBackProc: TSimpleTimerCallBackProc);
  171. begin
  172.   inherited Create;
  173.   FOwner := AOwner;
  174. {$WARNINGS OFF}
  175.   FId := UINT(Self);         // Use Self as id in call to SetTimer and callback method
  176. {$WARNINGS ON}
  177.   FCallBackProc := CallBackProc;
  178.   FActive := False;
  179.   AddTimer;                  // Container management
  180. end;
  181.  
  182.  
  183. destructor TSimpleTimer.Destroy;
  184. begin
  185.   if FActive then
  186.     Stop;
  187.   RemoveTimer;               // Container management
  188.   inherited Destroy;
  189. end;
  190.  
  191.  
  192. function TSimpleTimer.Start(MilliSecs: Cardinal): Boolean;
  193. begin
  194.   if FActive then
  195.     Stop;
  196.   FInterval := MilliSecs;
  197. //  Result := (SetTimer(SimpleTimerHandler.FWindowHandle, FId, MilliSecs, @TimerProc) <> 0);
  198.   Result := (SetTimer(SimpleTimerHandler.FWindowHandle, FId, MilliSecs, nil) <> 0);
  199.   if Result then
  200.     FActive := True
  201. {  else
  202.     raise EOutOfResources.Create(SNoTimers); }
  203. end;
  204.  
  205.  
  206. function TSimpleTimer.Stop: Boolean;
  207. begin
  208.   FActive := False;
  209.   Result := KillTimer(SimpleTimerHandler.FWindowHandle, FId);
  210. end;
  211.  
  212.  
  213. initialization
  214.  
  215. finalization
  216.   if Assigned(SimpleTimerHandler) then
  217.   begin
  218.     SimpleTimerHandler.Free;
  219.     SimpleTimerHandler := nil;
  220.   end;
  221.  
  222. end.
  223.  
  224.