zoukankan      html  css  js  c++  java
  • 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;
    我们就看关键的方法UpdateTimer和WndProc窗体过程.
    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;
    这个有个timer方法,干什么的呢?对了,就是执行用户事件的.
    procedure TTimer.Timer;
    begin
      if Assigned(FOnTimer) then FOnTimer(Self);
    end;

    也很简单嘛,主要让大家看看控件怎么编写的.

    我是DH

  • 相关阅读:
    很简单的在Ubuntu系统下安装字体和切换默认字体的方法
    Qt添加驱动——Qt数据库之添加MySQL驱动插件
    qt 字体的相关问题
    qt configure参数配置介绍
    Qt封装QTcpServer参考资料--QT4中构建多线程的服务器
    Qt封装QTcpServer参考资料--QTcpServer多线程实现
    Qt封装QTcpServer参考资料--QT自带QTcpServer架构分析
    Qt Creator设置多核编译(-j8参数)
    QString::​arg的用法
    《Qt数据类型》--QByteArray,QString,int,hex之间的转化
  • 原文地址:https://www.cnblogs.com/huangjacky/p/1677254.html
Copyright © 2011-2022 走看看