UWAGA! Promocja dla firm - MICROSOFT OFFICE 365  na 12 miesiecy ZA DARMO! Tylko na CentrumXP.pl!
Wielka promocja Office 365 na CentrumXP.pl!
Do góry Skomentuj

Budzik w C#

Budzik w C#

Autor: Marcin Hałaczkiewicz Opublikowano: 20 maja 2006 Odsłon: 101 993

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

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.

Zobacz również

Komentarze

Bardzo jasno i wyraźnie napisane Przyda sie :) Pozdro dla redakcji!
Buddy, 21 maja 2006, 20:06
Przydał by się jeszcze gotowy projekt do ściągnięcia.
Anonim, 21 maja 2006, 22:00
uuu Anonim ty... skypto-podbierco-żerco
Anonim, 21 maja 2006, 22:40
Na 2. stronie artykułu, na samym dole jest link do gotowego projektu...
Kuba, 22 maja 2006, 07:27
Zarobiste poprostu kul ale nimam tego na kompie tylko gram se u kolegi ,ale jest bardzo fajne
Komentarz, 25 maja 2006, 17:26
Świetny tutorial! :) Naprawe sporo cennych informacji, minusem jest tylko niekiedy zła kolejność przedstawiania kodu (odwoływanie się do komponentow, zanim jeszcze je wsadzimy na formę), ale ogólnie tutek na 5+! :)
m010ch, 11 czerwca 2006, 15:45
Jeszcze dwie sprawy, o których w opisie nie wspomniałeś: TRZEBA zdefiniować jakąs ikonę dla komponentu IkonaTray (właściwość 'Icon'), w przeciwnym wypadku - mimo, iż program jest minimalizowany do traya, to w trayu go nie widać, ponieważ nie ma co go tam reprezentować. Druga sprawa to brak instrukcji 'this.Show();' dla kliku na elemencie menu 'mnuPokaz' - przez co forma wraca do postaci normalnej, ikonka znika z traya, ale forma nie jest pokazywana ;)
m010ch, 11 czerwca 2006, 15:58
Bardzo trafne uwagi - po drobnych poprawkach wszystko jest już ok. Zauważ, że były to jedynie niedopatrzenia w treści artykułu, w treści programu wszystko było tak jak być powinno.
Marcin Hałaczkiewicz, 12 czerwca 2006, 21:53
Bardzo dobry tutorialik :) Gratuluje !
fones, 25 czerwca 2006, 13:45
The BEST:):):):)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....................
KaSiA;), 28 czerwca 2006, 16:48
VS 2005 jest dla mnie nowym środowiskiem i mam problem w znalezieniu zdarzeń MauseMove i MauseClick w prperites IconaTay(co wynika z opisu). Gdzie jest konstruktor ? Z tego co się orietuje przy powoływaniu obiektu klasy uruchamiany jest konstruktor nazwany jak klasa tu kazdy przycisk ,label itp jest obiektem roznych klas i sorry za moje rozgarniecie ale nie widze jasno zadeklarowanego kodu konstruktora do ktorego mam wklepać kod :licznik.Start();
poczatkujący_a_jednak, 10 sierpnia 2006, 20:50
Super artykuł. Mam jednak pytanie. Po uruchomieniu program zajmuje w pamięci prawie 10 mb, po minimalizacji i dalszym użytkowaniu już mniej. Wiecie może co jest przyczyna?
WoojO, 17 sierpnia 2006, 00:04
Jestem poczatkujacy i ciezko jakos wychodzi rozumienie kodu. Co prawda pod kodem albo przed nim jest zawsze wyjasnienie ale bardziej zrozumiale by byly komentarze w kodzie z opisem co do czego a przynajmniej tak mi sie wydaje. W kodzie odwolujemy sie czesto do czegos co jeszcze nie istnieje przez co trzeba recznie cale wpisac a przy debugowaniu sa informacje ze odwolujemy sie do czegos co nie istnieje ale tylko jednego nie da sie zrobic i to opisanego na samym poczatku: aby w AcceptButton ustawic cmdUstaw najpierw musimy go nanies na forme a nie odwrotnie. Tutorial chyba rozni sie od gotowego projektu np zmieniamy tutaj nazwe formy a w gotowym tego nie ma... Problem mialem z SoundPlayerem gdyz aby go urzyc po pierwsze trzeba dodac using System.Media a nie widze tego w tutorialu no i z wgraniem wave w odpowiednie miejsce gdyz wskazowka "do projektu" nie jest scisla gdyz nalezy go umiescic w \bin\debug poczatkujacy_a_jednak: MouseMove i MouseClick znajdziesz w Properties i Events(to taka zolta blyskawica) konstruktor ktorego szukasz to fragment kodu: public frmBudzik() { InitializeComponent(); licznik.Start(); }
Adam, 28 sierpnia 2006, 19:49
hey, mam trzy pytanka do programu: 1) deklarujemy 4 zmienne typu DateTime ale tylko przy dwoch jest "= new DateTime();" - dlaczego?? 2) przy konwersji czasu na stringa podajemy ("T") - jw 3) TimeSpan(0, 1, 0) - co oznaczja kolejne cyfry ??
Adam, 29 sierpnia 2006, 13:19
pod drugim obrazkiem zrobiłeś błąd: napisałeś "ukarzą"
:D, 14 sierpnia 2007, 20:50
Well done ... :)
Fuku, 26 września 2007, 00:52
Ogólnie świetna sprawa, fajnie, że coś takiego jest! Jest parę rzeczy, które drażnią, np odwoływanie się obiektów, metod, których jeszcze nie ma. Dla osoby, która z programowaniem już miała kontakt nie będzie to wielką przeszkodą natomiast dla osoby świeżej będzie to zupełne zagmatwanie kodu. Taka osoba będzie się zastanawiała co to jest, skąd się to wzięło itd.
Paweł, 9 listopada 2007, 09:09
Ogólnie bardzo spoko ale dopatrzyłem się drobnego błędu - mało znaczącego ale jednak. Mianowicie timer "licznik" powinien być ustawiony na 1000ms a nie na 100ms. Dlaczego? Otóż w sekundzie, w której włącza się alarm, program rozpoczyna odgrywanie dźwięku 10-krotnie, ponieważ licznik sprawdza czas co 100ms, a więc 10 razy na sekundę. Niepotrzebnie, bo wystarczy jeden raz na sekundę, czyli timer powinien być ustawiony na 1000ms. Ten błąd może denerwować w przypadku kiedy chcemy zastąpić dźwięk np. jakimś komunikatem - okienko pojawia się wtedy na ekranie 10 razy. Pozdro 4all ;))
Arturrrro, 20 marca 2008, 19:42
"wpisujemy Budzik we właściwości Text formatki." A dokładniej?
misiekk, 17 sierpnia 2008, 16:45
Dodałem swój plik dźwiękowy i po publikacji i instalacji w czasnie uruchamiania dźwieku wyskakuje błąd:
System.IO.FileNotFoundException: Sprawdź, czy plik dźwiękowy istnieje w podanej lokalizacji.

