lekcja10 VGKP743JJYI3DTYOKL6HKMOTFF4TGWAAZ7KS34Q

Delphi, cz. 10


Cóż będziemy robić tym razem? Tym razem trochę języka Pascal i początki animacji. Co w przyszłości? W przyszłym rozdziale omówię odtwarzanie dźwięków, jeszcze bardziej skomplikowane animacje, następnie wykorzystanie rejestru Windows, plików INI i blibliotek DLL. Tak szybko się ode mnie nie uwolnicie :) Później jeszcze komunikaty Windows, kontrolki ActiveX oraz bardziej skompilowane rzeczy jak wykorzystanie informacji o pamięci, ilości klastrów na dysku i inne bajery :) Najnowsze części kursu oraz inne rzeczy związane z programowaniem możesz znaleźć na: www.programowanie.of.pl


Co to właściwie jest ten uchwyt ( Handle )?


Zanim ruszymy dalej trzeba to omówić. Jest to bardzo ważne. Otóż każde okno, każdy komponent posiada swój uchwyt. Znając ten uchwyt można odwołać się do kontrolki czy okna. Zobaczysz, ze jest to bardzo częste przy programowaniu. Przykładowo: chciałbyś, aby któraś z kontrolek ( np. Edit ) stała się aktywna po naciśnięciu przycisku. Służy do tego funkcja "SetFocus", w której jako parametr należy podać uchwyt okna:


Windows.SetFocus(Edit1.Handle);


Tak jak powiedziałem: każde okno ma swój uchwyt.


Konwersja i rzutowanie


To było już omawiany w części 2, ale tym razem dokładniej. Najpierw konwersja. nieraz niektóre typy, które chcesz przypisać są różnych typów. Przykład: chcesz wyświetlić w okienko aktualną datę i czas:


var

DateTime: TDateTime; // zmienna przechowuje datę i czas

begin

DateTime := Now; // przypisanie do zmiennej aktualnego czasu

ShowMessage(DateTime); // Blad: próba wyświetlenia zmiennej TDateTime


W tym przykładze pobierana jest aktualna data i czas. Następnie następuje próba wyświetlenia tej daty w okienku. Kompilator wskaże błąd. W funkcji "ShowMessage" musi się znaleźć zmienna typu "String", a zmienna "DateTime" jest typu "TDateTime". W takim przypadku z pomocą przychodzi konwersja:


ShowMessage(DateTimeToStr(DateTime));


Polecenie "DateTimeToStr" konwertuje datę i czas do postaci zmiennej "String". Istnieją jeszcze inne konwersje:


  1. IntToStr - konwertuje zmienna "Integer" na "String"

  2. StrToInt - "String" na "Integer"

  3. StrPas - "PChar" na "String"

  4. StrPCopy - "String" na "PChar"

  5. TimeToStr - zmienna "Time" na "String"

  6. DateToStr - zmienna "Date" na "String"

  7. StrToDate - "String" na "Date"

  8. StrToTime - "String" na "Time"

  9. CurrToStr - "Currency" ( zmiennoprzecinkowy ) na "String"

  10. StrToCurr - "String" na "Currency"

  11. FloatToStr - zmiennoprzecinkowy na "String"


Rzutowanie to co innego. Jest to sposób na oszukanie kompilatora.


var

B : Byte;

C : Char;

begin

B := 123; // jakas cyfra

C := Char(B); // rzutowanie

ShowMessage(C);


W tym przykładze następuje rzutowanie zmiennej "Byte" na "Char". Przecież zmienna Byte to zupełnie co innego niż Char! A jednak! Jezeli uruchomić program to zobaczysz na ekranie okienko z jakimś znakiem ( chyba: "{" ). Są to tzw. numery ASCII. Każdy znak ma swój numer i właśnie poprzez rzutowanie można ten numer poznać ( ci którzy programowali w Turbo Pascalu pewnie wiedzą o co chodzi ). Ten sam efekt można osiągnąć stosując funkcję "Chr". Funkcja ta zwraca w postaci znaku numer - np:


var

B : Byte;

C : Char;

begin

B := 123; // jakas cyfra

C := Chr(B); // zamiana ( uzyskanie znaku poprzez zamiane cyfry )

ShowMessage(C);


Istnieje też funkcja, która to odwraca - tzn., podajesz znak, a funkcja zamienia ten znak na numer ASCII tego znaku. Do tego służy funkcja "Ord":


