蓝天旭日

高手如云,自己只是个菜鸟而已! 没有人在意你曾经的努力和散漫,只有人关注你是否有成就......
  博客园  :: 首页  :: 新随笔  :: 联系 :: 管理

简单C# DGI绘图:时钟 (透明pictureBox解决抖动问题)

Posted on 2008-01-03 16:57  蓝天旭日  阅读(11142)  评论(15编辑  收藏  举报

                    

以前用VC++设计过时钟,也用flash做过,也在web上结合js做过,采用的思路是在直接绘制,当然是画圆、描点采用计数器来定时绘制时针、分针和秒针。

这里是在C#中采用GDI绘图来完成,结合pictureBox来解决了普通的抖动、闪烁问题。

解决方法:

1 当然是在表单上拖置一个pictureBox控件,这里暂且name = pictureBox1

2 重载OnPaint方法:protected override void OnPaint(PaintEventArgs e)

3 设置定时器timer, name =timer1, 响应timer1_Tick(),并在事件中重绘pictureBox

 [也可以用Threading来sleep方法来定时]

    pictureBox1.Invalidate();

4 [关键]在OnPaint()方法中绘制表盘和刻度等

5 [关键]将 pictureBox的设置为透明。属性->>backcolor->>web->>Transparent

完整代码如下:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Drawing.Drawing2D;

using System.Text;

using System.Windows.Forms;

namespace clock

{

    public partial class Form1 : Form

    {

        private Graphics g;

        private Pen pen;

        private FontFamily MyFamily;

        private Font MyFont;

        private int w;

        private int h;

        public Form1()

        {

            InitializeComponent();

          

        }

        private void Form1_Load(object sender, EventArgs e)

        {

            timer_Second.Start(); //开启定时器

            timer_Second.Interval = 1000; //间隔为毫秒,即秒

        }

        protected override void OnPaint(PaintEventArgs e)

        {

            base.OnPaint(e);

            g = e.Graphics;

            g.SmoothingMode = SmoothingMode.AntiAlias; //

            g.SmoothingMode = SmoothingMode.HighQuality;//绘图模式默认为粗糙模式,将会出现锯齿!

          

            w = pictureBox1.Width;

            h = pictureBox1.Height;

            int x1 = pictureBox1.Location.X;

            int y1 = pictureBox1.Location.Y;

            /*------------------------------------------------------------------------------

            计算:整点刻度个,每个刻度偏移角度为/12 = 30 度及为小时偏移角度

                  分秒刻度为个,每个刻度偏移角度为/60 = 6 度及为分、秒偏移角度

            --------------------------------------------------------------------------------*/

            g.FillEllipse(Brushes.Black, x1+2,y1+2, w - 4, h - 4); //外圆

            MyFamily = new System.Drawing.FontFamily("Impact"); //字体

            MyFont = new System.Drawing.Font(MyFamily, 20, FontStyle.Bold, GraphicsUnit.Pixel);

            g.DrawString("HOCYLAN", MyFont, Brushes.Yellow, x1 + w-180, y1 + h -100);

            MyFamily = new System.Drawing.FontFamily("Times New Roman");

            MyFont = new System.Drawing.Font(MyFamily, 14, FontStyle.Bold, GraphicsUnit.Pixel);

            pen = new Pen(Color.White, 2);

            g.DrawEllipse(pen, x1+7, y1+7, w - 13, h - 13);// 内圆

            g.TranslateTransform(x1+(w / 2),y1+(h / 2));//重新设置坐标原点

            g.FillEllipse(Brushes.White, -5,-5, 10, 10);//绘制表盘中心

            //g.TranslateTransform(w/2,h/2);

            for (int x = 0; x < 60; x++) //小刻度

            {

                g.FillRectangle(Brushes.White, new Rectangle(-2, (System.Convert.ToInt16(h- 8) / 2 - 2) * (-1), 3, 10));

                g.RotateTransform(6);//偏移角度

            }

            for (int i = 12; i > 0; i--) //大刻度

            {

                string myString = i.ToString();

                //绘制整点刻度

                g.FillRectangle(Brushes.White, new Rectangle(-3, (System.Convert.ToInt16(h - 8) / 2 - 2) * (-1), 6, 20));

                //绘制数值

                g.DrawString(myString, MyFont, Brushes.White, new PointF(myString.Length * (-6),( h - 8) / -2 + 26));

                //顺时针旋转度

                g.RotateTransform(-30);//偏移角度

            }

        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)

        {

            g = e.Graphics;

            //绘图模式默认为粗糙模式,将会出现锯齿!

            g.SmoothingMode = SmoothingMode.AntiAlias;

            g.SmoothingMode = SmoothingMode.HighQuality;

            g.TranslateTransform(w / 2, h / 2);//重新设置坐标原点

            //获得系统时间值

            int second = DateTime.Now.Second;

            int minute = DateTime.Now.Minute;

            int hour = DateTime.Now.Hour;

            /*------------------------------------------------------------------------------------

            每秒偏移度,秒针偏移=当前秒*6

            每分偏移读,分针偏移= 当前分*6+当前秒*(/60)

            每小时偏移读,时针偏移= 当前时*30+当前分*(/60)+当前秒*(/60/60)

            --------------------------------------------------------------------------------------*/

            //绘秒针

            pen = new Pen(Color.White, 1);

            pen.EndCap = LineCap.ArrowAnchor;

            g.RotateTransform(6 * second);

            float y = (float)((-1) * (h / 2.75));

            g.DrawLine(pen, new PointF(0, 0), new PointF((float)0, y));

            ////绘分针

            pen = new Pen(Color.White, 4);

           // pen.EndCap = LineCap.ArrowAnchor;

            g.RotateTransform(-6 * second); //恢复系统偏移量,再计算下次偏移

            g.RotateTransform((float)(second*0.1+minute*6));

            y = (float)((-1) * ((h-20) / 2.75));

            g.DrawLine(pen, new PointF(0, 0), new PointF((float)0, y));

            ////绘时针

            pen = new Pen(Color.White, 6);

           // pen.EndCap = LineCap.ArrowAnchor;

            g.RotateTransform((float)(-second * 0.1 - minute * 6));//恢复系统偏移量,再计算下次偏移

            g.RotateTransform((float)(second * 0.01 + minute * 0.1+hour*30));

            y = (float)((-1) * ((h-35) / 2.75));

            g.DrawLine(pen, new PointF(0, 0), new PointF((float)0, y));

        }

        private void timer1_Tick(object sender, EventArgs e)

        {

            pictureBox1.Invalidate();//只重新绘制pictureBox    

        }

        }

}

最后执行结果如下: