.NET Analog Clock Example

This is a simple example of a .NET custom user control. Compare this code to the MFC Analog Clock. Download the complete source code: DOTNETCLOCK.zip

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace ClockControls
{
	class AnalogClockControl : UserControl
	{
		private DateTime dt;

		public AnalogClockControl()
		{
			ResizeRedraw = true;
			Enabled = false;
		}
		public DateTime Time
		{
			set
			{
				using (Graphics grfx = CreateGraphics())
				{
					Pen pn = new Pen(BackColor);

					InitializeCoordinates(grfx);

					//erase the current hour if it is not the same
					if (dt.Hour != value.Hour)
					{
						DrawHourHand(grfx, pn);
					}
					//erase the current hour and minute if not the same
					if (dt.Minute != value.Minute)
					{
						DrawHourHand(grfx, pn);
						DrawMinuteHand(grfx, pn, null);
					}

					if (dt.Second != value.Second)
					{
						DrawMinuteHand(grfx, pn, null);
						DrawSecondHand(grfx, pn);
					}

					if (dt.Millisecond != value.Millisecond)
					{
						DrawSecondHand(grfx, pn);
					}
					dt = value;
					pn = new Pen(ForeColor);
					Brush brBack = new SolidBrush(BackColor);
					DrawHourHand(grfx, pn);
					DrawMinuteHand(grfx, pn, brBack);
					DrawSecondHand(grfx, pn);
				}
			}
			get
			{
				return dt;
			}
		}
		protected override void OnPaint(PaintEventArgs e)
		{
			Graphics grfx = e.Graphics;
			Pen pn = new Pen(ForeColor);
			Brush brFore = new SolidBrush(ForeColor);
			Brush brBack = new SolidBrush(BackColor);
			
			InitializeCoordinates(grfx);
			DrawDots(grfx, brFore);
			DrawHourHand(grfx, pn);
			DrawMinuteHand(grfx, pn, brBack);
			DrawSecondHand(grfx, pn);
		}
		private void InitializeCoordinates(Graphics grfx)
		{
			if (Width == 0 || Height == 0)
			{
				return;
			}
			grfx.TranslateTransform(Width / 2.0F, Height / 2.0F);
			float fInches = Math.Min(Width / grfx.DpiX, Height / grfx.DpiY);
			grfx.ScaleTransform(fInches * grfx.DpiX / 2000, fInches * grfx.DpiY / 2000);
		}
		private void DrawDots(Graphics grfx, Brush brFore)
		{
			int i, iSize;

			for (i = 0; i < 60; i++)
			{
				// modulus 5 to change the size of the minute marker every five minutes
				if (i % 5 == 0)
					iSize = 100;
				else
					iSize = 30;
				grfx.FillEllipse(brFore, 0 - iSize / 2.0F, -900 - iSize / 2.0F, iSize, iSize);
				grfx.RotateTransform(360 / 60);
			}
		}
		protected virtual void DrawHourHand(Graphics grfx, Pen pnFore)
		{
			GraphicsState gs = grfx.Save();
			grfx.RotateTransform(360.0F * Time.Hour / 12 + 30.0F * Time.Minute / 60);
			grfx.DrawPolygon(pnFore, new Point[] { new Point(0, 150), new Point(100, 0), new Point(0, -600), new Point(-100, 0) });
			grfx.Restore(gs);
		}
		protected virtual void DrawMinuteHand(Graphics grfx, Pen pnFore, Brush brBack)
		{
			GraphicsState gs = grfx.Save();
			grfx.RotateTransform(360.0F * Time.Minute / 60 + 6.0F * Time.Second / 60);
			Point[] pts = new Point[] { new Point(0, 200), new Point(50, 0), new Point(0, -800), new Point(-50, 0) };
			if (brBack != null)
				grfx.FillPolygon(brBack, pts);
			grfx.DrawPolygon(pnFore, pts);
			grfx.Restore(gs);
		}
		protected virtual void DrawSecondHand(Graphics grfx, Pen pnFore)
		{
			GraphicsState gs = grfx.Save();
			grfx.RotateTransform(360.0F * Time.Second / 60 + 6.0F * Time.Millisecond / 1000);
			grfx.DrawLine(pnFore, 0, 0, 0, -800);
			grfx.Restore(gs);
		}
	}
}
using System;
using System.Drawing;
using System.Windows.Forms;
using ClockControls;

namespace AnalogClock
{
	class AnalogClock : Form
	{
		private AnalogClockControl clock, clock2;

		static void Main()
		{
			Application.Run(new AnalogClock());
		}
		public AnalogClock()
		{
			Text = "Analog Clock";
			Width = 450;
			Height = 450;
			BackColor = SystemColors.Window;
			ForeColor = SystemColors.WindowText;

			clock = new AnalogClockControl();
			clock.Parent = this;
			clock.Time = DateTime.Now;
			clock.Top = 0;
			clock.Left = 0;
			clock.Width = 200;
			clock.Height = 200;
			clock.BackColor = Color.White;
			clock.ForeColor = Color.Black;

			clock2 = new AnalogClockControl();
			clock2.Parent = this;
			clock2.Time = DateTime.Now;
			clock2.Top = 0;
			clock2.Left = 215;
			clock2.Width = 200;
			clock2.Height = 200;
			clock2.BackColor = Color.Orange;
			clock2.ForeColor = Color.White;

			Timer tmr = new Timer();
			tmr.Interval = 50;
			tmr.Tick+=new EventHandler(TimerOnTick);
			tmr.Start();
		}
		private void TimerOnTick(object obj, EventArgs e)
		{
			clock.Time = DateTime.Now;
			clock2.Time = DateTime.Now.AddHours(7);
		}
	}
}