var

B : Byte;

C : Char;

begin

C := '{'; // znak

B := Ord(C); // uzyskanie numeru znaku

ShowMessage(IntToStr(B)); // wyswietlenie numeru



Wcześniej mówiłem o datach. Może dokończę ten temat. Podstawową funkcją jest "FormatDateTime". Zwraca ona datę w postaci tekstu ( np ): '2 luty 2001'. Oto przykład:


ShowMessage(

FormatDateTime('d mmmm yyy', Now));


Pierwszym parametrem tej funkcji jest ciąg znaków. Ciąg ten reprezentuje w jakim stylu mają być wyświetlana data. Np. mmmm oznacza pełny miesiąc: "luty". W ostatnim parametrze zamiast yyy można by było napisać: yy - spowodowałoby to wyświetlenie jedynie dwóch ostatnich cyfr daty ( 01 ). Jest tych parametrów wiele ( ich znaczenia szukaj w systemie pomocy Delphi pod hasłem "FormatDateTime" ). Z datą wiąże się jeszcze jedna ciekawa funkcja podająca dzień tygodnia. Służy do tego funkcja "DayOfWeek". Ponieważ zwraca ona numer tygodnia musimy zadeklarować tablicę, która zawierała by opis dni:


const

Dni : array[1..7] of String = // deklracja dni

(('Niedziela'),

('Poniedziałek'),

('Wtorek'),

('Środa'),

('Czwartek'),

('Piątek'),

('Sobota'));

begin

ShowMessage(Dni[ // wyświetl aktualny dzień

DayOfWeek(Now)]);


Na samym początku deklaracja tablicy ( była o tym mowa w poprzednim rozdziale ). Nie wiedzieć czemu w Delphi dni liczone są od niedzieli ( tzn., że środa jest 4 dniem tygodnia ). Stąd taki kształt tablicy :-) No i w końcu następuje wyświetlenie aktualnego dnia tygodnia. Jeżeli coś jest niejasne, czegoś nie rozumiecie to czekam na listy. Czekam także na opinię dotyczące kursu ( prosty, sztywny, trudny, niedokładny ). Mój e-mail: boduch@poland.com


Proste animacje


Tematem tego pod rozdziału są proste animacje. Procedura, którą przedstawię ma za zadanie tekstu od lewej strony do prawej. Teskt będzie płynnie przesuwany, będzie także posiadał cień. W kolejnych rozdziałach stworzymy animację mająca za zadanie ładować bitmapki i odtwarzać dźwięk ( wszystko w jednym pliku EXE ! ).

Najpierw prosty test. Wyświetli się statyczny tekst posiadający cień. Wklej ten tekst do jakiejś procedury i sprawdź efekt:


Canvas.Font.Name := 'Courier New'; // czcionka

Canvas.Font.Size := 20; // rozmiar czcionki

Canvas.Font.Style := Font.Style + [fsBold]; // pogrubenie

Canvas.Brush.Style := bsClear; // tlo czyste

Canvas.Font.Color := clWhite; // kolor czcionki

Canvas.TextOut(20, 20, 'WWW.PROGRAMOWANIE.OF.PL');

Canvas.Brush.Style := bsClear; // tlo przezroczyste

Canvas.Font.Color := clBlack; // kolor czcionki

Canvas.TextOut(19, 19, 'WWW.PROGRAMOWANIE.OF.PL');


Nie przerażaj się - kod ten nie wygląda tak strasznie! :) Ładny efekt, prawda? Tekst jest rysowany dwa razy innym kolorem co daje efekt cienia. My swoją animację będziemy rysować w trochę inny sposób. Otóż poprzez bitmapę. Stworzona zostanie bitmapa, która będzie wyświetlana w innym miejscu dając efekt animacji. Zacznijmy! Stworzymy uniwersalną procedurę. Dodaj do sekcji "private" taki nagłówek:


Done : Boolean;

procedure DrawAnim(Text: String; X, Y: Integer);


Pierwszym parametrem tej funkcji jest tekst, który ma być przesuwany, kolejne dwa to pozycja od której tekst ma być wyświetlony oraz jaka ma być pozycja Y tego tekstu. Tak więc jeżeli będziesz chciał wyświetlić taką animację będziesz pisał:


DrawAnim('Adam Boduch', 0, 200);


