BETA
Aby się zalogować, najpiew wybierz portal.
Aby się zarejestrować, najpiew wybierz portal.
Podaj słowa kluczowe
Słowa kluczowe muszą mieć co najmniej 3 sąsiadujące znaki alfanumeryczne
Pole zawiera niedozwolone znaki

Baza wiedzy











Program rezydujący w obszarze powiadomień – prosta implementacja

09-05-2004 00:17 | User 79315

Kilka słów wprowadzenia...

Kilka dni temu pomyślałem sobie, że fajnie by było mieć taki mały program, który byłby widoczny tylko w obszarze powiadomień i co jakiś czas sprawdzał stan mojego konta pocztowego pod względem ilości wiadomości. Wiem, że w Internecie takich programów jest pewnie na pęczki, ale pomyślałem sobie, że mógłbym równie dobrze sam sobie coś takiego napisać wykorzystując platformę .NET. Za chwilkę pokażę Wam co mi z tego wyszło...

Zaczynamy...

Pierwszą rzeczą jaką musimy zrobić to stworzenie nowego projektu w Visual Studio .NET. Wybieramy File -> New -> Project i w okienku wybieramy WindowsApplication. Nazwijmy teraz nasz projekt. Niech będzie: „Dręczyciel” :D.

Teraz przystosujemy nasz formularz do pracy w obszarze powiadomień. Po pierwsze okno formularza głównego będzie cały czas niewidoczne. Aby to osiągnąć ustawiamy dwie jego właściwości. Pierwszą z nich jest WindowState, którą ustawiamy na Minimized, co oznacza, że zaraz po starcie okno naszej aplikacji będzie zminimalizowane.

Rys.1. Ustawienie właściwości WindowState

Jednakże będzie ono widoczne na pasku zadań. Chcąc tego uniknąć ustawiamy drugą właściwość formularza. Nazywa się ona ShowInTaskbar.

Rys.2. Ustawienie właściwości ShowInTaskbar

Osiągnęliśmy cel. Nasza aplikacja nie jest już widoczna. Jednak to nie wszystko. Zauważmy, że gdy uruchomimy teraz ten projekt nie zobaczymy nic. Jedynym miejscem, w którym znajdziemy naszą uruchomiona aplikację będzie Menedżer zadań windows dostępny po naciśnięciu Ctrl + Alt + Del. To nie jest to czego chcieliśmy. Brakuje nam jeszcze ikony w obszarze powiadomień.

Sposób na to jest prosty. Wystarczy z umieszczonego po lewej stronie Toolbox’a przeciągnąć na nasz formularz obiekt NotifyIcon. Warunkiem koniecznym aby coś pojawiło się o obszarze powiadomień jest przypisanie mu ikony. Wystarczy polu Icon przypisać plik z ikoną.

Rys. 3. Przypisanie ikonki do pola Icon

Pierwszy etap skończyliśmy. Mamy już program, który wyświetla ikonę w obszarze powiadomień.

Rys. 4. Uruchomiona aplikacja w obszarze powiadomień

Etap drugi – komunikacja z programem.

Nasz program nie będzie miał okna głównego, a my musimy się przecież z nim jakoś komunikować (chociażby po to by móc mu powiedzieć: „teraz się zamknij”). Posłuży nam do tego menu kontekstowe. Aby takowe stworzyć wystarczy przeciągnąć na nasz formularz obiekt ContextMenu. Rozbudujmy teraz nieco nasze menu. W trybie projektu robi się to bardzo prosto. Wystarczy kliknąć obiekt contextMenu1 widoczny na dole strony a następnie na formularzu wypełnić pola menu jak na obrazku:

Rys. 5. Budowa menu kontekstowego

Kliknijmy teraz dwa razy na element menu zatytułowany ‘Wyjście’. Zostanie stworzona metoda obsługująca kliknięcia na ten element. Chcielibyśmy, aby po kliknięciu nasz program zakończył działanie. Wystarczy zatem wywołać metodę Exit() klasy Application.

private void menuItem4_Click(object sender, System.EventArgs e)
{
     Application.Exit();
}

Ostatnią rzeczą, która należy zrobić by nasze menu kontekstowe było dostępne jest przypisanie go do obiektu notifyIcon1:

Rys. 6. Przypisanie menu kontekstowego do ikonki obszaru powiadomień

Jeżeli teraz uruchomimy aplikację powinna ona dać się bez problemu wyłączyć poprzez menu kontekstowe.

Stwórzmy teraz nowy formularz, na którym będziemy prezentowali komunikaty od serwera POP3. Będzie to małe okienko zawierające jedynie pole tekstowe pokrywające całą jego powierzchnię. Niech się nazywa Messages. Ten formularz będzie wywoływany z menu kontekstowego. Użyjemy do tego jego metod Show() i Hide(). Nową instancję formularza Messages utworzymy już w konstruktorze formularza głównego.

