302Soft—302软件技术联盟

ASP.NET / C# / PowerBuilder 技术交流
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

使用C#编写LED样式时钟控件

Posted on 2007-01-21 17:03  寒夜听雨  阅读(1464)  评论(1编辑  收藏  举报

运行效果:

 

//--------------------------(如转载,请保留版权信息)-------------------------//
//   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, 
00);
   
//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(44864);
   
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 = {
         {
1110111},       // 0
         {0010010},       // 1
         {1011101},       // 2
         {1011011},       // 3
         {0111010},       // 4
         {1101011},       // 5
         {1101111},       // 6
         {1010010},       // 7
         {1111111},       // 8
         {1111011}        // 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(3110), new Point(1110)
         };

   apt[
1= new Point[] {
          
new Point( 2,  3), new Point(1011),
          
new Point(1031), new Point( 235)
         };

   apt[
2= new Point[] {
          
new Point(40,  3), new Point(4035),
          
new Point(3231), new Point(3211)
         };

   apt[
3= new Point[] {
          
new Point( 336), new Point(1132),
          
new Point(3132), new Point(3936),
          
new Point(3140), new Point(1140)
         };

   apt[
4= new Point[] {
          
new Point( 237), new Point(1041),
          
new Point(1061), new Point( 269)
         };

   apt[
5= new Point[] {
          
new Point(4037), new Point(4069),
          
new Point(3261), new Point(3241)
         };

   apt[
6= new Point[] {
          
new Point(1162), new Point(3162),
          
new Point(3970), new Point( 370)
         };
  }

  
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( 412), new Point( 1612),
          
new Point(1624), new Point( 424)
         };

   apt[
1= new Point[] {
          
new Point( 450), new Point( 1650),
          
new Point(1662), new Point( 462)
         };

   
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);
  }
 }
}




Copyright(C) 2004-2007 302Soft-寒夜听雨 版权所有