DLL
Timer
Grafikk
Sound
Børre Stenseth
Moduler>Assemblies>Alarmklokke

Alarmklokke

Hva
Image1
Skisse til en alarmklokke

Denne modulen bygger på Klokke. Det er lagt til lyd og klokka kan settes som alarmklokke. Den sier fra at det er alarm (pip-pip-pip) og den sier vor mye klokka er. Vi bruker to DLL'er, en for å beregne visere (Visere) og en for å si klokkeslettet (Lyd).

Utvidelsen av selve klokkekoden er liten. Det eneste nye er at vi skal spille noen lyder hver hele time, metoden PlaySound, og vi skal tegne en alarmviser.

Form1

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Media;
using System.Threading;
namespace niceclock
{
    public partial class Form1 : Form
    {
        private int ms_since_alarm = 0;
        private bool alarmeIsOn = false;
        
        public Form1()
        {
            InitializeComponent();
            //this.SetBounds(100, 100, 400, 400 + 100);
        }
        
        private void timer1_Tick(object sender, EventArgs e)
        {
            // refresh clock
            ms_since_alarm = 
                Math.Min(ms_since_alarm + timer1.Interval, 100000);
            clockPanel.Invalidate();
            DrawArms(this.clockPanel.CreateGraphics());
       }
 
        private void clockPanel_Paint(object sender, PaintEventArgs e)
        {
            DrawArms(e.Graphics);            
        }
        
        protected void DrawArms(Graphics g)
        {
            // assume clock has radius 1
            Matrix m = new Matrix();
            m.Reset();
            m.Translate(0.5f, 0.5f);
            m.Scale(0.4f, -0.4f);
            g.Transform = m;
            //Rectangle R = this.ClientRectangle;
            Rectangle R = clockPanel.ClientRectangle;
            float factor = (float)Math.Min(R.Height, R.Width);
            g.PageScale = factor;
            Brush markbrush = new SolidBrush(Color.Black);
            Pen markpen = new Pen(markbrush);
            // mark hours
            markpen.Width = 0.005f;
            double angle = 0.0;
            while (angle < 2 * Math.PI + 0.01f)
            {
                float x = (float)Math.Cos(angle);
                float y = (float)Math.Sin(angle);
                g.FillEllipse(markbrush, 
                    x - 0.03f, y - 0.03f, 0.06f, 0.06f);
                angle += Math.PI / 6;
            }
            
            DrawArmsNow(g);
            if (alarmeIsOn)
                   DrawAlarm(g);
        }
        private void DrawArmsNow(Graphics g)
        {
            Brush markbrush = new SolidBrush(Color.Black);
            Pen markpen = new Pen(markbrush);
            // seconds arm
            markpen.Width = 0.005f;
            double angle = clockarms.TimeAngle.SecondAngleNow;
            g.DrawLine(markpen, 0.0f, 0.0f,
                (float)Math.Cos(angle * (Math.PI / 180.0)),
                (float)Math.Sin(angle * (Math.PI / 180.0)));
            // minutes arm
            markpen.Width = 2 * markpen.Width;
            angle = clockarms.TimeAngle.MinuteAngleNow;
            g.DrawLine(markpen, 0.0f, 0.0f,
                0.7f * (float)Math.Cos(angle * (Math.PI / 180.0)),
                0.7f * (float)Math.Sin(angle * (Math.PI / 180.0)));
            
            // hours arm
            markpen.Width = 2 * markpen.Width;
            angle = clockarms.TimeAngle.HourAngleNow;
            g.DrawLine(markpen, 0.0f, 0.0f,
                0.5f * (float)Math.Cos(angle * (Math.PI / 180.0)),
                0.5f * (float)Math.Sin(angle * (Math.PI / 180.0)));
        }
        private void DrawAlarm(Graphics g)
        {
            
            Brush markbrush = new SolidBrush(Color.Red);
            Pen markpen = new Pen(markbrush);
            double angle = 0.0;
            markpen.Width = 0.005f;
            // AlarmTime: 
            // year,month,day is irrelevant, seconds allways null
            DateTime alarmTime = new DateTime(2006, 12, 10,
                        Convert.ToInt32(numericHours.Value),
                        Convert.ToInt32(numericMinutes.Value), 0);
            // hours arm
            markpen.Width = 3 * markpen.Width;
            angle = clockarms.TimeAngle.HourAngle(alarmTime);
            g.DrawLine(markpen, 0.0f, 0.0f,
                (float)Math.Cos(angle * (Math.PI / 180.0)),
                (float)Math.Sin(angle * (Math.PI / 180.0)));
            int alarmMinutes = 60 * alarmTime.Hour + alarmTime.Minute;
            DateTime dt=DateTime.UtcNow.ToLocalTime();
            int nowMinutes = 60 * (dt.Hour % 12) + dt.Minute;
            if ((alarmMinutes == nowMinutes) && (ms_since_alarm > 61000))
            {
                playSound();
                ms_since_alarm = 0;
            }
        }
        
        private void playSound()
        {
            // pick sound from app resources
            SoundPlayer snd = 
                new SoundPlayer(Properties.Resources.clock_alarm);
            snd.PlaySync();
            saynumber.Talker.Say(DateTime.UtcNow.ToLocalTime().Hour);
            saynumber.Talker.Say(DateTime.UtcNow.ToLocalTime().Minute);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            // user want to set alarm
            alarmeIsOn = !alarmeIsOn;
            if (alarmeIsOn)
                button1.Text = "Skru av alarm";
            else
                button1.Text = "Sett p� alarm";
        }
    }
}

Merk at selve alarmen er inkludert i klokkalarmprosjektet som en ressurs, mens alle klokkeslettene er lagret i saynumber.

Den kompilerte versjonen av de to dll-filene, clocarms.dll (som beregner viservinkler) og saynumber.dll må koples til i Visual Studio dersom du skal eksperimentere med dette klokkeprosjektet. Dette gjøres ved å høyreklikke på References i Solution Explorer-vinduet i Visual Studio og velge "Add Reference..". Det kommer da opp en dialogboks som gir deg noen valg. Du kan enten velge fra lista over assemblies som er registrerte som system globale eller i dette tilfellet må du browse til den katalogen der du har plassert de to dll-filene.

Referanser
  • DLL-prosjektet clocklib:
    https://svn.hiof.no/svn/psource/Csharpspikes/clockarms
  • DLL-prosjektet SayNumber:
    https://svn.hiof.no/svn/psource/Csharpspikes/saynumber
  • Alarmklokke-prosjektet:
    https://svn.hiof.no/svn/psource/Csharpspikes/clockalarm
Vedlikehold

B. Stenseth, desember 2005

(Velkommen) Moduler>Assemblies>Alarmklokke (Lyd)