使用C#编写LED样式时钟控件
运行效果:
右下角图片
//--------------------------(如转载,请保留版权信息)-------------------------// // SevenSegmentClockStyle.cs 朱继山 a3news(AT)hotmail.com --// // ----------------------------- http://www.brawdraw.com ----------------------// // -------------------- 未经书面许可,请勿用于商业用途 ---------------------// using System; namespace BrawDraw.Com.PhotoFrame.Net.PublicFunctions.Clock { /// <summary> /// Clock's Style.时钟的样式定义 /// </summary> public enum SevenSegmentClockStyle { DateOnly, // 只显示日期 TimeOnly, // 只显示时间 DateAndTime //显示日期和时间 } }
//--------------------------(如转载,请保留版权信息)-------------------------// // SevenSegmentClock.cs 朱继山 a3news(AT)hotmail.com -------// // ----------------------------- http://www.brawdraw.com ----------------------// // -------------------- 未经书面许可,请勿用于商业用途 ---------------------// using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Globalization; using System.Windows.Forms; using BrawDraw.Com.PhotoFrame.Net.PublicFunctions; using System.ComponentModel; namespace BrawDraw.Com.PhotoFrame.Net.PublicFunctions.Clock { //这是控件的关键代码 public class SevenSegmentClock : UserControl { DateTime _dateTime; //默认使用同时绘制日期和时间 SevenSegmentClockStyle _clockStyle = SevenSegmentClockStyle.DateAndTime; Color _clockColor = Color.Black; //是否绘制阴影(即残影),以摸拟真似的LED时钟 bool _isDrawShadow = true; Timer _timer = null; //是否自动更新时间 bool _isTimerEnable = false; Graphics g = null; Bitmap m_Bitmap = null; public bool IsDrawShadow { get { return this._isDrawShadow; } set { this._isDrawShadow = value; this.Invalidate(); } } [Browsable(false)] public System.Windows.Forms.Timer Timer { get { return this._timer; } set { this._timer = value; if (_timer != null) { _timer.Tick = new EventHandler(TimerOnTick); } } } public bool IsTimerEnable { get { return this._isTimerEnable; } set { if (value == true) { if (this._timer == null) { _timer = new Timer(); _timer.Tick = new EventHandler(TimerOnTick); _timer.Interval = 1000; _timer.Enabled = true; } } else { if (this._timer != null) { _timer.Enabled = false; } } this._isTimerEnable = value; } } public void Start() { this.IsTimerEnable = true; this.Refresh(); } public void Stop() { this.IsTimerEnable = false; } public System.DateTime DateTime { get { return this._dateTime; } set { this._dateTime = value; } } //LED文字的颜色 public System.Drawing.Color ClockColor { get { return this._clockColor; } set { this._clockColor = value; this.Invalidate(); } } public SevenSegmentClockStyle SevenSegmentClockStyle { get { return this._clockStyle; } set { this._clockStyle = value; this.Invalidate(); } } public SevenSegmentClock() { Text = "Seven-Segment Clock"; //使用双缓冲,支持透明绘制 SetStyle(ControlStyles.UserPaint | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor, true); this.UpdateStyles(); Init(); _dateTime = DateTime.Now; } //初始化 private void Init() { m_Bitmap = new Bitmap(this.Width, this.Height); g = Graphics.FromImage(m_Bitmap); g.CompositingQuality = CompositingQuality.HighQuality; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; //g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.SmoothingMode = SmoothingMode.HighQuality; //g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; } void TimerOnTick(object obj, EventArgs ea) { DateTime dtNow = DateTime.Now; dtNow = new DateTime(dtNow.Year, dtNow.Month, dtNow.Day, dtNow.Hour, dtNow.Minute, dtNow.Second); if (dtNow != _dateTime) { _dateTime = dtNow; Invalidate(); } } protected override void OnPaint(PaintEventArgs e) { m_Bitmap = DrawClock(); Graphics gg = e.Graphics; gg.CompositingQuality = CompositingQuality.HighQuality; gg.DrawImageUnscaled(m_Bitmap, 0, 0); //g.Dispose(); } public Bitmap DrawClock() { return this.DrawClock(this.ClientRectangle); } private void SevenSegmentClock_Resize(object sender, System.EventArgs e) { Init(); this.Refresh(); } private void InitializeComponent() { // // SevenSegmentClock // this.Name = "SevenSegmentClock"; this.Size = new System.Drawing.Size(448, 64); this.Resize = new System.EventHandler(this.SevenSegmentClock_Resize); } int _clockStringWidth; int _clockStringHeight; public int ClockStringWidth { get { return _clockStringWidth; } } public int ClockStringHeight { get { return _clockStringHeight; } } //绘制时钟 public Bitmap DrawClock(Rectangle destRect) { m_Bitmap = new Bitmap(destRect.Width, destRect.Height); //m_Bitmap = new Bitmap(destRect.X this.Width, destRect.Y this.Height); Graphics grfx = Graphics.FromImage(m_Bitmap); //设置绘图面板的绘制质量等 grfx.CompositingQuality = CompositingQuality.HighQuality; grfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; grfx.SmoothingMode = SmoothingMode.HighQuality; SevenSegmentDisplay ssd = new SevenSegmentDisplay(grfx); ssd.IsDrawShadow = this._isDrawShadow; GraphicsState gs = grfx.Save(); grfx.TranslateTransform(destRect.X, destRect.Y); string strTime = string.Empty; if (this._clockStyle == SevenSegmentClockStyle.TimeOnly) { strTime = _dateTime.ToString("T", DateTimeFormatInfo.InvariantInfo); } else if (this._clockStyle == SevenSegmentClockStyle.DateOnly) { //设置日期格式 strTime = _dateTime.ToString("yyyy-MM-dd", DateTimeFormatInfo.InvariantInfo); } else { strTime = _dateTime.ToString("yyyy-MM-dd", DateTimeFormatInfo.InvariantInfo) " " _dateTime.ToString("T", DateTimeFormatInfo.InvariantInfo); } SizeF sizef = ssd.MeasureString(strTime, Font); float fScale = Math.Min(destRect.Width / sizef.Width, destRect.Height / sizef.Height); Font font = new Font(Font.FontFamily, fScale * Font.SizeInPoints); sizef = ssd.MeasureString(strTime, font); _clockStringWidth = (int) sizef.Width; _clockStringHeight = (int) sizef.Height; ssd.DrawString(strTime, font, new SolidBrush(this._clockColor), (destRect.Width - sizef.Width) / 2, (destRect.Height - sizef.Height) / 2); grfx.Restore(gs); return m_Bitmap; } } }
//--------------------------(如转载,请保留版权信息)-------------------------// // SevenSegmentDisplay.cs 2001 by Charles Petzold // //------------------------改编:朱继山 a3news(AT)hotmail.com -----------// using System; using System.Drawing; using System.Windows.Forms; namespace BrawDraw.Com.PhotoFrame.Net.PublicFunctions.Clock { //字符绘制的算法 class SevenSegmentDisplay { Graphics grfx; Brush _brush = Brushes.Black; bool _isDrawShadow = true; Color _shadowColor = Color.FromArgb(60, Color.White); Brush _shadowBrush = null; // Indicates what segments are illuminated for all 10 digits static byte[,] bySegment = { {1, 1, 1, 0, 1, 1, 1}, // 0 {0, 0, 1, 0, 0, 1, 0}, // 1 {1, 0, 1, 1, 1, 0, 1}, // 2 {1, 0, 1, 1, 0, 1, 1}, // 3 {0, 1, 1, 1, 0, 1, 0}, // 4 {1, 1, 0, 1, 0, 1, 1}, // 5 {1, 1, 0, 1, 1, 1, 1}, // 6 {1, 0, 1, 0, 0, 1, 0}, // 7 {1, 1, 1, 1, 1, 1, 1}, // 8 {1, 1, 1, 1, 0, 1, 1} // 9 }; // Points that define each of the seven segments readonly Point[][] apt = new Point[7][]; public bool IsDrawShadow { get { return this._isDrawShadow; } set { this._isDrawShadow = value; } } public SevenSegmentDisplay(Graphics grfx) { this.grfx = grfx; // Initialize jagged Point array. apt[0] = new Point[] { new Point( 3, 2), new Point(39, 2), new Point(31, 10), new Point(11, 10) }; apt[1] = new Point[] { new Point( 2, 3), new Point(10, 11), new Point(10, 31), new Point( 2, 35) }; apt[2] = new Point[] { new Point(40, 3), new Point(40, 35), new Point(32, 31), new Point(32, 11) }; apt[3] = new Point[] { new Point( 3, 36), new Point(11, 32), new Point(31, 32), new Point(39, 36), new Point(31, 40), new Point(11, 40) }; apt[4] = new Point[] { new Point( 2, 37), new Point(10, 41), new Point(10, 61), new Point( 2, 69) }; apt[5] = new Point[] { new Point(40, 37), new Point(40, 69), new Point(32, 61), new Point(32, 41) }; apt[6] = new Point[] { new Point(11, 62), new Point(31, 62), new Point(39, 70), new Point( 3, 70) }; } public SizeF MeasureString(string str, Font font) { SizeF sizef = new SizeF(0, grfx.DpiX * font.SizeInPoints / 72); for (int i = 0; i < str.Length; i ) { if (Char.IsDigit(str[i])) { sizef.Width = 42 * grfx.DpiX * font.SizeInPoints / 72 / 72; } else if (str[i] == '-') { sizef.Width = 42 * grfx.DpiX * font.SizeInPoints / 72 / 72; } else if (str[i] == ':') { sizef.Width = 20 * grfx.DpiX * font.SizeInPoints / 72 / 72; } else if (str[i] == ' ') { sizef.Width = 36 * grfx.DpiX * font.SizeInPoints / 72 / 72; } } return sizef; } public void DrawString(string str, Font font, Brush brush, float x, float y) { this._brush = brush; this._shadowBrush = new SolidBrush(Color.FromArgb(40, ((SolidBrush) this._brush).Color)); for (int i = 0; i < str.Length; i ) { if (Char.IsDigit(str[i])) { x = Number(str[i] - '0', font, brush, x, y); } else if (str[i] == '-') { x = MinusSign(font, brush, x, y); } else if (str[i] == ':') { x = Colon(font, brush, x, y); } else if (str[i] == ' ') { x = DrawSpace(font, brush, x, y); } } } private float Number(int num, Font font, Brush brush, float x, float y) { for (int i = 0; i < apt.Length; i ) { if (_isDrawShadow) { Fill(apt[i], font, _shadowBrush, x, y); } if (bySegment[num, i] == 1) { Fill(apt[i], font, brush, x, y); } } return x 42 * grfx.DpiX * font.SizeInPoints / 72 / 72; } private float MinusSign(Font font, Brush brush, float x, float y) { Fill(apt[3], font, brush, x, y); return x 42 * grfx.DpiX * font.SizeInPoints / 72 / 72; } private float DrawSpace(Font font, Brush brush, float x, float y) { return x 36 * grfx.DpiX * font.SizeInPoints / 72 / 72; } private float Colon(Font font, Brush brush, float x, float y) { Point[][] apt = new Point[2][]; apt[0] = new Point[] { new Point( 4, 12), new Point( 16, 12), new Point(16, 24), new Point( 4, 24) }; apt[1] = new Point[] { new Point( 4, 50), new Point( 16, 50), new Point(16, 62), new Point( 4, 62) }; for (int i = 0; i < apt.Length; i ) { Fill(apt[i], font, brush, x, y); } return x 20 * grfx.DpiX * font.SizeInPoints / 72 / 72; } private void Fill(Point[] apt, Font font, Brush brush, float x, float y) { PointF[] aptf = new PointF[apt.Length]; for (int i = 0; i < apt.Length; i ) { aptf[i].X = x apt[i].X * grfx.DpiX * font.SizeInPoints / 72 / 72; aptf[i].Y = y apt[i].Y * grfx.DpiY * font.SizeInPoints / 72 / 72; } grfx.FillPolygon(brush, aptf); } } }