Ok, teraz uzupełnij procedurę w sekcji "Implementation" ( przypominam: najeżdżasz kursorem na nazwę procedury i wciskasz: Shift + Ctrl + C ). W każdym razie wpisz taki tekst w sekcji "Implementation":


procedure TForm1.DrawAnim(Text: String; X, Y: Integer);

var

B : TBitmap; // Bitmapa

i : Integer;

begin

B := TBitmap.Create; // utwórz bitmape

B.Height := 40; // wysokosc bitmapy

B.Width := Canvas.TextWidth(Text) * 10; // szerokosc bitmapy

B.Canvas.Font.Name := 'Arial Black'; // czcionka

B.Canvas.Font.Size := 14; // rozmiar czcionki

B.Canvas.Brush.Color := clSilver; // kolor tla

// stworz obszar na ktorym bitmapa ma byc wyswietlana

B.Canvas.FillRect(Rect(0, 0, Canvas.TextWidth(Text) * 10, 40));


while not (Done) do // Jezeli Done = False...

begin // zacznij odtwarzanie animacji

for i:= X to Width do // zacznij od punktu X to konca formy

begin

Application.ProcessMessages; // daj odetchnac systemowi

Sleep(1); // czekaj 1 milisekunde

B.Canvas.Font.Color := clWhite; // kolor na bialy

B.Canvas.TextOut(10, 10, Text); // wyswietlenie tekstu

B.Canvas.Brush.Style := bsClear; // tlo na przezroczyste

B.Canvas.Font.Color := clBlack; // kolor czcionki: czarny

B.Canvas.TextOut(9, 9, Text); // wyswietl tekst jeszcze raz

Canvas.Draw(I, Y, B); // wyswiet bitmape

if (Done) then // Jezeli ktos przerwal animacje ( Done = True )...

Break; // ... to przerwij odtwarzanie animacji

end;

end;

B.Free; // zwolnji pamiec dla zmiennej

end;


Czy ten kod jest skomplikowany? Dużą jego część zajmują komentarze. Zmienna "Done", która stworzyłeś w sekcji "private" informuje o tym, czy zmienna jest uruchomiona, czy też nie. No, ale po kolei zacznijmy analizować tę procedurę. Na samym początku następuje Stworzenie bitmapy i przypisanie jej odpowiednich rozmiarów. Zauważyłeś polecenie "TextWidth" przy określaniu szerokości bitmapy? Funkcja ta podaje szerokość ( w pikselach ) tekstu wpisanego w nawiasie. Ponieważ jest to szerokość w pikselach mnożymy ją przez 10, aby zagwarantować, że cały tekst się zmieści. Istnieje taże funkcja "TextHeight", która podaje wysokość ( w pikselach ) tekstu. Następnie funkcja "FillRect", która określa region na którym będzie można rysować ( bitmape ). W funkcji tej musi się znaleźć parametr typu "TRect". Następnie pętla "While". Jeżeli zmienna "Done" nadal ma wartość "False" to znaczy, ze animacja jest uruchomiona - kontynuuj więc. Następnie pętla "For". Zaczyna się ona od zmiennej "X", czyli pozycji od której animacja ma się rozpoczynać. Tekst będzie "przelatywał" od tej właśnie pozycji do końca formy. Następna ważna funkcja to "Application.ProcessMessages". Jest ona bardzo ważna gdyż daje odetchnąć systemowi. Gdyby tej funkcji nie było to program nie dopuszczał by do siebie żadnych komend dopóki nie zakończy działania pętli. Nie można by było więc zakończyć działania programu ( tylko: Ctrl + Alt + Del ). Następnie pauza to 1 milisekunda ( możesz ją zmienić wedle własnych upodobań ). Późniejsze komendy zmieniają kolor na biały rysują tekst w punkcie 10, 10 [ punkty te teraz nie oznaczają położenia na formie, ale położenie w obszarze, który zadeklarowaliśmy z użyciem funkcji "FillRect" ]. Następnie zmiana koloru czcionki i narysowanie tekstu przesuniętego w lewo i dół. No i na końcu ta bitmapa jest rysowana na formie. To jeszcze nie koniec. Żeby zakończyć animację musisz gdzieś w procedurze ( najlepiej w "OnClose" ) napisać:


Done := True; // zakończ animację.


Dobra. Gotowe. Teraz napisz gdzieś w procedurze:


DrawAnim('HTTP://WWW.PROGRAMOWANIE.OF.PL', 0, 20);


Zobacz jak działa!


