C#/WindowForm

C# 시계만들기

hyun0229 2022. 6. 16. 00:43

디자인

디자인은 패널(panel)을 사용하였다.

public partial class Form1 : Form
    {
        Graphics g;
        bool aClock_Flag = true;
        Point center;
        double radius;
        int hourHand;
        int minHand;
        int secHand;
        
        const int clientSize = 300;
        const int clockSize = 200;
        //필드, 속성
        public Form1()
        {
            InitializeComponent();

            this.Text = "FormClock";
            this.ClientSize = new Size(clientSize, clientSize + menuStrip1.Height);
            panel1.BackColor = Color.WhiteSmoke;

            g=panel1.CreateGraphics();
            aClockSetting();
            TimerSetting();
        }

 시계를 그리기위해 panel1의 CreateGraphis를 사용한다. 

aClockSetting()

 private void aClockSetting()
        {
            center = new Point(clientSize / 2, clientSize / 2);
            radius = clockSize / 2;
            hourHand = (int)(radius * 0.45);
            minHand = (int)(radius * 0.55);
            secHand = (int)(radius * 0.65);
        }

아날로그 시게를 새팅한다. 

클라이트 가운데를 포인트로 초침, 분침, 시침을 설정한다.

 

TimerSetting()

 private void TimerSetting()
        {
            Timer timer =new Timer();
            timer.Interval = 1000;
            timer.Tick += Timer_Tick;
            timer.Start();
        }

타이머를 생선한다. 인터벌은 1000으로 1초로 설정하였다.

 

Timer_Tick()

 private void Timer_Tick(object sender, EventArgs e)
        {
            DateTime c = DateTime.Now;
            panel1.Refresh();
            if (aClock_Flag)
            {
                
                DrawClockFace(); //시계판

                //시계바늘 그리기
                double radHr=(c.Hour%12+c.Minute/60)*30*Math.PI/180;
                double radMin=(c.Minute+c.Second/60)*6 * Math.PI / 180;
                double radSec = (c.Second * 6) * Math.PI / 180;

                DrawHands(radHr,radMin,radSec);
            }
            else
            {
                Font fDate = new Font("맑은 고딕", 12, FontStyle.Bold);
                Font fTime = new Font("맑은 고딕", 12, FontStyle.Bold | FontStyle.Italic);
                Brush bdate = Brushes.SkyBlue;
                Brush bTime= Brushes.SteelBlue;

                string date = DateTime.Today.ToString("D");
                string time = string.Format("{0:D2}:{1:D2}:{2:D2}", c.Hour,c.Minute,c.Second);
                g.DrawString(date,fDate,bdate,new Point(2,50));
                g.DrawString(time,fTime,bTime,new Point(2,100));


            }
        }

aClock_Flag은 디지털 시계와 아날로그 시계를 구분하기위해 사용하였다.

시계바늘을 그리는 알고리즘이 중요한데 각도를 계산하여 각각 시간, 분, 초를 설정하였다.

 

DrawClockFace()

 private void DrawClockFace()
        {
            Pen pen=new Pen(Brushes.LightSteelBlue, 30);
            g.DrawEllipse(pen, center.X - clockSize / 2, center.Y - clockSize/2, clockSize, clockSize);
        }

말그대로 시계의 얼굴을 그려준다. DrawEllipse로 원을 그려줌 Ellipse는 타원을 뜻한다.

 

 

DrawHands()

    private void DrawHands(double radHr, double radMin, double radSec)
        {
            //초침(현재 시간의 좌표를 각도를 이용하여 구하자)
            DrawLine(0, 0,(int)(secHand * Math.Sin(radSec)), (int)(secHand * Math.Cos(radSec)),Brushes.OrangeRed,4);
            DrawLine(0, 0, (int)(minHand * Math.Sin(radMin)), (int)(minHand * Math.Cos(radMin)),Brushes.Blue, 4);
            DrawLine(0, 0, (int)(hourHand * Math.Sin(radHr)), (int)(minHand * Math.Cos(radHr)), Brushes.Green, 4);
            int coreSize = 16;
            Rectangle r=new Rectangle(center.X-coreSize/2,center.Y-coreSize/2,coreSize,coreSize);
            g.FillEllipse(Brushes.Gold, r);
            g.DrawEllipse(new Pen(Brushes.Green, 3), r);
        }

Timer_Tick()에서 받은 DrawHands(radHr,radMin,radSec);를 통해 선을 그려준다.  

아래 Rectangle을 통해 시계의 배꼽을 그려준다.

FillEllipse로 원을 금색으로

DrawEllipse로 태두리를 초록으로 설정했다.

 

DrawLine()

 private void DrawLine(int x1, int y1, int x2, int y2, Brush brush, int thick)
        {
            Pen p = new Pen(brush,thick);
            
            g.DrawLine(p, center.X + x1, center.Y - y1, center.X+x2, center.Y - y2);
        }

DrawHands()에서 호출되며 받아온 값으로 분침, 시침, 초침을 그린다. 

 

실행결과
실행결과

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _043_FromClock
{
    public partial class Form1 : Form
    {
        Graphics g;
        bool aClock_Flag = true;
        Point center;
        double radius;
        int hourHand;
        int minHand;
        int secHand;
        
        const int clientSize = 300;
        const int clockSize = 200;
        //필드, 속성
        public Form1()
        {
            InitializeComponent();

            this.Text = "FormClock";
            this.ClientSize = new Size(clientSize, clientSize + menuStrip1.Height);
            panel1.BackColor = Color.WhiteSmoke;

            g=panel1.CreateGraphics();
            aClockSetting();
            TimerSetting();
        }

        private void TimerSetting()
        {
            Timer timer =new Timer();
            timer.Interval = 1000;
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            DateTime c = DateTime.Now;
            panel1.Refresh();
            if (aClock_Flag)
            {
                
                DrawClockFace(); //시계판

                //시계바늘 그리기
                double radHr=(c.Hour%12+c.Minute/60)*30*Math.PI/180;
                double radMin=(c.Minute+c.Second/60)*6 * Math.PI / 180;
                double radSec = (c.Second * 6) * Math.PI / 180;

                DrawHands(radHr,radMin,radSec);
            }
            else
            {
                Font fDate = new Font("맑은 고딕", 12, FontStyle.Bold);
                Font fTime = new Font("맑은 고딕", 12, FontStyle.Bold | FontStyle.Italic);
                Brush bdate = Brushes.SkyBlue;
                Brush bTime= Brushes.SteelBlue;

                string date = DateTime.Today.ToString("D");
                string time = string.Format("{0:D2}:{1:D2}:{2:D2}", c.Hour,c.Minute,c.Second);
                g.DrawString(date,fDate,bdate,new Point(2,50));
                g.DrawString(time,fTime,bTime,new Point(2,100));


            }
        }

        //시계바늘 그리기
        private void DrawHands(double radHr, double radMin, double radSec)
        {
            //초침(현재 시간의 좌표를 각도를 이용하여 구하자)
            DrawLine(0, 0,(int)(secHand * Math.Sin(radSec)), (int)(secHand * Math.Cos(radSec)),Brushes.OrangeRed,4);
            DrawLine(0, 0, (int)(minHand * Math.Sin(radMin)), (int)(minHand * Math.Cos(radMin)),Brushes.Blue, 4);
            DrawLine(0, 0, (int)(hourHand * Math.Sin(radHr)), (int)(minHand * Math.Cos(radHr)), Brushes.Green, 4);
            int coreSize = 16;
            Rectangle r=new Rectangle(center.X-coreSize/2,center.Y-coreSize/2,coreSize,coreSize);
            g.FillEllipse(Brushes.Gold, r);
            g.DrawEllipse(new Pen(Brushes.Green, 3), r);
        }

        private void DrawLine(int x1, int y1, int x2, int y2, Brush brush, int thick)
        {
            Pen p = new Pen(brush,thick);
            
            g.DrawLine(p, center.X + x1, center.Y - y1, center.X+x2, center.Y - y2);
        }

        private void DrawClockFace()
        {
            Pen pen=new Pen(Brushes.LightSteelBlue, 30);
            g.DrawEllipse(pen, center.X - clockSize / 2, center.Y - clockSize/2, clockSize, clockSize);
        }

        //아날로그 시계 세팅
        private void aClockSetting()
        {
            center = new Point(clientSize / 2, clientSize / 2);
            radius = clockSize / 2;
            hourHand = (int)(radius * 0.45);
            minHand = (int)(radius * 0.55);
            secHand = (int)(radius * 0.65);
        }

        private void 아날로그ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            aClock_Flag = true;

        }

        private void 디지털ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            aClock_Flag = false;

        }
    }
}

전체코드