mtt, 4 października 2008, 19:04
Dokaladnie dobrze ktos napisal! Dlaczego odwolujecie sie najpierw do czegos co nie jest stworzone! To wszystko mega miesza!

Ale ogolnie tutorial siwetny choc bym w nim troche poprawila np te bledy ze brakuje srednika albo sa dwa... Ale to szczegoly bo sie wie o co chodzi najgorzej jak nagle pisze jakies odwolanie do czegos czego jeszcze nie mam:/


Canim, 18 października 2008, 13:59
Nie jest jasno napisane co trzeba zrobic... Jestem poczatkujacym w C# i juz nie rozumiem tego:"We właściwościach Text pierwszych dwóch wpisujemy Alarm i Czas, ich nazwy są nieistotne." Gdzie to jest?!

gosc, 8 czerwca 2009, 18:28
Padają tutaj pytania RETORYCZNE!!!!!!!!!!!!! Nie zadam kolejnego :|

gregor, 7 lipca 2009, 13:23
Wszystko działa poprawnie :) Idzie się pobawić :D

Mimek, 31 lipca 2009, 13:17
zastanawia mnie po co ten kurs jest skoro nie wprowadza po kolei wszystkich elelementów wykorzystanych w programie żeby ci co już C# znają mogli się upewnić że potrafią budzik stworzyć?
lol, 30 października 2011, 11:28

Dodaj swój komentarz

Zasady publikacji komentarzyZasady publikacji komentarzy

Redakcja CentrumXP.pl nie odpowiada za treść komentarzy publikowanych na stronach Portalu
i zastrzega sobie prawo do usuwania wypowiedzi, które:

  • zawierają słowa wulgarne, obraźliwe, prowokujące i inne naruszające dobre obyczaje;
  • są jedynie próbami reklamowania stron internetowych (spamowanie poprzez umieszczanie linków);
  • przyczyniają się do złamania prawa bądź warunków licencyjnych oprogramowania (cracki, seriale, torrenty itp.);
  • zawierają dane osobowe, teleadresowe, adresy mailowe lub numery GG;
  • merytorycznie nie wnoszą nic do dyskusji lub nie mają związku z tematem komentowanego newsa, artykułu bądź pliku.

Autor:

Komentarz:

Dodaj komentarz