Budzik w C#

Budzik w C#

Autor: Marcin Hałaczkiewicz

Opublikowano: 5/20/2006, 12:00 AM

Liczba odsłon: 144220

Zajmiemy się dzisiaj napisaniem prostego budzika. Nauczymy się minimalizować program do traya, wykorzystamy także menu kontekstowe (pojawia się po naciśnięciu prawego przycisku myszy). Do odliczania czasu posłużymy się kontrolką Timer, która 10 razy na sekundę będzie sprawdzać czas systemowy i odpowiednio reagować. Teoretycznie można by wykorzystać sam Timer do odmierzania czasu, jednak element ten robi to dość niedokładnie.

Tworzymy nowy projekt o nazwie Budzik, formę nazywamy frmBudzik i jeszcze raz wpisujemy Budzik we właściwości Text formatki. Ustawiamy pole AcceptButton na cmdUstaw, dzięki czemu przycisk, który za chwilę utworzymy będzie domyślnie aktywny dla formy. Następnie zmieniamy AutoSizeMode na GrowAndShrink oraz MaximizeBox na false - uniemożliwi to zmianę rozmiaru formy i jej maksymalizację. Kolejną rzeczą będzie utworzenie czterech etykiet. We właściwościach Text pierwszych dwóch wpisujemy Alarm i Czas, ich nazwy są nieistotne. Kolejne dwie nazywamy lblAlarm (w polu Text wpisujemy nie ustawiono) i lblCzas (czyścimy Text). Dodajemy jeszcze pole tekstowe oraz przycisk i kolejno nadajemy im nazwy txtAlarm i cmdUstaw. Dla txtAlarm ustawiamy właściwość Visible na false, następnie układamy elementy, zmieniamy rozmiar formy. Wszystko powinno wyglądać mniej więcej tak (oczywiście czasu nie będzie widać):

txtAlarm ma być w tym samym miejscu co lblAlarm. Oto screen, gdy kontrolka ta jest widoczna:

Zajmijmy się teraz ikonką w trayu oraz menu kontekstowym z nią związanym. Najpierw utwórzmy menu, jest to kontrolka ContextMenuStrip, nadajemy jej nazwę mnuIkonaTray (jej właściwości standardowo ukarzą się w okienku Properties). U góry formy zobaczymy projekt naszej listy. W miejscu, gdzie widoczny jest napis Type Here wpisujemy Pokaż, w polu pod spodem Ustaw, a jeszcze niżej Wyłącz. Następnie klikamy kolejno na każdym z elementów menu i w okienku z właściwościami zmieniamy ich nazwy na odpowiednio: mnuPokaz, mnuUstaw i mnuWylacz. Teraz utworzymy zdarzenia odpowiadające kliknięciu na każdej z nich. Zacznijmy od mnuPokaz - klikamy na nim 2 razy. Wewnątrz funkcji wpisujemy:

IkonaTray.Visible = false;
this.Show();

this.WindowState = FormWindowState.Normal;

Posłuży ona do pokazania formy (po zminimalizowaniu będziemy ją ukrywać, ale o tym później) oraz ukrycia ikonki z traya.
Teraz ta sama procedura (podwójne kliknięcie) z mnuUstaw, wpisujemy kod:

this.Show();
this.WindowState = FormWindowState.Normal;
IkonaTray.Visible = false;

cmdUstaw_Click(sender, e);

Funkcja ta spowoduje pokazanie się okna programu oraz zostanie wywołany efekt kliknięcia w przycisk cmdUstaw. Oprogramujmy teraz ostatni element menu mnuWylacz. Będzie on po prostu wyłączać program za pomocą polecenia:

Application.Exit();

Menu już utworzone, zajmijmy się reprezentacją aplikacji w trayu. Odpowiedzialna jest za to kontrolka NotifyIcon. Dodajemy ją do formy i nazywamy IkonaTray. W katalogu z projektem znajduje się plik bell.ico. Użyjemy tej ikony jako ikonki do wyświetlania w trayu. Aby to zrobić wybieramy bell.ico we właściwości Icon dla kontrolki. Chcemy aby ikonka była widoczna tylko, gdy program będzie zminimalizowany (wtedy forma będzie niewidoczna), więc właściwość Visible ustawiamy na false. Aby menu, które utworzyliśmy było powiązane z IkonaTray, wybieramy jego nazwę w polu ContextMenuStrip. Dodajmy teraz obsługę dwóch zdarzeń dla ikony: MouseClick oraz MouseMove. W kodzie pierwszego wpisujemy:

if (e.Button == MouseButtons.Left)
    mnuPokaz_Click(sender, e);

Innymi słowy po kliknięciu lewym przyciskiem myszy na ikonce wywołamy ten sam efekt co po wybraniu Pokaż w menu, czyli ukazanie się formy. W kodzie zdarzenia MouseMove wpisujemy:

IkonaTray.Text = "Czas: " + lblCzas.Text +
    "\nAlarm: " + lblAlarm.Text

@STRONA@

Gdy przytrzymamy myszkę nad obrazkiem w trayu pojawi nam się napis przechowywany we właściwości Text. Zdarzenie MouseMove będzie pilnować, aby etykieta ta zawierała aktualny.

Przejdźmy na chwilę do widoku kodu formy, dopiszmy w konstruktorze licznik.Start(); i dodajmy do formy następujące zmienne:

private DateTime alarm = new DateTime();
private DateTime teraz;
private bool gra = false;
private bool ustawiony = false;
private SoundPlayer dzwonek = new System.Media.SoundPlayer("whistle.wav");
private TimeSpan czastrwania = new TimeSpan(0, 1, 0);

