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 |