this.msgForm = new Messages();

Teraz w metodzie obsługującej kliknięcie na element menu ‘Pokaż okno’ napiszemy:

private void menuItem1_Click(object sender, System.EventArgs e)
{
     this.msgForm.Show();
}

Musimy jeszcze umieć to okno schować. Użyjemy do tego celu zdarzenia Closing formularza, które jest wywoływane tuz przed zamknięciem okna.

private void Messages_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
     //chowamy okno
     this.Hide();
     //anulujemy zdarzneie
     e.Cancel = true;
}

Ważnym jest aby nie pozwolić na wykonanie się metody Close() okna. Dlatego anulujemy zdarzenie (e.Cancel = true). Gdybyśmy tak nie zrobili obiekt naszego okna zostałby zniszczony i ponowne wywołanie metody Show() skończyłoby się zgłoszeniem wyjątku. A tak będziemy mogli wielokrotnie pokazywać i chować okno Messages. Dla porządku ustawmy jeszcze

//schowaj przycisk maksymalizacji
this.MaximizeBox = false;
//schowaj przycisk minimalizacji
this.MinimizeBox = false;

w Messages, a to po to by wymusić chowanie okna przez naciśnięcie krzyżyka w jego prawym górnym rogu.

Etap trzeci – przekazywanie wartości między formularzami

Do przekazywania różnych wartości między formularzami użyjemy zdarzeń i delegatów. Stworzyłem specjalną klasę o nazwie ServerMsgEventArgs:

public class ServerMsgEventArgs : EventArgs
{
     private readonly string msg;
     public ServerMsgEventArgs( string msg )
     {
          this.msg = msg;
     }
     public string Message
     {
          get{ return this.msg; }
     }
}

a także specjalnego delegata:

public delegate void ServerMsgEventHandler( object sender, ServerMsgEventArgs e );

Klasa ta posłuży do przekazywania argumentu zdarzenia (w naszym przypadku komunikatu od serwera w postaci napisu).

W komunikacji z serwerem pośredniczyć będzie klasa POP3, która zawiera metody do łączenia i rozłączania się z serwerem, a także do pobierania liczby wiadomości znajdujących się w skrzynce (pominę sposób jej implementacji, gdyż to by jedynie zaciemniło obraz). Nową instancję tej klasy tworzymy podobnie jak okno Messages w konstruktorze okna głównego.

this.p = new Pop3("serwer", "użytkownik", "hasło");

To właśnie metody tej klasy będą odbierały komunikaty od serwera. My chcielibyśmy, aby te komunikaty trafiły do okna Messages. W tym celu w klasie POP3 zdefiniujemy zdarzenie  SrvMsg, które będzie uruchamiane, gdy nadejdzie jakaś wiadomość od serwera.

public event ServerMsgEventHandler SrvMsg;

Zauważmy, że użyliśmy tutaj delegata stworzonego wcześniej w tym artykule. Potrzebna jest nam jeszcze metoda za pomocą której będzie można wywołać zdarzenie.

protected virtual void OnMessage( ServerMsgEventArgs e )
{
     //jeżeli mamy jakichś słuchaczy to wywołaj ich
     if( SrvMsg != null)
     {
          SrvMsg( this, e );
     }
}

Teraz jeżeli którakolwiek metoda chce przesłać odebraną wiadomość wystarczy, że wywoła metodę OnMessage w taki sposób:

this.OnMessage( new ServerMsgEventArgs( "wiadomość" ) );

Zaimplementujemy teraz metodę dla klasy formularza Messages, która będzie dodawała tekst do pola tekstowego w nim umieszczonego. Dodatkowo nagłówek tej metody będzie tak dobrany, by spełniał wymagania delegata ServerMsgEventHandler, co pozwoli na ją ‘podpiąć’ do zdarzenia SrvMsg klasy POP3.

public void putSrvMsg(object sender, ServerMsgEventArgs e)
{
     //dodajemy do pola tekstowego wiadomość niesioną przez zdarzenie
     this.richTextBox1.AppendText( e.Message.ToString() + "\n" );
     //odświeżamy pole
     this.richTextBox1.Update();
}

Teraz wystarczy już tylko podpiąć naszą metodę do zdarzenia obiektu klasy POP3. Robimy to w konstruktorze formularza głównego.

p.SrvMsg +=new ServerMsgEventHandler( this.msgForm.putSrvMsg );

