C#

047_Form_Clock_C#

iwannabebackendexpert 2022. 6. 9. 04:11

 

C# WinForm으로 아날로그 시계와 디지털 시계를 만들어보자.

 

WinForm은 GDI+를 사용합니다

-윈도우가 디바이스 드라이버에 독립적으로 프로그래밍할 수 있도록 그래픽을 제공해주는 모든 기능
-Visual C++ 환경에서 닷넷 환경으로 변경되면서 더 많은 장점과 사용의 편리함을 제공하는 것이 GDI+

 

public partial class Form1 : Form
    {
        //필드 , 속성
        Graphics g;
        bool aClock_Flag = false;
        Point center; //중심점
        double radius; //반지름
        int hourHand; //시침의 길이
        int minHand; //분침
        int secHand; //초침
        const int clientSize = 300;
        const int clockSize = 200;
    }

Graphics 형의 객체 g생성. 및 클라이언트 크기 및 여러가지 시계부품 선언.

public Form1()
        {
            InitializeComponent();
            this.ClientSize = new Size(clientSize, clientSize+menuStrip1.Height); //메뉴스트립 높이 더 함 
            this.Text = "Form Clock";
            panel1.BackColor = Color.Gray;

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

Form 크기 , 폼 제목, 패널의 색상, panel1의 GDI+ 이용. 각각의 함수 선언

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

timer객체를 만들고 interval을 1초로 둠.

 private void Timer_Tick(object sender, EventArgs e)
        {
            DateTime c = DateTime.Now;
            panel1.Refresh(); //패널지우기
            if (aClock_Flag == true)
            {

                DrawClockFace(); //시계판

                //시계바늘 그리기
                double radHr = (c.Hour % 12 + c.Minute / 60.0) * 30 * Math.PI / 180;
                double radMin = (c.Minute + c.Second / 60.0) * 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("맑은 고딕", 32, FontStyle.Bold|FontStyle.Italic);
                Brush bDate = Brushes.SkyBlue;
                Brush bTime = Brushes.White;

                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(50, 120));
                g.DrawString(time,fTime,bTime,new Point(50, 150));
            }
        }

 

 

Datetime 을 이용해서 c객체에 현재 시간 저장.

Flag이용

- aClock (analog) == true; 이라면 시계판 그리고, 시침분침초침의 각도 설정.

- aClock == false; (digital) 이라면 디지털 시계 그리기.

 

시계바늘 그리는 알고리즘.

예를 들어 분침이 10분을 가리킨다면, <그림>처럼 중심점에서 60도의 각도를 갖고 침의 길이만큼 그려주면 됩니다.
(삼각함수 이용)

 

그림에서 (x2, y2)를 구해야 하는데 이는,

 

x2 = Center.X + L*sin(θ)
y2 = Center.Y L*cos(θ)
private void DrawHands(double radHr, double radMin, double radSec)
        {
            //시침
            DrawLine(0, 0,
            (int)(hourHand * Math.Sin(radHr)), (int)(hourHand * Math.Cos(radHr)),Brushes.HotPink,5);
            
            //분침
            DrawLine(0, 0,
            (int)(minHand * Math.Sin(radMin)), (int)(minHand * Math.Cos(radMin)),Brushes.Linen,4);
            
            //초침(현재 시간의 좌표를 각도를 이용하여 구하자)
            DrawLine(0,0,
            (int)(secHand * Math.Sin(radSec)),(int)(secHand* Math.Cos(radSec)),Brushes.Gold,3);

            //배꼽
            int coreSize = 16;
            Rectangle r = new Rectangle(
                center.X - coreSize / 2, center.Y - coreSize / 2, coreSize, coreSize);
            g.FillEllipse(Brushes.White, r);
            g.DrawEllipse(new Pen(Brushes.Bisque, 3), r);
               
        }

시침,분침,초침,배꼽 그리기

* DrawEllipse는 원을 그리는 것이다.

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.White, 15);
            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);

        }

aClockSetting()은 시,분,초침의 길이를 정하는 메소드. 시침이 일반적으로 분침, 초침에 비해 짧다.

 

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

        }

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

        private void 끝내기ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

아날로그를 눌렀을때, 디지털을 눌렀을때, 끝내기를 눌렀을때 실행되는 이벤트들

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 _047_FormClock
{

    public partial class Form1 : Form
    {
        //필드 , 속성
        Graphics g;
        bool aClock_Flag = false;
        Point center; //중심점
        double radius; //반지름
        int hourHand; //시침의 길이
        int minHand; //분침
        int secHand; //초침
        const int clientSize = 300;
        const int clockSize = 200;
        public Form1()
        {
            InitializeComponent();
            this.ClientSize = new Size(clientSize, clientSize+menuStrip1.Height); //메뉴스트립 높이 더 함 
            this.Text = "Form Clock";
            panel1.BackColor = Color.Gray;

            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 == true)
            {

                DrawClockFace(); //시계판

                //시계바늘 그리기
                double radHr = (c.Hour % 12 + c.Minute / 60.0) * 30 * Math.PI / 180;
                double radMin = (c.Minute + c.Second / 60.0) * 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("맑은 고딕", 32, FontStyle.Bold|FontStyle.Italic);
                Brush bDate = Brushes.SkyBlue;
                Brush bTime = Brushes.White;

                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(50, 120));
                g.DrawString(time,fTime,bTime,new Point(50, 150));
            }
        }

        private void DrawHands(double radHr, double radMin, double radSec)
        {
            //시침
            DrawLine(0, 0,
            (int)(hourHand * Math.Sin(radHr)), (int)(hourHand * Math.Cos(radHr)),Brushes.HotPink,5);
            
            //분침
            DrawLine(0, 0,
            (int)(minHand * Math.Sin(radMin)), (int)(minHand * Math.Cos(radMin)),Brushes.Linen,4);
            
            //초침(현재 시간의 좌표를 각도를 이용하여 구하자)
            DrawLine(0,0,
            (int)(secHand * Math.Sin(radSec)),(int)(secHand* Math.Cos(radSec)),Brushes.Gold,3);

            //배꼽
            int coreSize = 16;
            Rectangle r = new Rectangle(
                center.X - coreSize / 2, center.Y - coreSize / 2, coreSize, coreSize);
            g.FillEllipse(Brushes.White, r);
            g.DrawEllipse(new Pen(Brushes.Bisque, 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.White, 15);
            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;
        }

        private void 끝내기ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}

'C#' 카테고리의 다른 글

049_Rotation_Clock_C#  (0) 2022.06.12
048_WPF_Clock_C#  (0) 2022.06.12
046_Matching Game(그림 맞추기 게임)_C#  (0) 2022.06.09
045_ECG,PPG(Gragh Control)  (0) 2022.06.09
044_Graph  (0) 2022.06.09