李朝强的博客

人之为学,如饮河海,大饮则大盈,小饮则小颖!
随笔 - 39, 文章 - 2, 评论 - 187, 阅读 - 19万
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

GDI绘制时钟效果,与系统时间保持同步,基于Winform

Posted on   李朝强  阅读(1653)  评论(1编辑  收藏  举报

      2018年工作之余,想起来捡起GDI方面的技术,特意在RichCodeBox项目中做了两个示例程序,其中一个就是时钟效果,纯C#开发。这个CSharpQuartz是今天上午抽出一些时间,编写的,算是偷得浮生半日休闲吧。先来看看效果图吧:

这是直接在Winform的基础上进行绘制的。接下来,我对时钟进行了封装,封装成一个名为CSharpQuartz的类,效果如下:

这是把时钟封装后,实现的一种效果,CSharpQuartz内部开辟了一个线程,与系统时间,保持同步,每秒刷新一次。所采用的技术也就是GDI和多线程及事件委托。把时钟封装成对象后,还为其添加了OnChanged事件,用于对象提供外部

处理之用。接下来就简单的说下,做次小程序的一些准备工作吧。

           这也是最近偶尔听到有朋友问怎样做时钟的事,想来,其实也简单的,只是需要一些耐心和细心,这里主要还利用一些三角函数进行计算。上图看似很简单,其实也有很多小细节需要注意。我就把大致绘制的过程简单说下:

          首先,我们需要定义一个圆,来作为时钟的轮廓,这里是通过设置时钟的直径及winform的宽高,来计算出时钟在窗体居中的位置。绘制圆的代码就更简单了

1
2
3
4
5
6
7
8
float w = 300f, h = 300f;
float x = (this.Width - w) / 2;
float y = (this.Height - h) / 2;
 
float d = w;//直径
float r = d / 2;//半径
 
graphics.DrawEllipse(pen, new RectangleF(x, y, w, h));//绘制圆

   接下来,我们需要计算圆的一周遍布的12个时间点。然后把这些时间点和圆心连在一起,就形成了上图我们看到的不同时间点的线段。圆心的查找非常简单,圆心的坐标点,其实就是x轴+半径r,y轴+半径r:

1
PointF pointEclipse = new PointF(x + r, y + r);

  开始分表绘制12个点与圆心的连线,我这里是以9点为起点,此时,脑海中呈现这样的画面

时针一圈12格,每格也就是 Math.PI/6

比如我们计算10点在圆上的坐标P10.

10点所在的点,与x轴的夹角呈30度。那么10点在x上的坐标应该是,x1=x+r-r*Cos(30),以此类推,不难求出12个点的位置,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/// <summary>
/// <![CDATA[画时刻线 这里是以9点这个时间坐标为起点 进行360度]]>
/// </summary>
/// <param name="graphics"><![CDATA[画布]]></param>
/// <param name="x"><![CDATA[圆x坐标]]></param>
/// <param name="y"><![CDATA[圆y坐标]]></param>
/// <param name="r"><![CDATA[圆x坐标]]></param>
private void DrawQuartzLine(Graphics graphics, float x, float y, float r)
{
    //圆心
    PointF pointEclipse = new PointF(x + r, y + r);
    float labelX, labelY;//文本坐标
    float angle = Convert.ToSingle(Math.PI / 6);//角度 30度
    Font font = new Font(FontFamily.GenericSerif, 12);
    float _x, _y;//圆上的坐标点
    using (Brush brush = new System.Drawing.SolidBrush(Color.Red))
    {
        using (Pen pen = new Pen(Color.Black, 0.6f))
        {
            //一天12H,将圆分为12份 
            for (int i = 0; i <= 11; i++)
            {
                PointF p10;//圆周上的点
                float pAngle = angle * i;
                float x1, y1;
 
                //三、四象限
                if (pAngle > Math.PI)
                {
                    if ((pAngle - Math.PI) > Math.PI / 2)//钝角大于90度 
                    {
                        //第三象限
                        x1 = Convert.ToSingle(r * Math.Cos(Math.PI * 2 - pAngle));
                        y1 = Convert.ToSingle(r * Math.Sin(Math.PI * 2 - pAngle));
                        _x = x + r - x1;
                        _y = y + r + y1;
                        labelX = _x - 8;
                        labelY = _y;
                    }
                    else
                    {
                        //第四象限
                        x1 = Convert.ToSingle(r * Math.Cos(pAngle - Math.PI));
                        y1 = Convert.ToSingle(r * Math.Sin(pAngle - Math.PI));
                        _x = x + r + x1;
                        _y = y + r + y1;
                        labelX = _x;
                        labelY = _y;
                    }
                }
                //一、二象限
                else if (pAngle > Math.PI / 2)//钝角大于90度
                {
                    //第一象限
                    x1 = Convert.ToSingle(r * Math.Cos(Math.PI - pAngle));
                    y1 = Convert.ToSingle(r * Math.Sin(Math.PI - pAngle));
                    _x = x + r + x1;
                    _y = y + r - y1;
                    labelX = _x;
                    labelY = _y - 20;
                }
                else
                {
                    //第二象限
                    x1 = Convert.ToSingle(r * Math.Cos(pAngle));
                    y1 = Convert.ToSingle(r * Math.Sin(pAngle));
                    _x = x + r - x1;
                    _y = y + r - y1;
                    labelX = _x - 15;
                    labelY = _y - 20;
                }
                //上半圆 分成12份,每份 30度
                if (i + 9 > 12)
                {
                    graphics.DrawString((i + 9 - 12).ToString(), font, brush, labelX, labelY);
                }
                else
                {
                    if (i + 9 == 9)
                    {
                        labelX = x - 13;
                        labelY = y + r - 6;
                    }
                    graphics.DrawString((i + 9).ToString(), font, brush, labelX, labelY);
                }
                p10 = new PointF(_x, _y);
                graphics.DrawLine(pen, pointEclipse, p10);
            }
        }
    }
}

  为了辅助计算,我又添加了x轴与y轴的线,就是我们在效果图中看到的垂直于水平两条线段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/// <summary>
/// <![CDATA[绘制象限]]>
/// </summary>
/// <param name="graphics"><![CDATA[画布]]></param>
/// <param name="x"><![CDATA[圆x坐标]]></param>
/// <param name="y"><![CDATA[圆y坐标]]></param>
/// <param name="r"><![CDATA[圆半径]]></param>
private void DrawQuadrant(Graphics graphics, float x, float y, float r)
{
    float w = r * 2;
    float extend = 100f;
    using (Pen pen = new Pen(Color.Black, 1))
    {
        #region  绘制象限
        PointF point1 = new PointF(x - extend, y + r);//
        PointF point2 = new PointF(x + w + extend, y + r);
 
        PointF point3 = new PointF(x + r, y - extend);//
        PointF point4 = new PointF(x + r, y + w + extend);
 
        graphics.DrawLine(pen, point1, point2);
 
        graphics.DrawLine(pen, point3, point4);
        #endregion 绘制象限
    }
 
}

  接下来,该绘制指针(时、分、秒),就是我们效果图中看到的,红绿蓝,三条长短不一的线段,秒针最长,这是和本地系统时间同步,所以要根据当前时间,计算出指针所在的位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/// <summary>
/// <![CDATA[绘制时、分、秒针]]>
/// </summary>
/// <param name="graphics"><![CDATA[画布]]></param>
/// <param name="x"><![CDATA[圆x坐标]]></param>
/// <param name="y"><![CDATA[圆y坐标]]></param>
/// <param name="r"><![CDATA[圆半径]]></param>
private void DrawQuartzShot(Graphics graphics, float x, float y, float r)
{
    if (this.IsHandleCreated)
    {
        this.Invoke(new Action(() =>
        {
            //当前时间
            DateTime dtNow = DateTime.Now;
            int h = dtNow.Hour;
            int m = dtNow.Minute;
            int s = dtNow.Second;
            float ha = Convert.ToSingle(Math.PI * 2 / 12);//每小时所弧度 360/12格=30
            float hm = Convert.ToSingle(Math.PI * 2 / 60);
            float hs = Convert.ToSingle(Math.PI * 2 / 60);
            float x1, y1, offset = 60f;
            using (Pen pen = new Pen(Color.Green, 4))
            {
                //时针
                h = h >= 12 ? h - 12 : h;
                double angle = h * ha;//当前时针所占弧度
                x1 = x + r + Convert.ToSingle(Math.Sin(angle) * (r - offset));//通过调整offset的大小,可以控制时针的长短
                y1 = y + r - Convert.ToSingle(Math.Cos(angle) * (r - offset));
                //圆心
                PointF pointEclipse = new PointF(x + r, y + r);
                PointF pointEnd = new PointF(x1, y1);
 
                graphics.DrawLine(pen, pointEclipse, pointEnd);//画45度角
 
                //分针
                using (Pen penYellow = new Pen(Color.Red, 2))
                {
                    offset = 30;
                    //分
                    double angelMinutes = hm * m;//每分钟弧度
                    x1 = x + r + Convert.ToSingle(Math.Sin(angelMinutes) * (r - offset));//通过调整offset的大小,可以控制时针的长短
                    y1 = y + r - Convert.ToSingle(Math.Cos(angelMinutes) * (r - offset));
                    graphics.DrawLine(penYellow, pointEclipse, new PointF(x1, y1));//画45度角
                }
 
                //秒针
                using (Pen penYellow = new Pen(Color.Blue, 2))
                {
                    offset = 20;
                    //分
                    double angelSeconds = hs * s;//每秒钟弧度
                    x1 = x + r + Convert.ToSingle(Math.Sin(angelSeconds) * (r - offset));//通过调整offset的大小,可以控制时针的长短
                    y1 = y + r - Convert.ToSingle(Math.Cos(angelSeconds) * (r - offset));
                    graphics.DrawLine(penYellow, pointEclipse, new PointF(x1, y1));//画45度角
                }
 
            }
 
            this.lblTime.Text = string.Format("当前时间:{0}:{1}:{2}", h, m, s);
        }));
 
    }
}

  最后,开辟一个线程,来同步更新时针的状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Quartz_Load(object sender, EventArgs e)
{
    timer = new Thread(() =>
    {
        if (_graphics == null)
        {
            _graphics = this.CreateGraphics();
            _graphics.SmoothingMode = SmoothingMode.HighQuality; //高质量
            _graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移质量
        }
        while (true)
        {
            _graphics.Clear(this.BackColor);
            DrawCaller(_graphics);
            System.Threading.Thread.Sleep(1000);
        }
    });
    timer.IsBackground = true;
}

  每秒钟,更新一次,其实就是重绘。

      完成了以上几个步骤,我们就完成GDI绘制时钟的工作,后来,把它封装成一个名为CSharpQuartz的对象,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
 
/*=================================================================================================
*
* Title:C#开发的简易时钟
* Author:李朝强
* Description:模块描述
* CreatedBy:lichaoqiang.com
* CreatedOn:
* ModifyBy:暂无...
* ModifyOn:
* Company:河南天一文化传播股份有限公司
* Blog:http://www.lichaoqiang.com
* Mark:
*
*** ================================================================================================*/
namespace WinformGDIEvent.Sample
{
 
    /// <summary>
    /// <![CDATA[CSharpQuarz GDI时钟]]>
    /// </summary>
    public class CSharpQuartz : IDisposable
    {
 
        /// <summary>
        /// 定时器
        /// </summary>
        private Thread timer = null;
 
        /// <summary>
        /// X坐标
        /// </summary>
        public float X { get; private set; }
 
        /// <summary>
        /// Y坐标
        /// </summary>
        public float Y { get; private set; }
 
        /// <summary>
        /// 半径
        /// </summary>
        private float r;
 
        /// <summary>
        /// 画布
        /// </summary>
        private Graphics Graphics = null;
 
        /// <summary>
        /// 直径
        /// </summary>
        public float Diameter { get; private set; }
 
        /// <summary>
        ///
        /// </summary>
        public Form CurrentWinform { get; private set; }
 
 
        /// <summary>
        ///
        /// </summary>
        private EventHandler _OnChanged;
 
        /// <summary>
        /// 事件,时钟状态更新后,当前频次1秒钟
        /// </summary>
        public event EventHandler OnChanged
        {
            add
            {
                this._OnChanged += value;
            }
            remove
            {
                this._OnChanged -= value;
            }
        }
 
 
        /// <summary>
        /// 构造函数
        /// </summary>
        CSharpQuartz()
        {
            //
            timer = new Thread((() =>
            {
                if (Graphics == null)
                {
                    Graphics = CurrentWinform.CreateGraphics();//创建画布
                    Graphics.SmoothingMode = SmoothingMode.HighQuality; //高质量
                    Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移质量
                }
                while (true)
                {
                    //清除画布颜色,以窗体底色填充
                    Graphics.Clear(CurrentWinform.BackColor);
                    DrawCaller();//绘制时钟
                    //事件
                    if (_OnChanged != null) _OnChanged(this, null);
                    System.Threading.Thread.Sleep(1000);
                }
            }));
            timer.IsBackground = true;
        }
 
        /// <summary>
        /// <![CDATA[构造函数]]>
        /// </summary>
        /// <param name="x"><![CDATA[圆x坐标]]></param>
        /// <param name="y"><![CDATA[圆y坐标]]></param>
        /// <param name="d"><![CDATA[圆直径]]></param>
        public CSharpQuartz(Form form, float x, float y, float d)
            : this()
        {
            this.CurrentWinform = form;
            this.X = x;
            this.Y = y;
            this.Diameter = d;
            r = d / 2;
        }
 
 
        /// <summary>
        ///
        /// </summary>
        public void Start()
        {
            if (timer.IsAlive == false) timer.Start();//启动工作线程
        }
 
        /// <summary>
        /// 终止
        /// </summary>
        public void Stop()
        {
            if (timer.IsAlive == true) timer.Abort();//终止工作线程
        }
 
        /// <summary>
        /// <![CDATA[调用绘图]]>
        /// </summary>
        private void DrawCaller()
        {
            Graphics.SmoothingMode = SmoothingMode.HighQuality; //高质量
            Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移质量
            using (Pen pen = new Pen(Color.Red, 2))
            {
                if (this.CurrentWinform.IsHandleCreated)
                {
                    this.CurrentWinform.Invoke(new Action(() =>
                    {
                        //绘制圆
                        Graphics.DrawEllipse(pen, new RectangleF(X, Y, Diameter, Diameter));
 
                        //绘制象限
                        DrawQuadrant();
 
                        //绘制时、分、秒等针
                        DrawQuartzShot();
 
                        //绘制时刻线
                        DrawQuartzLine();
 
                        //写入版本信息
                        WriteVersion();
                    }));
                }
            }
        }
 
 
        /// <summary>
        /// <![CDATA[绘制象限]]>
        /// </summary>
        private void DrawQuadrant()
        {
            #region  绘制象限
            float w = Diameter;
            float extend = 100f;
            using (Pen pen = new Pen(Color.Black, 1))
            {
 
                PointF point1 = new PointF(X - extend, Y + r);//
                PointF point2 = new PointF(X + w + extend, Y + r);
 
                PointF point3 = new PointF(X + r, Y - extend);//
                PointF point4 = new PointF(X + r, Y + w + extend);
 
                Graphics.DrawLine(pen, point1, point2);
 
                Graphics.DrawLine(pen, point3, point4);
 
            }
            #endregion 绘制象限
        }
 
 
        /// <summary>
        /// <![CDATA[绘制时、分、秒针]]>
        /// </summary>
        private void DrawQuartzShot()
        {
            //当前时间
            DateTime dtNow = DateTime.Now;
            int h = dtNow.Hour;
            int m = dtNow.Minute;
            int s = dtNow.Second;
            float ha = Convert.ToSingle(Math.PI * 2 / 12);//每小时所弧度 360/12格=30
            float radian = Convert.ToSingle(Math.PI * 2 / 60);//分秒偏移弧度
            float x1, y1, offset = 60f;
            using (Pen pen = new Pen(Color.Green, 4))
            {
                //时针
                h = h >= 12 ? h - 12 : h;
                double angle = h * ha;//当前时针所占弧度
                x1 = X + r + Convert.ToSingle(Math.Sin(angle) * (r - offset));//通过调整offset的大小,可以控制时针的长短
                y1 = Y + r - Convert.ToSingle(Math.Cos(angle) * (r - offset));
                //圆心
                PointF pointEclipse = new PointF(X + r, Y + r);
                PointF pointEnd = new PointF(x1, y1);
 
                Graphics.DrawLine(pen, pointEclipse, pointEnd);//画45度角
 
                //分针
                using (Pen penYellow = new Pen(Color.Red, 2))
                {
                    offset = 30;//与分针长度成反比
                    //分
                    double angelMinutes = radian * m;//每分钟弧度
                    x1 = X + r + Convert.ToSingle(Math.Sin(angelMinutes) * (r - offset));//通过调整offset的大小,可以控制时针的长短
                    y1 = Y + r - Convert.ToSingle(Math.Cos(angelMinutes) * (r - offset));
                    Graphics.DrawLine(penYellow, pointEclipse, new PointF(x1, y1));//画45度角
                }
 
                //秒针
                using (Pen penYellow = new Pen(Color.Blue, 2))
                {
                    offset = 20;
                    //分
                    double angelSeconds = radian * s;//每秒钟弧度
                    x1 = X + r + Convert.ToSingle(Math.Sin(angelSeconds) * (r - offset));//通过调整offset的大小,可以控制时针的长短
                    y1 = Y + r - Convert.ToSingle(Math.Cos(angelSeconds) * (r - offset));
                    Graphics.DrawLine(penYellow, pointEclipse, new PointF(x1, y1));//画45度角
                }
            }
        }
 
 
        /// <summary>
        /// <![CDATA[绘制时刻线]]>
        /// </summary>
        private void DrawQuartzLine()
        {
            //圆心
            PointF pointEclipse = new PointF(X + r, Y + r);
            float labelX, labelY;//文本坐标
            float angle = Convert.ToSingle(Math.PI / 6);//角度 30度
            using (Font font = new Font(FontFamily.GenericSerif, 12))
            {
                float _x, _y;//圆上的坐标点
                using (Brush brush = new System.Drawing.SolidBrush(Color.Red))
                {
                    using (Pen pen = new Pen(Color.Black, 0.6f))
                    {
                        //一天12H,将圆分为12份 
                        for (int i = 0; i <= 11; i++)
                        {
                            PointF p10;//圆周上的点
                            float pAngle = angle * i;
                            float x1, y1;
 
                            //三、四象限
                            if (pAngle > Math.PI)
                            {
                                if ((pAngle - Math.PI) > Math.PI / 2)//钝角大于90度 
                                {
                                    //第三象限
                                    x1 = Convert.ToSingle(r * Math.Cos(Math.PI * 2 - pAngle));
                                    y1 = Convert.ToSingle(r * Math.Sin(Math.PI * 2 - pAngle));
                                    _x = X + r - x1;
                                    _y = Y + r + y1;
                                    labelX = _x - 8;
                                    labelY = _y;
                                }
                                else
                                {
                                    //第四象限
                                    x1 = Convert.ToSingle(r * Math.Cos(pAngle - Math.PI));
                                    y1 = Convert.ToSingle(r * Math.Sin(pAngle - Math.PI));
                                    _x = X + r + x1;
                                    _y = Y + r + y1;
                                    labelX = _x;
                                    labelY = _y;
                                }
                            }
                            //一、二象限
                            else if (pAngle > Math.PI / 2)//钝角大于90度
                            {
                                //第一象限
                                x1 = Convert.ToSingle(r * Math.Cos(Math.PI - pAngle));
                                y1 = Convert.ToSingle(r * Math.Sin(Math.PI - pAngle));
                                _x = X + r + x1;
                                _y = Y + r - y1;
                                labelX = _x;
                                labelY = _y - 20;
                            }
                            else
                            {
                                //第二象限
                                x1 = Convert.ToSingle(r * Math.Cos(pAngle));
                                y1 = Convert.ToSingle(r * Math.Sin(pAngle));
                                _x = X + r - x1;
                                _y = Y + r - y1;
                                labelX = _x - 15;
                                labelY = _y - 20;
                            }
                            //上半圆 分成12份,每份 30度
                            if (i + 9 > 12)
                            {
                                Graphics.DrawString((i + 9 - 12).ToString(), font, brush, labelX, labelY);
                            }
                            else
                            {
                                if (i + 9 == 9)
                                {
                                    labelX = X - 13;
                                    labelY = Y + r - 6;
                                }
                                Graphics.DrawString((i + 9).ToString(), font, brush, labelX, labelY);
                            }
                            p10 = new PointF(_x, _y);
                            Graphics.DrawLine(pen, pointEclipse, p10);
                        }
                    }
                }
            }
        }
 
 
        /// <summary>
        /// <![CDATA[写入版本信息]]>
        /// </summary>
        private void WriteVersion()
        {
            PointF point = new PointF(X + r / 4, Y + r - 30);
            using (Font font = new Font(FontFamily.GenericSansSerif, 18))
            {
                using (Brush brush = new SolidBrush(Color.Black))
                {
                    this.Graphics.DrawString("Quartz", font, brush, point);
                }
            }
        }
 
 
        /// <summary>
        /// <![CDATA[释放]]>
        /// </summary>
        /// <param name="isDispose"></param>
        private void Dispose(bool isDispose)
        {
            if (isDispose)
            {
                timer.Abort();
                this.Graphics.Dispose();
            }
        }
 
        /// <summary>
        ///
        /// </summary>
        public void Dispose()
        {
            this.Dispose(true);
        }
    }
}

  winfom调用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/// <summary>
    ///
    /// </summary>
    private CSharpQuartz sharpQuartz = null;
 
    /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void CSharpQuartzSample_Load(object sender, EventArgs e)
    {
        float w = 300f, h = 300f;
        float x = (this.Width - w) / 2;
        float y = (this.Height - h) / 2;
        sharpQuartz = new CSharpQuartz(this, x, y, w);
        sharpQuartz.OnChanged += SharpQuartz_OnChanged;
        sharpQuartz.Start();
    }
 
    /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void SharpQuartz_OnChanged(object sender, EventArgs e)
    {
        if (lblTime.IsHandleCreated)
        {
            lblTime.Invoke(new Action(() =>
            {
                lblTime.Text = DateTime.Now.ToString("当前时间:HH:mm:ss");
            }));
        }
    }

  这就是我们开篇第一张效果图,带有Quartz字样的,至此,关于GDI绘制时钟与系统时间同步的小程序就这样完成。时间仓促,某些计算方法买来得及仔细推敲,不足之处,大家多提意见。

 

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示