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

Delphi控件源码

开发平台:

Delphi

  1. {========================================================================}
  2. {=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
  3. {========================================================================}
  4. {=                          All Rights Reserved                         =}
  5. {========================================================================}
  6. {=  D 01099 Dresden             = Tel.: +0351-8012255                   =}
  7. {=  Loewenstr.7a                = info@swiftsoft.de                     =}
  8. {========================================================================}
  9. {=  Actual versions on http://www.swiftsoft.de/mmtools.html             =}
  10. {========================================================================}
  11. {=  This code is for reference purposes only and may not be copied or   =}
  12. {=  distributed in any format electronic or otherwise except one copy   =}
  13. {=  for backup purposes.                                                =}
  14. {=                                                                      =}
  15. {=  No Delphi Component Kit or Component individually or in a collection=}
  16. {=  subclassed or otherwise from the code in this unit, or associated   =}
  17. {=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
  18. {=  without express permission from SwiftSoft.                          =}
  19. {=                                                                      =}
  20. {=  For more licence informations please refer to the associated        =}
  21. {=  HelpFile.                                                           =}
  22. {========================================================================}
  23. {=  $Date: 20.01.1998 - 18:00:00 $                                      =}
  24. {========================================================================}
  25. unit MMLTimer;
  26. {$C FIXED PRELOAD PERMANENT}
  27. {$I COMPILER.INC}
  28. interface
  29. uses
  30. {$IFDEF WIN32}
  31.     Windows,
  32. {$ELSE}
  33.     WinTypes,
  34.     WinProcs,
  35. {$ENDIF}
  36.     SysUtils,
  37.     Messages,
  38.     Classes,
  39.     Controls,
  40.     Forms,
  41.     MMObj,
  42.     MMUtils,
  43.     MMString;
  44. type
  45.     {-- TMMLongTimer ------------------------------------------------------}
  46.     TMMLongTimer = class(TMMNonVisualComponent)
  47.     private
  48.       FEnabled : Boolean;
  49.       FInterval: Longint;
  50.       FCounter : Longint;
  51.       FOnTimer : TNotifyEvent;
  52.       procedure SetEnabled(aValue: Boolean);
  53.       procedure SetInterval(aValue: Longint);
  54.       procedure SetOnTimer(aValue: TNotifyEvent);
  55.     protected
  56.       procedure Timer; dynamic;
  57.     public
  58.       constructor Create(AOwner: TComponent); override;
  59.       destructor Destroy; override;
  60.     published
  61.       property Enabled: Boolean read FEnabled write SetEnabled default True;
  62.       property Interval: Longint read FInterval write SetInterval default 1;
  63.       property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
  64.     end;
  65. implementation
  66. uses Consts,MMSystem;
  67. type
  68.    PTimerRec = ^TTimerRec;
  69.    TTimerRec = record
  70.      TimerID    : Longint;
  71.      TimerCount : Longint;
  72.      CBHandle   : THandle;
  73.      ControlList: TList;
  74.    end;
  75. const
  76.    lpTimerRec : PTimerRec = nil;
  77. {-- TimeCallBack -------------------------------------------------------}
  78. procedure TimeCallBack(uTimerID, uMessage: UINT; dwUser, dw1, dw2: Longint);
  79. export;{$IFDEF WIN32}stdcall;{$ENDIF}
  80. var
  81.    i: integer;
  82. begin
  83.    if (dwUser <> 0) then
  84.    with PTimerRec(dwUser)^ do
  85.    begin
  86.       if (ControlList.Count > 0) then
  87.       for i := 0 to ControlList.Count-1 do
  88.       with TMMLongTimer(ControlList.Items[i]) do
  89.       begin
  90.          if (FInterval <> 0) and FEnabled and assigned(FOnTimer) then
  91.          begin
  92.            inc(FCounter);
  93.            if (FCounter = FInterval) then
  94.            begin
  95.               FCounter := 0;
  96.               PostMessage(CBHandle,MM_TIMER,TimerID,Longint(ControlList.Items[i]));
  97.            end;
  98.         end;
  99.       end;
  100.    end;
  101. end;
  102. {------------------------------------------------------------------------}
  103. function TimerWndProc(Window: HWND; Message, wParam: UINT; lParam: Longint): Longint;
  104. export;{$IFDEF WIN32}stdcall;{$ENDIF}
  105. begin
  106.    if (lpTimerRec <> nil) and (lpTimerRec^.ControlList <> nil) then
  107.    with lpTimerRec^ do
  108.    begin
  109.       if (Message = MM_TIMER) and (wParam = TimerID) and (ControlList.Count > 0) then
  110.       with ControlList do
  111.       begin
  112.          if (IndexOf(Pointer(lParam)) <> -1) then
  113.          try
  114.             TMMLongTimer(lParam).Timer;
  115.          except
  116.             Application.HandleException(nil);
  117.          end;
  118.       end
  119.       else Result := DefWindowProc(Window, Message, wParam, lParam);
  120.    end;
  121. end;
  122. const
  123.   TMMTimerWindowClass: TWndClass = (
  124.     style: 0;
  125.     lpfnWndProc: @TimerWndProc;
  126.     cbClsExtra: 0;
  127.     cbWndExtra: 0;
  128.     hInstance: 0;
  129.     hIcon: 0;
  130.     hCursor: 0;
  131.     hbrBackground: 0;
  132.     lpszMenuName: nil;
  133.     lpszClassName: 'TMMLongTimerWindow');
  134. {------------------------------------------------------------------------}
  135. function AllocateTimerWindow: HWND;
  136. var
  137.    TempClass: TWndClass;
  138.    ClassRegistered: Boolean;
  139. begin
  140.    TMMTimerWindowClass.hInstance := HInstance;
  141.    ClassRegistered := GetClassInfo(HInstance,
  142.                       TMMTimerWindowClass.lpszClassName, TempClass);
  143.     if not ClassRegistered or (TempClass.lpfnWndProc <> @TimerWndProc) then
  144.     begin
  145.        {$IFDEF WIN32}
  146.        if ClassRegistered then
  147.           Windows.UnregisterClass(TMMTimerWindowClass.lpszClassName, HInstance);
  148.        Windows.RegisterClass(TMMTimerWindowClass);
  149.        {$ELSE}
  150.        if ClassRegistered then
  151.           WinProcs.UnregisterClass(TMMTimerWindowClass.lpszClassName, HInstance);
  152.        WinProcs.RegisterClass(TMMTimerWindowClass);
  153.        {$ENDIF}
  154.     end;
  155.     Result := CreateWindow(TMMTimerWindowClass.lpszClassName, '', 0,
  156.                            0, 0, 0, 0, 0, 0, HInstance, nil);
  157. end;
  158. {------------------------------------------------------------------------}
  159. procedure UpdateTimer(Enabled: Boolean);
  160. {$IFNDEF WIN32}
  161. var
  162.    TimeCB: TTimeCallBack;
  163. {$ENDIF}
  164. begin
  165.    if (lpTimerRec <> nil) then
  166.    with lpTimerRec^ do
  167.    begin
  168.       if (TimerID <> 0) then
  169.       begin
  170.          TimeKillEvent(TimerID);
  171.          TimerID := 0;
  172.       end;
  173.       if Enabled then
  174.       begin
  175.          {$IFDEF WIN32}
  176.          TimerID := TimeSetEvent(1000, 1000, @TimeCallBack, Longint(lpTimerRec), TIME_PERIODIC);
  177.          if (TimerID = 0) then
  178.             raise EOutOfResources.Create({$IFDEF DELPHI3}SNoTimers{$ELSE}LoadStr(SNoTimers){$ENDIF});
  179.          {$ELSE}
  180.          TimeCB := TimeCallBack;
  181.          TimerID := TimeSetEvent(1000, 1000, TimeCB, Longint(lpTimerRec), TIME_PERIODIC);
  182.          if (TimerID = 0) then
  183.             raise EOutOfResources.Create(LoadStr(SNoTimers));
  184.          {$ENDIF}
  185.       end;
  186.    end;
  187. end;
  188. {------------------------------------------------------------------------}
  189. procedure AddTimer(Timer: TMMLongTimer);
  190. begin
  191.    if (lpTimerRec = nil) then
  192.    begin
  193.       lpTimerRec := GlobalAllocPtr(GPTR,sizeOf(TTimerRec));
  194.       lpTimerRec^.TimerCount := 0;
  195.       lpTimerRec^.ControlList := TList.Create;
  196.       lpTimerRec^.CBHandle := AllocateTimerWindow;
  197.       UpdateTimer(True);
  198.    end;
  199.    if (lpTimerRec^.ControlList.IndexOf(Timer) = -1) then
  200.    begin
  201.       lpTimerRec^.ControlList.Add(Timer);
  202.       inc(lpTimerRec^.TimerCount);
  203.    end;
  204. end;
  205. {------------------------------------------------------------------------}
  206. procedure RemoveTimer(Timer: TMMLongTimer);
  207. begin
  208.    if (lpTimerRec <> nil) then
  209.    begin
  210.       lpTimerRec^.ControlList.Remove(Timer);
  211.       lpTimerRec^.ControlList.Pack;
  212.       dec(lpTimerRec^.TimerCount);
  213.       if (lpTimerRec^.TimerCount = 0) then
  214.       begin
  215.          UpdateTimer(False);
  216.          lpTimerRec^.ControlList.Free;
  217.          lpTimerRec^.ControlList := nil;
  218.          DestroyWindow(lpTimerRec^.CBHandle);
  219.          GlobalFreePtr(lpTimerRec);
  220.          lpTimerRec := nil;
  221.       end;
  222.    end;
  223. end;
  224. {-- TMMLongTimer ---------------------------------------------------------}
  225. constructor TMMLongTimer.Create(AOwner: TComponent);
  226. begin
  227.   inherited Create(AOwner);
  228.   FEnabled := True;
  229.   FInterval := 1;
  230.   FCounter := 0;
  231.   ErrorCode := ComponentRegistered(InitCode, Self, ClassName);
  232.   if (ErrorCode <> 0) then RegisterFailed(InitCode, Self , ClassName);
  233. end;
  234. {-- TMMLongTimer ---------------------------------------------------------}
  235. destructor TMMLongTimer.Destroy;
  236. begin
  237.    Enabled := False;
  238.    inherited Destroy;
  239. end;
  240. {-- TMMLongTimer ---------------------------------------------------------}
  241. procedure TMMLongTimer.SetEnabled(aValue: Boolean);
  242. begin
  243.   if (aValue <> FEnabled) then
  244.   begin
  245.     FEnabled := aValue;
  246.     FCounter := 0;
  247.     if FEnabled then
  248.        AddTimer(Self)
  249.     else
  250.        RemoveTimer(Self);
  251.   end;
  252.   {$IFDEF WIN32}
  253.   {$IFDEF TRIAL}
  254.   {$DEFINE _HACK1}
  255.   {$I MMHACK.INC}
  256.   {$ENDIF}
  257.   {$ENDIF}
  258. end;
  259. {-- TMMLongTimer ---------------------------------------------------------}
  260. procedure TMMLongTimer.SetInterval(aValue: Longint);
  261. begin
  262.   if (aValue <> FInterval) then
  263.   begin
  264.     FInterval := aValue;
  265.     FCounter := 0;
  266.   end;
  267.   {$IFDEF WIN32}
  268.   {$IFDEF TRIAL}
  269.   {$DEFINE _HACK2}
  270.   {$I MMHACK.INC}
  271.   {$ENDIF}
  272.   {$ENDIF}
  273. end;
  274. {-- TMMLongTimer ---------------------------------------------------------}
  275. procedure TMMLongTimer.SetOnTimer(aValue: TNotifyEvent);
  276. begin
  277.   FOnTimer := aValue;
  278.   FCounter := 0;
  279. end;
  280. {-- TMMLongTimer ---------------------------------------------------------}
  281. procedure TMMLongTimer.Timer;
  282. begin
  283.   if Assigned(FOnTimer) then FOnTimer(Self);
  284. end;
  285. end.