Zegarek

Strona g│≤wna

 

Zegarek

Poni┐szy kod jest do╢µ specyficzny. Nie jest to typowy algorytm lecz rozwi▒zanie pewnego nurtuj▒cego wielu ludzi problemu. Kod ten bowiem pozwala kontrolowaµ czas w systemie. Pobiera on czas z systemu, a nastΩpnie rozdziela go na poszczeg≤lne zmienne - sekundy, minuty, milisekundy, godziny tak, ┐e mo┐na kontrolowaµ zachowanie programu - np. chcia│by╢, aby jaki╢ kod wykonywa│ siΩ co p≤│ godziny, co godzinΩ lub co minutΩ - nie ma problemu - dziΩki poni┐szemu kodowi bΩdzie to proste. Wykorzystamy do tego celu w▒tki

Wa┐ne czynno╢ci wykonywa│ wiΩc bΩdzie w▒tek zawarty w osobnym module - ClockUnit. Na pocz▒tek wygl▒d samej struktury: 

Listing 10.1


type
  TTimeEvent = procedure of object;  // nowy typ procedury
{
 Jak widzisz kod tej klasy to watek. Zasada dzialania jest prosta - procedura
 GetTime pobiera czas i odpowiednio go rozdziela pomiedzy rozne zmienne.
 Nastepnie zmienne sa porownywane i generowane sa odpowiednie zdarzenia.
}
  TClock = class(TThread)
  private
    FHour, FMinute, FSecond, FMilSec : Word; // zmienne zawieraja godzine, minuty itp.
    FOnHour, FOnMinute, FOnSecond, FOnMilisecond, FOnHalf : TTimeEvent; // zdarzenia
    FDateTime : TDateTime; // pobrany czas
    procedure GetTime;  // pobiera aktualny czas
  protected
    procedure Execute; override;
  published
    property Milisecond : Word read FMilSec; // wlasciwosc zawiera aktualny czas ( w milisekundach )
    property Second : Word read FSecond;  // sekundy
    property Minute : Word read FMinute; // minuty
    property Hour : Word read FHour; // godziny
    property DateTime : TDateTime read FDateTime; // aktualny czas
  { Zdarzenia }
    property OnMilisecond : TTimeEvent read FOnMilisecond write FOnMilisecond;
    property OnSecond : TTimeEvent read FOnSecond write FOnSecond;
    property OnMinute : TTimeEvent read FOnMinute write FOnMinute;
    property OnHour : TTimeEvent read FOnHour write FOnHour;
    property OnHalf : TTimeEvent read FOnHalf write FOnHalf;
  end;

Klasa ta mo┐e wygl▒daµ do╢µ przera┐aj▒co, ale w sumie kodu bΩdzie do╢µ ma│o. Na to co warto zwr≤ciµ uwagΩ jest to, ┐e zadeklarowany zosta│ nowy typ bΩd▒cych procedur▒. NajwiΩcej w│a╢ciwo╢ci jest w sekcji Published gdy┐ zawarte s▒ tam zdarzenia. Zobacz, ┐e w sekcji Implementation kodu jest ma│o - zaledwie dwie procedury:

Listing 10.2


procedure TClock.Execute;
begin
  FreeOnTerminate := TRUE; // zwolnij po zakonczeniu
  //kontynuuj az do zakonczenia dzialania programu
  while not (Application.Terminated) or (Terminated) do 
  begin
    Sleep(1000); // czekaj sekunde
    GetTime; // pobierz czas - wywolanie procedury
    OnSecond; // wywolanie zdarzenia wystΩpuj▒cego co sekunde
    if (FMinute =  0) and (FSecond = 0) then OnHour; // generowanie zdarzenia godzinnego
    if (FMinute = 30) and (FSecond = 0) then OnHalf; // wystepuje co pol godziny
    if (FSecond = 0) then OnMinute;  // wystepuje co minute
  end;
end;

procedure TClock.GetTime;
begin
  FDateTime := Now;  // pobierz aktualny czas
  DecodeTime(FDateTime, FHour, FMinute, FSecond, fMilSec); // rozdziel go na poszczegolne zmienne
end;

Druga procedura pobiera aktualn▒ datΩ i czas, a nastΩpnie rozdziela czas pomiΩdzy r≤┐ne zmienne zawieraj▒ce warto╢ci godziny, minut, sekund oraz milisekund. 

Pierwsza procedura Execute to w▒tek. Jest on kontynuowany do czasu zako±czenia programu - nastΩpnie odczekuje sekundΩ poczym wywo│uje procedurΩ GetTime, a nastΩpnie por≤wnuje zmienne. Je┐eli zmienna FMinute ma warto╢µ 0 to znaczy, ┐e zmieni│a siΩ godzina - generowane jest w≤wczas zdarzenie OnHout. Itd...

Teraz w swoim programie musisz stworzyµ procedury, kt≤re bΩd▒ obs│ugiwaµ zdarzenia, kt≤re wystΩpuj▒ co godzinΩ, sekundΩ, minutΩ i o wp≤│ do. 

Oto te procedury:

Listing 10.3


procedure TMainFormU.FHalf;
begin
{ W przypadku wystapenia zdarzenia wyswietla tekst na pasku stanu }
  HelpBar.SimpleText := Format('Jest w p≤│ do: %d', [Clock.Hour]);
end;

procedure TMainFormU.FHour;
begin
{ Wyswietl co godzine: }
  HelpBar.SimpleText := Format('Mine│a godzina: %d', [Clock.Hour]);
end;

procedure TMainFormU.FMinute;
begin
{ Wyswietl co minute }
  HelpBar.SimpleText := Format('Mine│a ju┐ kolejna: %d minuta', [Clock.Minute]);
end;

procedure TMainFormU.FSecond;
begin
{ Wyswietl co sekunde - pobiera czas z wlaciwosci DateTime }
  pnlTime.Caption := TimeToStr(Clock.DateTime);
end;

Nie robi▒ one nic specjalnego - po prostu na pasku ( komponencie ) StatusBar wy╢wietlaj▒ odpowiednie informacje. 

Natomiast w procedurze OnCreate programu musisz wpisaµ co╢ takiego:

Listing 10.4


procedure TMainFormU.FormCreate(Sender: TObject);
begin
  Clock := TClock.Create(False);
{ Przypisanie procedur zdarzeniowych }
  Clock.OnSecond := FSecond;
  Clock.OnMinute := FMinute;
  Clock.OnHour := FHour;
  Clock.OnHalf := FHalf;
end;

W tej procedurze nastΩpuje przypisanie odpowiednich zdarze± do procedur i... to wszystko!

Mo┐esz ╢ci▒gn▒µ ca│y program klikaj▒c na poni┐szy link. 

Przydatne linki:

  • Klasy - opis klas - co to jest jak siΩ je tworzy i na jakich zasadach;
  • W▒tki - dzia│anie w▒tk≤w;

 

Adam Boduch