给你一个模仿LED的控件 //SevenSegmentClock.cs namespace LEDClock { public partial class SevenSegmentClock : UserControl { public SevenSegmentClock() { Text = "Seven-Segment Clock"; //使用双缓冲,支持透明绘制 SetStyle(ControlStyles.UserPaint | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor, true); this.UpdateStyles(); Init(); _dateTime = DateTime.Now; } 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(); } } //初始化 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(); } 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 namespace LEDClock { /// <summary> /// Clock's Style.时钟的样式定义 /// </summary> public enum SevenSegmentClockStyle { DateOnly, // 只显示日期 TimeOnly, // 只显示时间 DateAndTime //显示日期和时间 } //字符绘制的算法 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); } } } |
|