W poprzedniej procedurze zastosowałem instrukcję "if", która sprawdza, czy zmienna "Done" równa jest True. Jeżeli chcemy sprawdzić, czy zmienna równa jest True to nie trzeba pisać:


if Done = True, ale wystarczy tak jak w poprzednim przykładzie. Jeżeli tak jest to następuje wyjście z pętli ( polecenie Break ). Istnieje jeszcze polecenie "Continue", które powoduje ominięcie następnej instrukcji i przejście do kolejnego bloku poza pętlą.


Jeszcze jeden ciekawy efekt z grafiką. Procedura, którą tutaj zaprezentuje ma za zadanie wyświetlać znak po znaku określony tekst. Najlepiej sam sprawdź -wklej ten tekst do procedury:


procedure TForm1.Button2Click(Sender: TObject);

var

TextLength, I: Integer;

const // tekst do wyswietlenia

Text = 'http://www.programowanie.of.pl';

begin

TextLength := StrLen(Text); // określ dlugosc tekstu ( w znakach )


with Canvas do

begin

for I := 1 to TextLength do // od pierwszego znaku to ostatniego

begin

Application.ProcessMessages;

Sleep(100); // pauza

Brush.Style := bsClear; // styl przezroczysty

Font.Name := 'Courier New'; // czcionka

Font.Color := clWhite; // kolor czcionki

Font.Size := 14; // rozmiar czcionki

TextOut((20 + i * 12), 40, Text[i]); // wyswietl znak po znaku

Brush.Style := bsClear;

Font.Color := clBlack; // zmien kolor czcionki

TextOut((20 + i * 12) -2, 40 -2, Text[i]);

end;

end;

end;


Procedura jest prostsza i krótsza od poprzedniej. Na początku liczona jest długość tekstu ( w znakach ). Dokonuje tego procedura "StrLen". Następnie pętla - w odstępach 100 milisekundowych ustawia odpowiednie parametry czcionki. Później wyświetlenie tekstu. Ponieważ każdy znak ma być wyświetlony w pewnym odstępie od drugiego potrzebna była specyficzna konstrukcja procedury "TextOut". W pierwszym parametrze X podawana jest pozycja X, a następnie do tego dodawana jest zmienna "i", która później mnożona jest jeszcze przez cyfrę 12, aby zachować odpowiednie odstępy. Kolejna pozycja Y - bez komentarza :). No i wreszcie ostatni parametr, czyli tekst, który ma być wyświetlony. Konstrukcja:

Text[i] gwarantuje, ze wyświetlany będzie znak po znaku. Bo jeżeli piszesz w nawiasie klamrowym cyfrę to wyświetlony zostaje znak podany w tym nawiasie. Przykład:


const

Tx = 'Adam';

begin

ShowMessage(Tx[2]); // wyświetlona zostanie litera 'd'


I tak w poprzedniej procedurze rysowany jest jeszcze raz tekst tyle, że jest on przesunięty o dwa znaki.

I tak dotarłem do końca rozdziału. Najważniejsze jest w programowaniu rozumienie tego, co się robi. Dlatego też piszcie do mnie ( boduch@poland.com ) i odwiedźcie stronę www.programowanie.of.pl - tam znajdziesz odpowiedzi na większość Twoich pytań.



Adam Boduch











Wyszukiwarka

Podobne podstrony:
Lekcja kliniczna 2 VI rok WL
Lekcja Przysposobienia Obronnego dla klasy pierwszej liceum ogólnokształcącego
Lekcja wychowania fizycznego jako organizacyjno metodyczna forma lekcji ruchu
Lekcja kliniczna nr 2 VI rok WL
04 Lekcja
PF7 Lekcja2
lekcja52
Printing bbjorgos lekcja41 uzupelnienie A
lekcja 18 id 265103 Nieznany
Hydrostatyka i hydrodynamika lekcja ze wspomaganiem komputerowym
Lekcja 6 Jak zapamietywac z notatki Tajemnica skutecznych notatek
lekcja 20
lekcja20
Lekcja 04 Szene 04
LINGO ROSYJSKI raz a dobrze Intensywny kurs w 30 lekcjach PDF nagrania audio audio kurs
Printing bbjorgos lekcja01 05 A
'Half Life', czyli pół życia przed monitorem zagrożenia medialne foliogramy gim modul 3 lekcja 5
Lekcja od mamy
lekcja 3 id 265134 Nieznany