Analogicznie w klasie POP3 stworzone jest zdarzenie, poprzez które będzie podawana liczba wiadomości w skrzynce, a w konstruktorze formularza głównego podpięta jest pod nie odpowiednia funkcja zmieniająca napis wyświetlający się po najechaniu myszką na ikonę programu w obszarze powiadomień.

private void p_NoMsg(object sender, ServerMsgEventArgs e)
{
     this.NotifyIcon.Text = "Masz " + e.Message.ToString() + " wiadomości.";
}

Pozostało nam jedynie dodać obsługę kliknięcia na element menu ‘Sprawdź’.

private void menuItem2_Click(object sender, System.EventArgs e)
{
//wywołanie metody pobierającej ilość wiadomości
     GetNoM();
}

Tak zbudowana aplikacja będzie już potrafiła sprawdzić ilość wiadomości na nasze żądanie (wybranie z menu ‘Sprawdź’).

Etap ostatni – wywoływanie sprawdzania stanu kont w pewnych odstępach czasowych

Posłuży nam do tego obiekt klasy Timer. Przeciągnijmy go z paska po lewej stronie na nasz formularz główny. We właściwościach ustawiamy Interval – określający długość odstępu między wywołaniami funkcji w milisekundach.

Rys. 7. Ustawienie długości trwania odstępu między wywołaniami funkcji

Teraz wybierając zakładkę Events w polu Tick ustalamy funkcję, która będzie wywoływana. Ta funkcja oczywiście ma nam wywołać metodę, która sprawdzi ile mamy wiadomości.

private void CheckMailTimer_Tick(object sender, System.EventArgs e)
{
     GetNoM();          
}

Rys. 8. Wskazanie funkcji do wywołania

Słowo na koniec

Udało się. Wyrażałem się możliwie najjaśniej i mam nadzieję, że przynajmniej część z Was coś z tego artykułu wyniosła. Ja jestem zadowolony. Aplikacja działa i jest dla mnie pożyteczna.

Bartłomiej Legiędź

Załączniki:

Podobne artykuły

Komentarze 35