private DateTime koniecalarmu;;

alarm posłuży do przechowywania czasu, w którym ma się uruchomić budzik. teraz będzie pomocniczą zmienną reprezentującą aktualny w danym momencie czas. gra będzie "wiedzieć" czy dzwonek budzika właśnie gra, ustawiony "powie nam" czy budzik jest ustawiony. dzwonek należący do klasy System.Media.SoundPlayer (nowość w .NET 2.0) będzie reprezentować melodię wykorzystywaną do budzenia. Plik whistle.wav, który ją zawiera, musi znajdować się w katalogu z programem. czastrwania przechowa długość trwania alarmu, a koniecalarmu będzie "wiedzieć", o której dzwonek ma przestać grać.

Wracamy do widoku graficznego formy i dodajemy kontrolkę Timer. Nazywamy ją licznik, właściwość Interval pozostawiamy bez zmian (100). Klikamy na kontrolkę dwa razy, aby utworzyło się zdarzenie Tick. W jego wnętrzu wpisujemy kod:

teraz = DateTime.Now;
lblCzas.Text = teraz.ToString("T");
if (ustawiony &&
    teraz.Hour == alarm.Hour &&
    teraz.Minute == alarm.Minute &&
    teraz.Second == alarm.Second && !gra)
{
    gra = true;
    mnuUstaw.Text = "Stop";
    cmdUstaw.Text = "Stop";
    koniecalarmu = DateTime.Now.Add(czastrwania);
    dzwonek.PlayLooping();
}
if (gra)
{
    if (koniecalarmu.Hour == teraz.Hour &&
        koniecalarmu.Minute == teraz.Minute &&
        koniecalarmu.Second == teraz.Second)
    {
        mnuUstaw.Text = "Ustaw";
        cmdUstaw.Text = "Ustaw";
        gra = false;
        dzwonek.Stop();
    }

}

Kod ten będzie kontrolował wyświetlanie aktualnego czasu, a w odpowiednim momencie uruchomi alarm. Jeśli budzik gra, to wyłączy go po upływie czasu zawartego w czastrwania (1 minuta). Do odgrywania pliku dźwiękowego używamy funkcji PlayLooping(), która będzie odtwarzać melodię w kółko. Zatrzymujemy ją przy pomocy metody Stop().

Zajmijmy się następnie przyciskiem cmdUstaw. Klikamy na nim dwa razy i wewnątrz zdarzenia wpisujemy:

if (cmdUstaw.Text == "Ustaw")
{
    cmdUstaw.Text = "OK";
    lblAlarm.Visible = false;
    txtAlarm.Visible = true;
    txtAlarm.Focus();
}
else if (cmdUstaw.Text == "OK")
{
    DateTime tmp = new DateTime();
    try
    {
        tmp = DateTime.Parse(txtAlarm.Text);
    }
    catch
    {
        lblAlarm.Text = "nie ustawiono";
        ustawiony = false;
        txtAlarm.Visible = false;
        lblAlarm.Visible = true;
        cmdUstaw.Text = "Ustaw";
        MessageBox.Show("Błąd", "Błąd", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return;
    }
    alarm = tmp;
    lblAlarm.Text = alarm.ToString("T");
    txtAlarm.Visible = false;
    lblAlarm.Visible = true;
    ustawiony = true;
    cmdUstaw.Text = "Ustaw";
}
else if (cmdUstaw.Text == "Stop")
{
    gra = false;
    dzwonek.Stop();
    cmdUstaw.Text = "Ustaw";
    mnuUstaw.Text = "Ustaw";

}

Przycisk obsługuje trzy swoje wersje. Pierwsza to taka, gdy wyświetlany jest napis Ustaw. Zmienia ona tekst na OK oraz ukrywa lblAlarm i pokazuje txtAlarm, dzięki czemu można wpisać nowy czas alarmu. Druga opcja - napis OK - akceptuje lub nie nowo wpisany czas. Robi to za pomocą bloku try {} catch {}, który służy do przechwytywania wyjątków. Próbuje przekształcić wpisany string na czas. Jeśli się nie uda, zostanie zgłoszony wyjątek, znów ukarze się lblAlarm i schowa txtAlarm. W przeciwnym wypadku nowy czas alarmu zostanie ustawiony oraz wyświetli się na odsłoniętej lblAlarm (txtAlarm stanie się niewidoczne). Ostatnia funkcja przycisku cmdUstaw - Stop - służy do zatrzymywania budzika, gdy alarm się rozlega. Identyczną rolę jak cmdUstaw pełni element menu mnuUstaw dlatego nazwy z Ustaw na Stop zmieniamy dla obydwu.

Na końcu oprogramujmy zdarzenie Resize dla formy. Zajmie się ono uniewidocznieniem okna aplikacji oraz pokazaniem ikonki w trayu. Oto jego kod:

if (this.WindowState == FormWindowState.Minimized)
{
    this.Hide();
    IkonaTray.Visible = true;

}

Tak oto ukończyliśmy kolejny program. Nauczyliśmy się korzystać z traya oraz z menu kontekstowych - bardzo ważnych elementów systemu Windows. Oprócz oczywistej funkcji budzenia, programik można wykorzystać również do np. poinformowania, o tym, że zaraz odjeżdża autobus czy nawet jako alternatywny dla windowskiego zegarka :)

Stworzony tutaj program wraz z plikami źródłowymi możemy pobrać stąd.

Jak wykorzystać Copilot w codziennej pracy? Kurs w przedsprzedaży
Jak wykorzystać Copilot w codziennej pracy? Kurs w przedsprzedaży

Wydarzenia