ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

毫秒级别计时器扩展----------WinForm控件开发系列

2020-07-09 21:42:44  阅读:294  来源: 互联网

标签:控件 分辨率 private 计时器 事件 uint public 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     }

源码下载:毫秒级别计时器扩展.zip

标签:控件,分辨率,private,计时器,事件,uint,public,WinForm
来源: https://www.cnblogs.com/tlmbem/p/13276333.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有