Wykorzystanie komponentu Timer i kontrolki PictureBox

Stronę tą wyświetlono już: 293 razy

Tym razem stworzę kolejny prosty projekt programu o nazwie Zegar. Chyba nazwa jest na tyle jasna, że wiadomo co ten program będzie robił. Dzięki temu projektowi poznamy podstawy rysowania, tworzenia bitmapy, wykorzystania kontrolki PictureBox oraz komponentu Timer.

Widok projektu okna programu.
Rys. 1
Widok projektu okna programu.

W właściwościach okna głównego programu należy zmienić pole (Name) z Form1 na Zegar i to samo należy uczynić z polem Text. Również rozmiar okna Size powinien zostać ustawiony na 312; 336. Tę samą wartość przypisać należy do pola MaximumSize i MinimumSize, co zablokuje możliwość zmiany wymiarów okna programu.

Warto też zmienić nieco właściwości wstawionej kontrolki PictureBox. Tak więc dla pola (Name) wpisać pb_drawing.

Kod programu należy zmodyfikować w następujący sposób:

Listing 1
  1. namespace Zegar
  2. {
  3. public partial class Zegar : Form
  4. {
  5. System.DateTime t; // zmienna, która będzie przechowywała czas
  6. Graphics gr; // interfejs graficzny do rysowania
  7. Bitmap bmp; // bitmapa, na której zegar będzie rysowany
  8. public Zegar()
  9. {
  10. InitializeComponent();
  11. t = System.DateTime.Now; // pobieranie aktualnego czasu
  12. timer1.Interval = 1000; // interwał dla zegara w milisekundach
  13. timer1.Start(); // uruchomienie zegara
  14. bmp = new Bitmap(300, 300); // tworzenie bitmapy 300 na 300 px (bo na cóż nam większa)
  15. gr = Graphics.FromImage(bmp); // tworzenie kontekstu graficznego, który będzie powiązany z otrzymaną bitmapą
  16. }
  17. private void DrawCircle(int xc, int yc, int ray, Color fill, Color pen) // a to będzie funkcja rysująca okręgi
  18. {
  19. Brush b = new SolidBrush(fill); // tak się tworzy wypełnienie
  20. gr.FillEllipse(b, xc - ray, yc - ray, 2 * ray, 2 * ray); // tak się rysuje wypełnioną elipsę
  21. Pen p = new Pen(pen, 2); // tak się tworzy pędzel
  22. gr.DrawEllipse(p, xc - ray, yc - ray, 2 * ray, 2 * ray); // a tak się rysuje obrys elipsy
  23. b.Dispose(); // zwalnianie wypełnienia
  24. p.Dispose(); // zwalnianie pędzla
  25. }
  26. }
  27. }

Dodać należy dwa zdarzenia, pierwsze dotyczące kontrolki pb_drawing dotyczyć będzie odrysowania Paint:

Listing 2
  1. private void pb_drawing_Paint(object sender, PaintEventArgs e)
  2. {
  3. DrawCircle(150, 150, 130, Color.FromArgb(255, 220, 220, 220), Color.FromArgb(255, 150, 150, 150));
  4. DrawCircle(150, 150, 120, Color.FromArgb(255, 255, 255, 255), Color.FromArgb(255, 150, 150, 150));
  5. int ray = 100;
  6. for (int i = 0; i < 12; i++) // Rysowanie punktów skali godzin
  7. {
  8. double angle = Math.PI / 6 * i; // wyliczanie kąta dla danej godziny (i = 0 - oznacza godzinę 0 lub 12; i = 1 - oznacza godzinę 1 lub 13 itd
  9. int x = (int)(150 + ray * Math.Sin(angle)); // obliczanie współrzędnej x
  10. int y = (int)(150 + ray * Math.Cos(angle)); // obliczanie współrzędnej y
  11. DrawCircle(x, y, 5, Color.Black, Color.Black); // rysowanie okręgu
  12. }
  13. for (int i = 0; i < 60; i++) // Rysowanie punktów skali sekundnika i minutnika
  14. {
  15. double angle = Math.PI / 30 * i;
  16. int x = (int)(150 + ray * Math.Sin(angle));
  17. int y = (int)(150 + ray * Math.Cos(angle));
  18. DrawCircle(x, y, 2, Color.White, Color.Black);
  19. }
  20. // Rysowanie wskazówki godzin
  21. Pen p = new Pen(Color.Black, 3);
  22. ray = 50;
  23. double angle2 = (double)((this.t.Hour % 12) * 60 + t.Minute) / 360.0 * Math.PI;
  24. gr.DrawLine(p, 150, 150, (int)(150 + ray * Math.Sin(angle2)), (int)(150 - ray * Math.Cos(angle2)));
  25. // Rysowanie wskazówki minut
  26. p.Dispose();
  27. p = new Pen(Color.Black, 2);
  28. angle2 = (double)(t.Minute * 60 + t.Minute) / 1800.0 * Math.PI;
  29. ray = 80;
  30. gr.DrawLine(p, 150, 150, (int)(150 + ray * Math.Sin(angle2)), (int)(150 - ray * Math.Cos(angle2)));
  31. // Rysowanie wskazówki sekund
  32. p.Dispose();
  33. p = new Pen(Color.Black, 1);
  34. angle2 = (double)t.Second / 30.0 * Math.PI;
  35. ray = 80;
  36. gr.DrawLine(p, 150, 150, (int)(150 + ray * Math.Sin(angle2)), (int)(150 - ray * Math.Cos(angle2)));
  37. p.Dispose();
  38. e.Graphics.DrawImage(bmp, new Point(0, 0));
  39. }

Drugie zdarzenie związane jest z komponentem Timer, które przyjmuje nazwę Tick:

Listing 3
  1. private void timer1_Tick(object sender, EventArgs e)
  2. {
  3. t = System.DateTime.Now;
  4. this.pb_drawing.Invalidate();
  5. }

Teraz pozostało już tylko najtrudniejsze, czyli wciśnięcie F5, co powinno spowodować pojawienie się okna programu jak na poniższym rysunku.

Program zegar
Rys. 2
Program zegar.

Komentarze