天天看點

GDI繪圖之指針時鐘

利用類的封裝将MyClock封裝到一個類中,以後想要繪制時鐘時直接調用這個類就行了。

MyClock代碼如下

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Drawing;

using System.Windows.Forms;

using System.Drawing.Drawing2D;

namespace Clock

{

    public class MyClock

    {

        public DateTime datetime;

        public Point Center;

        public Form form;

        public double Radius;

        public void Draw(Graphics g)

        {

            DrawDial(g);

            DrawSecond(g);

            DrawMinute(g);

            DrawHour(g);

        }

        void DrawDial(Graphics g)

        {

            Center = new Point((int)(form.Width / 2), (int)(form.Height / 2));

            Radius = (form.Height - 100) / 2;

            Pen pen = new Pen(Color.Black, 2f);

            g.DrawEllipse(pen, new Rectangle((int)(Center.X - Radius), (int)(Center.Y - Radius), (int)(2 * Radius), (int)(2 * Radius)));

            g.DrawEllipse(pen, new Rectangle((int)(Center.X - Radius - 4), (int)(Center.Y - Radius - 4), (int)(2 * Radius + 8), (int)(2 * Radius + 8)));

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

            Point pt1, pt2;

            Font font = new Font("Times New Roman", 10, FontStyle.Regular);

            for (int i = 0; i < 60; i++)

            {

                if (i % 5 == 0)

                {

                    pt1 = new Point((int)(Center.X + Radius * Math.Cos(Math.PI / 30 * i)), (int)(Center.Y + Radius * Math.Sin(Math.PI / 30 * i)));

                    pt2 = new Point((int)(Center.X + (Radius - 20) * Math.Cos(Math.PI / 30 * i)), (int)(Center.Y + (Radius - 20) * Math.Sin(Math.PI / 30 * i)));

                    g.DrawLine(pen, pt1, pt2);

                }

            }

            for (int i = 0; i < 300; i++)

            {

                if (i % 5 == 0)

                {

                    pt1 = new Point((int)(Center.X + Radius * Math.Cos(Math.PI / 150 * i)), (int)(Center.Y + Radius * Math.Sin(Math.PI / 150 * i)));

                    pt2 = new Point((int)(Center.X + (Radius - 10) * Math.Cos(Math.PI / 150 * i)), (int)(Center.Y + (Radius - 10) * Math.Sin(Math.PI / 150 * i)));

                    g.DrawLine(pen, pt1, pt2);

                }

            }

            for (int i = 1; i <= 12; i++)

            {

                g.DrawString(i.ToString(), font, new SolidBrush(Color.Black), new PointF((float)(Center.X-10 + (Radius - 30) * Math.Cos(Math.PI / 6 * i-0.5*Math.PI)),

                    (float)(Center.Y -5+ (Radius - 30) * Math.Sin(Math.PI / 6 * i - 0.5 * Math.PI))));

            }

            g.FillEllipse(new SolidBrush(Color.AliceBlue), Center.X-2, Center.Y-2,10, 10);

        }

        void DrawSecond(Graphics g)

        {

            Pen pen;

            Point pt1, pt2,pt3;

            int second = datetime.Second;

            pen = new Pen(Color.Red);

            pen.EndCap = LineCap.ArrowAnchor;

            pt1 = new Point((int)(Center.X ), (int)(Center.Y ));

            pt2 = new Point((int)(Center.X + (Radius - 20) * Math.Sin(Math.PI / 30 * second)), (int)(Center.Y - (Radius - 20) * Math.Cos(Math.PI / 30 * second)));

            pt3 = new Point((int)(Center.X + (30) * Math.Sin(Math.PI / 30 * second - Math.PI)), (int)(Center.Y - (30) * Math.Cos(Math.PI / 30 * second - Math.PI)));

            g.DrawLine(pen, pt3, pt2);

            //g.DrawLine(pen, pt1, pt3);

        }

        void DrawMinute(Graphics g)

        {

            Pen pen;

            Point pt1, pt2;

            int minute = datetime.Minute;

            pen = new Pen(Color.Blue, 3f);

            pen.EndCap = LineCap.ArrowAnchor;

            pt1 = new Point((int)(Center.X + (20) * Math.Sin(Math.PI / 30 * minute - Math.PI)), (int)(Center.Y - (20) * Math.Cos(Math.PI / 30 * minute - Math.PI))); ;

            pt2 = new Point((int)(Center.X + (Radius - 30) * Math.Sin(Math.PI / 30 * minute)), (int)(Center.Y - (Radius - 30) * Math.Cos(Math.PI / 30 * minute)));

            g.DrawLine(pen, pt1, pt2);

        }

        void DrawHour(Graphics g)

        {

            Pen pen;

            Point pt1, pt2;

            int second = datetime.Second;

            int minute = datetime.Minute;

            int hour = datetime.Hour;

            pen = new Pen(Color.Black, 5f);

            //pen.DashCap = DashCap.Flat;

            //pen.DashStyle = DashStyle.Solid;

            pen.EndCap = LineCap.ArrowAnchor;

            pt1 = new Point((int)(Center.X + (10) * Math.Sin((hour + (double)(minute) / 60) * Math.PI / 6 - Math.PI)), (int)(Center.Y - (10) * Math.Cos((hour + (double)(minute) / 60) * Math.PI / 6 - Math.PI)));

            pt2 = new Point((int)(Center.X + (Radius - 60) * Math.Sin((hour + (double)(minute)/60 ) * Math.PI / 6)), (int)(Center.Y - (Radius - 60) * Math.Cos((hour + (double)(minute)/60 ) * Math.PI / 6)));

            g.DrawLine(pen, pt1, pt2);

        }

    }

}

調用過程主程式中

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Drawing.Drawing2D;

namespace Clock

{

    public partial class FrmClock : Form

    {

        DateTime datetime = DateTime.Now;

        public FrmClock()

        {

            InitializeComponent();

            timer1.Enabled = true;

        }

        private void OnPaint(object sender, PaintEventArgs e)

        {

            Graphics g ;

            g = e.Graphics;

            Rectangle rect = e.ClipRectangle;

            BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;

            BufferedGraphics myBuffer = currentContext.Allocate(e.Graphics, e.ClipRectangle);

            g = myBuffer.Graphics;

            g.SmoothingMode = SmoothingMode.AntiAlias;

            g.PixelOffsetMode = PixelOffsetMode.Half;

            g.Clear(this.BackColor);

            this.SetStyle(ControlStyles.DoubleBuffer, true);

            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

            SetStyle(ControlStyles.UserPaint, true);

            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.

            SetStyle(ControlStyles.DoubleBuffer, true); // 雙緩沖

            MyClock clock = new MyClock();

            clock.datetime = datetime;

            clock.form = this;

            clock.Draw(g);

            myBuffer.Render(e.Graphics);

            g.Dispose();

            myBuffer.Dispose();//釋放資源 

        }

        private void OnTick(object sender, EventArgs e)

        {

            datetime = DateTime.Now;

            Invalidate();

        }

        private void FrmClock_Resize(object sender, EventArgs e)

        {

            Invalidate();

        }

       本程式在VS2010 C#編譯器中運作成功

繼續閱讀