Delphi - TTimer的源码
技术交流,DH讲解.
我之前用一个线程实现了Timer的功能,现在我们来看看Delphi自带的Timer怎么实现的?
其实,不看代码也大致知道怎么的?
1 SetTimer 和 KillTimer 2个API来控制Timer的启动和关闭
2 响应WM_Timer消息执行用户事件.
由于Timer是一个不可视控件,应该从TComponent继承,但是TComponent不具备处理消息的能力,也就是我们需要手动创建窗体过程然后分配给它.
好说了这么多,看代码:
TTimer = class(TComponent)
private
//间隔时间
FInterval: Cardinal;
//接收消息的句柄
FWindowHandle: HWND;
//用户事件
FOnTimer: TNotifyEvent;
FEnabled: Boolean;
//当属性设置后,更新计时器
//kill掉已有的,然后创建新的
procedure UpdateTimer;
//Setter
procedure SetEnabled(Value: Boolean);
procedure SetInterval(Value: Cardinal);
procedure SetOnTimer(Value: TNotifyEvent);
//窗体过程
procedure WndProc(var Msg: TMessage);
protected
procedure Timer; dynamic;
{$IF DEFINED(CLR)}
strict protected
procedure Finalize; override;
{$IFEND}
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Enabled: Boolean read FEnabled write SetEnabled default True;
property Interval: Cardinal read FInterval write SetInterval default 1000;
property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
end;
procedure TTimer.UpdateTimer; begin if FWindowHandle <> 0 then KillTimer(FWindowHandle, 1); if (FInterval <> 0) and FEnabled and Assigned(FOnTimer) then begin if FWindowHandle = 0 then //分配句柄处理消息 FWindowHandle := AllocateHWnd(WndProc); if SetTimer(FWindowHandle, 1, FInterval, nil) = 0 then raise EOutOfResources.Create(SNoTimers); end else if FWindowHandle <> 0 then begin DeallocateHWnd(FWindowHandle); //取消句柄处理消息 FWindowHandle := 0; end; end;
procedure TTimer.WndProc(var Msg: TMessage); begin with Msg do if Msg = WM_TIMER then try Timer; except Application.HandleException(Self); end else//其他消息,采用默认的windows处理方式 Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam); end;
procedure TTimer.Timer; begin if Assigned(FOnTimer) then FOnTimer(Self); end;
也很简单嘛,主要让大家看看控件怎么编写的.
我是DH
浙公网安备 33010602011771号