zoukankan      html  css  js  c++  java
  • 毫秒级别计时器扩展----------WinForm控件开发系列

    该控件是继承于 Component 基类开发的。主要是利用 winmm.dll  的 timeGetDevCaps  、timeSetEvent  、 timeKillEvent 来完成。

      1     /// <summary>
      2     /// 毫秒级别计时器扩展
      3     /// </summary>
      4     [ToolboxItem(true)]
      5     [Description("毫秒级别计时器扩展")]
      6     [DefaultProperty("Interval")]
      7     [DefaultEvent("Tick")]
      8     public partial class TimerExt : Component
      9     {
     10         #region 新增事件
     11 
     12         private event EventHandler tick;
     13         /// <summary>
     14         /// 计时器间隔引发事件
     15         /// </summary>
     16         public event EventHandler Tick
     17         {
     18             add { this.tick += value; }
     19             remove { this.tick -= value; }
     20         }
     21 
     22         #endregion
     23 
     24         #region 新增属性
     25 
     26         private uint interval = 10;
     27         /// <summary>
     28         ///   获取或设置在相对于上一次发生的Tick 事件引发的时间(以毫秒为单位)。
     29         /// </summary>
     30         [DefaultValue(10)]
     31         [Description("获取或设置在相对于上一次发生的Tick 事件引发的时间(以毫秒为单位)。")]
     32         public uint Interval
     33         {
     34             get
     35             {
     36                 return this.interval;
     37             }
     38             set
     39             {
     40                 if (this.interval == value || value < timecaps.wPeriodMin || value > timecaps.wPeriodMax)
     41                     return;
     42 
     43                 this.interval = value;
     44 
     45                 if (this.Enabled)
     46                 {
     47                     this.ReStart();
     48                 }
     49             }
     50         }
     51 
     52         private bool enabled = false;
     53         /// <summary>
     54         /// 获取或设置计时器是否正在运行。
     55         /// </summary>
     56         [DefaultValue(false)]
     57         [Description("获取或设置计时器是否正在运行。")]
     58         public bool Enabled
     59         {
     60             get
     61             {
     62                 return this.enabled;
     63             }
     64             set
     65             {
     66                 if (this.enabled == value)
     67                     return;
     68 
     69                 if (this.enabled == false)
     70                 {
     71                     this.Start();
     72                 }
     73                 else
     74                 {
     75                     this.Stop();
     76                 }
     77                 this.enabled = value;
     78             }
     79         }
     80 
     81         /// <summary>
     82         /// 计时器分辨率的信息
     83         /// </summary>
     84         [Description("计时器分辨率的信息")]
     85         public TIMECAPS Timecaps
     86         {
     87             get { return TimerExt.timecaps; }
     88         }
     89 
     90         #endregion
     91 
     92         #region 字段
     93 
     94         /// <summary>
     95         /// 计时器分辨率的信息
     96         /// </summary>
     97         private static TIMECAPS timecaps;
     98 
     99         /// <summary>
    100         ///作为fptc参数的函数指针
    101         /// </summary>
    102         private TimerExtCallback timerExtCallback;
    103 
    104         /// <summary>
    105         /// 定期是标识
    106         /// </summary>
    107         private uint timerID;
    108 
    109         #endregion
    110 
    111         #region  扩展
    112 
    113         private delegate void TimerExtCallback(uint uTimerID, uint uMsg, uint dwUser, UIntPtr dw1, UIntPtr dw2); // timeSetEvent所对应的回调函数的签名
    114 
    115         /// <summary>
    116         /// 查询计时器设备以确定其分辨率成功
    117         /// </summary>
    118         private const int TIMERR_NOERROR = 0x0000;
    119 
    120         /// <summary>
    121         /// 当计时器到期时,系统将调用fptc参数指向的函数。
    122         /// </summary>
    123         private const int TIME_CALLBACK_FUNCTION = 0x0001;
    124 
    125         /// <summary>
    126         /// 此结构包含有关计时器分辨率的信息。单位是ms
    127         /// </summary>
    128         [Description("此结构包含有关计时器分辨率的信息。单位是ms")]
    129         [StructLayout(LayoutKind.Sequential)]
    130         public struct TIMECAPS
    131         {
    132             /// <summary>
    133             /// 支持的最小期限。
    134             /// </summary>
    135             [Description("支持的最小期限")]
    136             public uint wPeriodMin;
    137             /// <summary>
    138             /// 支持的最大期限。
    139             /// </summary>
    140             [Description("支持的最大期限")]
    141             public uint wPeriodMax;
    142         }
    143 
    144         /// <summary>
    145         /// 此函数启动指定的计时器事件。
    146         /// </summary>
    147         /// <param name="uDelay">事件延迟,以毫秒为单位。如果该值不在计时器支持的最小和最大事件延迟范围内,则该函数返回错误。</param>
    148         /// <param name="uResolution">计时器事件的分辨率,以毫秒为单位。分辨率越高,分辨率越高;零分辨率表示周期性事件应该以最大可能的精度发生。但是,为减少系统开销,应使用适合您的应用程序的最大值。</param>
    149         /// <param name="fptc">如果fuEvent指定TIME_CALLBACK_EVENT_SET或TIME_CALLBACK_EVENT_PULSE标志,则fptc参数将解释为事件对象的句柄。事件将在单个事件完成时设置或发出脉冲,或者在周期性事件完成时定期设置或触发。对于fuEvent的任何其他值,fptc参数将被解释为函数指针。</param>
    150         /// <param name="dwUser">用户提供的回调数据。</param>
    151         /// <param name="fuEvent">计时器事件类型。下表显示了fuEvent参数可以包含的值。</param>
    152         /// <returns></returns>
    153         [DllImport("winmm.dll")]
    154         private static extern uint timeSetEvent(uint uDelay, uint uResolution, TimerExtCallback fptc, uint dwUser, uint fuEvent);
    155 
    156         /// <summary>
    157         /// 此功能取消指定的计时器事件。
    158         /// </summary>
    159         /// <param name="id">要取消的计时器事件的标识符。此标识符由timeSetEvent函数返回,该函数启动指定的计时器事件。</param>
    160         /// <returns></returns>
    161         [DllImport("winmm.dll")]
    162         private static extern uint timeKillEvent(uint uTimerID);
    163 
    164         /// <summary>
    165         /// 此函数查询计时器设备以确定其分辨率。
    166         /// </summary>
    167         /// <param name="ptc">指向TIMECAPS结构的指针。该结构充满了有关计时器设备分辨率的信息。</param>
    168         /// <param name="cbtc">TIMECAPS结构的大小(以字节为单位)。</param>
    169         /// <returns>如果成功,则返回TIMERR_NOERROR,如果未能返回计时器设备功能,则返回TIMERR_STRUCT。</returns>
    170         [DllImport("winmm.dll")]
    171         private static extern uint timeGetDevCaps(ref TIMECAPS ptc, int cbtc);
    172 
    173         #endregion
    174 
    175         static TimerExt()
    176         {
    177             uint result = timeGetDevCaps(ref timecaps, Marshal.SizeOf(timecaps));
    178             if (result != TIMERR_NOERROR)
    179             {
    180                 throw new Exception("timeGetDevCaps失败");
    181             }
    182         }
    183 
    184         public TimerExt()
    185         {
    186             this.timerExtCallback = new TimerExtCallback(this.TimerExtCallbackFun);
    187             InitializeComponent();
    188         }
    189 
    190         public TimerExt(IContainer container)
    191         {
    192             this.timerExtCallback = new TimerExtCallback(this.TimerExtCallbackFun);
    193 
    194             container.Add(this);
    195             InitializeComponent();
    196         }
    197 
    198         #region 重写
    199 
    200         /// <summary> 
    201         /// 清理所有正在使用的资源。
    202         /// </summary>
    203         /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
    204         protected override void Dispose(bool disposing)
    205         {
    206             if (disposing && (components != null))
    207             {
    208                 components.Dispose();
    209             }
    210 
    211             if (this.timerID != 0)
    212             {
    213                 timeKillEvent(this.timerID);
    214                 this.timerID = 0;
    215             }
    216             base.Dispose(disposing);
    217         }
    218 
    219         #endregion
    220 
    221         #region 公开方法
    222 
    223         /// <summary>
    224         /// 启动定时器
    225         /// </summary>
    226         public void Start()
    227         {
    228             if (!this.Enabled)
    229             {
    230                 uint result = timeSetEvent(this.interval, Math.Min(1, timecaps.wPeriodMin), this.timerExtCallback, 0, TIME_CALLBACK_FUNCTION); // 间隔性地运行
    231                 if (result == 0)
    232                 {
    233                     throw new Exception("timeSetEvent启动计时器失败");
    234                 }
    235                 this.enabled = true;
    236                 this.timerID = result;
    237             }
    238         }
    239 
    240         /// <summary>
    241         /// 重新开始定时器
    242         /// </summary>
    243         public void ReStart()
    244         {
    245             this.Stop();
    246             this.Start();
    247         }
    248 
    249         /// <summary>
    250         /// 暂停定时器
    251         /// </summary>
    252         public void Stop()
    253         {
    254             if (this.Enabled)
    255             {
    256                 timeKillEvent(this.timerID);
    257                 this.enabled = false;
    258             }
    259         }
    260 
    261         #endregion
    262 
    263         #region 私有方法
    264 
    265         private void TimerExtCallbackFun(uint uTimerID, uint uMsg, uint dwUser, UIntPtr dw1, UIntPtr dw2)
    266         {
    267             if (this.tick != null)
    268             {
    269                 this.tick(this, null);
    270             }
    271         }
    272 
    273         #endregion
    274 
    275     }

    控件库的源码已整体发布到gitee,下载地址:(花木兰控件库)https://gitee.com/tlmbem/hml

  • 相关阅读:
    利用ajax.dll类库文件实现无刷新
    给input的按钮控件添加onserverclick事件
    wpf datagrid 如何让标头 及内容居中
    MVC中Url请求与控制器的默认约定
    ASP.NET MVC中实现多个按钮提交的几种方法
    default(T)的含义
    MVC中Html.Listbox的用法实例
    编写高质量代码改善C#程序的157个建议——建议101:使用扩展方法,向现有类型“添加”方法
    编写高质量代码改善C#程序的157个建议——建议100:静态方法和实例方法没有区别
    编写高质量代码改善C#程序的157个建议——建议99:重写时不应使用子类参数
  • 原文地址:https://www.cnblogs.com/tlmbem/p/13276333.html
Copyright © 2011-2022 走看看