User 80305
User 80305
31 pkt.
Poczatkujacy
21-01-2010
oceń pozytywnie 0
Przyjemny artykuł dla początkujących
User 79209
User 79209
2 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
+ Ciekawy pomysl, z jeszcze lepsza nazwa ;)
+ Moze nie zawiera multum informacji, ale krok po kroku pokazuje, jak umiescic swoj program w trayu i jak potem z niego korzystac
+ Dokaldny opis jak sie definiuje i uzywa wlasne zdarzenie
- NoMsg srednio intuicyjne informuje o tym, ze dotyczy ilosci wiadomosci, a tak BTW to uzywanie az takich(podwojnych) skrotow nie jest najlepszym pomyslem
- Nazewniczy miszmasz: pobieranie i msgForm
rysiek146
rysiek146
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Prosty opis i niema niepotrzebnego zamieszania, Uzyteczny artykul - od czasu do czasu robi sie aplikacje z ikonka w tray-u, Screeny i wycinki kodu - przez co wiadomo o czym jest mowa.
_qbens
_qbens
13 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Bardzo przyjemny opis tworzenia aplikacji działającej w trayu oraz sposobu z nią komunikacji. Jasny i dokładny opis bez zbędnych zaciemnień. Jeśli chodzi o samą aplikację to przydałaby się możliwość konfiguracji (server, user, pass), chociażby jako parametry uruchomienia z wiersza poleceń (ale to rzecz jasna nie umniejsza wartości artykułu;)).
User 80016
User 80016
23 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Teraz już wiem jak robić aplikacje z wykorzystaniem traya.
corkarzeznika3249
corkarzeznika3249
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Prosty program, a tyle radości :) Wreszcie się dowiedziałam jak to ma wyglądać.
pjanet171
pjanet171
11 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Dobry pomysł i tekst. Łopatologia ale dla kogoś kto zaczyna zabawe z C# i WinForm super sprawa do nauki.
Włodzimierz Bielski
Włodzimierz Bielski
10 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Proste, a pozyteczne. Brawo, Bartek! :-)
BezPseudonimu
BezPseudonimu
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Bardzo jasny i przejrzysty artykuł. Pisany na jednolitym poziomie. Bardzo mi się podobał.
User 81423
User 81423
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Właśnie takich informacji poszukiwałem. Jasno i przyjemnie wytlumaczonych.
czerni5865
czerni5865
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Bardzo ładnie. Szkoda tylko, że tak mały program zajmuje 12 MB pamięci ... ale to jest już niezależne od autora. 6 za fajny opis!
User 79899
User 79899
35 pkt.
Poczatkujacy
21-01-2010
oceń pozytywnie 0
Takie ciekawostki zawsze mi sie podobają. Czekam na jeszcze :). Szósteczka ode mnie.
Paczeek
Paczeek
253 pkt.
Junior
21-01-2010
oceń pozytywnie 0
Jak dla mnie jest OK :)
vSzemkel
vSzemkel
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Obiekt klasy Messages tworzony jest przez inny wątek, niż ten który wykonuje metodę Messages.putSrvMsg Generalnie jeden wątek utworzył kontrolkę, a drugi po niej pisze. Teoretycznie to złe rozwiązanie, a jednak w tym przypadku niewątpliwie działa. Może ktoś mnie oświeci. Można tak pisać, czy trzeba wywoływać if (Control.InvokeRequired) ...
artwordnet6423
artwordnet6423
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Naprawde fajnie napisany artykuł, w zrozumiały sposób.
User 79561
User 79561
1 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Jest ok.
koltys
koltys
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Ciekawe, oryginalne i przydatne. Bardzo mi pomógł ten artykuł. Polecam.
kasprzol
kasprzol
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Bardzo przyjemny artykuł.
User 82272
User 82272
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Fajny pomysl i ciekawe wykonanie Programik mały zgrabny i przydatny HeHeHe Widac od razu że bez przegięć :):):)
User 131096
User 131096
189 pkt.
Junior
21-01-2010
oceń pozytywnie 0
Ciekawa realizacja :)
daniel_d
daniel_d
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Powaliła mnie lekkość opisu klikologii stosowanej (tak, tak - początek artykułu). Po prostu rewelacja ;-)))
User 79130
User 79130
9 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Fajne dla początkujących. Dla nieco bardziej doświadczonych troche za dużo klikologii. :)
testa1435
testa1435
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Dobry, ciekawy artykuł.
michalsznajder83
michalsznajder83
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Nudy nudy nudy. Powielanie helpa.
mluzyna2192
mluzyna2192
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Nuda nuda nuda
gm7467
gm7467
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
dla mnie porażka....
konrad.madej
konrad.madej
4 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Odkąd pamiętam były z tym problemy. Najpierw Delphi, ateraz C#. A tu wszystko jak na dłoni. Super.
jizz1237363
jizz1237363
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Milo sie to czytalo.
User 79357
User 79357
22 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Ciekawy przyklad, fajny styl opisu rekompensuja niezbyt trudny temat.Wg. mnie najlepszy artykul w tym miesiacu (razemn z art. o SQL CE). Odnosnie sytuacji jaka jest na CG w tej chwili: nalezy zmienic system oceniania, zablokowac mozliwosc glosowania w ramach jednej uczelni (nie tylko w ramach kola), mozliwosc oddawania glosow powinni miec uzytkownicy, ktorzy publikowali juz swoje artykuly (w zaleznosci od ilosci moznaby wprowadzic zroznicowane wagi). Jestem zniesmaczony dawaniem 1 itp. ale to jest konsekwencja zlego systemu i sytuacji z maja (ocenianie na 7 artykulow kolegow bez wzgledu na tresc), wiec jesli jedno kolko tak zaczelo robic to drugie sie dolaczylo (fakt ze duzo bardziej przeginajac). A odnosnie jednej wypowiedzi o "warszawiakach" to jedynki, ktore dostales z komentarzem "nuda" byly z zupelnie innego kola (tego "pokrzywdzonego"). No i czemu warszawiacy jak do tej pory dobrze oceniali twoj artykul a zle osoby, ktora widzi wielki spisek? Ogolnie jedna wielka parodia...
misto2191
misto2191
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Przepraszam Bartek. Nie czytalem, przyznaje sie bez bicia (sciemniac jak cala reszta nie bede), ale chce zeby wygral ten artykul, wiec daje 7em. (zeby wynik tego konkursu byl uczciwy, chyba bedziecie musieli wyciac tez oceny "Innych"...)
DonDoman
DonDoman
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Moze i temat oklepany, ale zawsze aktualny. Artykul za to napisany bardzo przystępnie, porządnie.
User 79538
User 79538
2 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Fajny, artykuł, no i oczywiście informacje, których szukałem, ale nie miałem czasu znaleźć :)
fila
fila
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Ciekawy i pozyteczny problem. Artykul prosty, prowadzacy za reke.
agciajan4284
agciajan4284
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Artykul napisany ciekawie,przystepnym jezykiem. Krotko,zwiezle i na temat. I o to wlasnie chodzi.
ja_raz141
ja_raz141
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
za prawdziwy tutorial oraz wzorowa postawe w goracych momentach glosowania... btw: administratora portalu oceniam na mniej niz zero w zwiazku z samoskompromitowaniem sie zwiazanym z nieuzasadnionym naruszeniem regulaminu konkursu. skandal...
pkt.

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.