ROZDZIAŁ 1
Jeżeli macie jakieś doświadczenie w programowaniu w Turbo Pascalu to na pewno przyswojenie materiału z tego rozdziału przyjdzie Wam łatwiej niż pozostałym. Jeżeli czegoś nie rozumiecie - piszcie: programowanie@poczta.onet.pl
Przejdźcie do następnych rozdziałów i rozwiązujcie przykłady. Zawsze najlepiej nową wiedze przyswoić w praktyce!
Poniżej przedstawiony jest nowo utworzony moduł Delphi:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations } end;
var
Form1: TForm1;
implementation
{$R *.DFM}
end.
WYJAŚNIENIE
Moduł to plik tekstowy, który może być kompilowany do programu wykonywalnego tzn. kod źródłowy kompilowany jest na język zrozumiały dla maszyny. Nazwa modułu wypisana jest w pierwszej linijce kodu i poprzedzona jest słówkiem Unit (od ang. Moduł).
Słowo uses oznacza początek listy w której wypisane są nazwy wszystkich dodatkowych modułów które to zawarte są w naszym module głównym.
Interface - po tym zwrocie wypisywane są nazwy wszystkich procedur, funkcji, które mają być widoczne w naszym module. Na przykład:
unit Unit1;
interface
procedura Moja_procedura1;
implementaion
procedura Moja_procedura;
begin
{treść procedury}
end;
end.
Słowo implementation oznacza początek programu; za tym słowem wpisujemy treść procedur, funkcji itp.
Musisz pamiętać o kilku ważnych sprawach:
· Każde zdanie (poza kilkoma wyjątkami jak np. słówko begin i end) kończymy średnikiem.
· Każdy program zakończony jest słowem end. ( z kropką na końcu!)
· Pisanie kodu należy poprzedzić słowem begin.
· W programach możesz się spotkać z komentarzami, które będą najczęściej w nawiasach klamrowych ({}). Nie mają one wpływu na działanie programu.
Słowo type
Deklarowane są tutaj nowe typy danych. Umieść na formularzu przycisk Button (na palecie Standard; umieszcza się go klikając pojedynczo myszą a następnie na formularzu). Przejedź teraz do edytora kodu (naciśnij przycisk F12). Zobaczysz, że w sekcji type powstała nowa linia:
Button1: TButton;
Po lewej stronie wypisana jest komponentu (nazwę można modyfikować w polu Name w Inspektorze Obiektów), a po prawej typ - w tym wypadku Tbutton.
Słowo var
Służy do deklarowania zmiennych w programie. Spójrz na poniższy kod:
procedure Moja_procedura;
var
x:integer; {deklaracja zmiennej; patrz tabelka niżej}
begin
x:=20; {przypisanie wrtości zminnej x liczby 20}
Label1.caption:=inttostr(x); {wyświetlenie wartości x jako nazwę komponentu Label; inttostr oznacza przekonwertowanie wartości Integer na wartość String (patrz poniżej)}
end;
Zakres wartości zmiennych |
|
Integer |
-2 147 483 648..2 147 483 647 |
String |
tekst |
Byte |
0..255 |
Boolean |
True albo False |
Currency |
-922 337 203 685 477 5808..922 337 203 685 477 5807 |
Word |
0.. 65 535 |
Wyżej przedstawiłem najczęściej używane typy zmiennych. Uniwersalnym typem będzie Integer.
Inttostr - konwertuje zmienną Integer na String
Strtoint - konwertuje zmienną String na Integer.
Słowo const
Oznacza stałą. Spójrz poniżej:
interface
const
name='Adam Boduch'; {przypisanie wartości stałej - w tym wypadku dla imienia I nazwiska}
implementation
procedure Moja_procedura;
begin
label1.caption:=name; {przypisanie komponentowi Label tekstu któremu przypisana jest stała: name}
end;
W powyższym przypadku stałej możesz używać w każdej innej procedurze.
Pętla if, then, else
Pętla oznacza warunek, który musi być spełniony, aby zadziałał kod, który zawarty jest w jej wnętrzu. Przykład:
if x<20 then begin {jeżeli liczba jest mniejsza od 20 następuj wczytanie warunku poniżej, jeżeli nie to wykonywany zostaje warunek po wyrażeniu else }
if x>10 then
if x=15 th en
Label1.caption:='Tak, tą liczbą jest 15!';
end else
label1.caption:='Przykro mi, to nie jest prawidłowa liczba.';
Warunek if, then, else można przetłumaczyć jako:
Jeżeli {warunek, który musi zostać spełniony} wtedy {kod procedury}, a jeżeli nie to {kod procedury}
Pętla for, to, downto
Działanie tej pętli najlepiej zrozumieć na przykładzie:
1. Umieść na formularzu komponent Gauge (na palecie Samples)
2. Umieść na formularzu przycisk Button i kliknij nań dwukrotnie.
3. Kod procedury uzupełnij następująco:
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
for i:=0 to 100 do begin {odliczaj do stu poczynając od zera, a...}
sleep(10); {.. . odstęp między odliczaniem ma wynieść 10 milisekund}
gauge1.progress:=i; {przypisanie komponentowi wartośći I}
end;
end;
4. Odpal program;
Downto działa podobnie tyle, że odlicza do dołu i słówko downto wpisujemy zamiast to.
for i:=100 downto 0 do begin
{kod}
Pętla repeat, until
Powtarza daną czynność dopóki nie zostanie spełniony warunek jej zakończenia.
i:=0;
repeat
memo.lines.add(`Dzisiaj jes '+inttostr(i)+' dzień');
i:=i+1;
until i:=10;
Procedury
Jest to blok kodu, który wykonuje daną czynność:
Budowa procedury:
procedure Moja_procedura(x:integer, y:integer)
begin
{treść procedury}
end;
Funkcje
Jest to blok kodu, który wykonuje daną czynność tyle, że zwraca wynik.
Budowa funkcji:
function Moja_funkcja(x:integer, y:integer):integer;
begin
{treść funkcji}
end;
PODSUMOWANIE
Sorry, że rozdział ten opisałem tak krótko. Zdaje sobie sprawę, że niektóre rzeczy mogą wydać się wam niezrozumiałe. Chętnie odpowiem na wszelkie pytania:
W dalszych częściach kursu postaram się bardziej rozwinąć temat języka Object Pascal. Rzeczy, które tu opisałem są podstawą przy programowaniu, ale oczywiście to nie jest wszystko, co oferuje, Delphi. Możecie teraz przejść do następnego rozdziału.
ROZDZIAŁ 2
Dobrze, możemy zaczynać. Napiszemy teraz pierwszy program; postępuj według poniższych wskazówek.
1. Otwórz program.
2. Kliknij komponent Label, a następnie umieść go na formularzu pojedynczym kliknięciem
3. W Inspektorze Obiektów w polu Caption wpisz tekst, który ma być umieszczony w komponencie
4. Umieść na formularzy komponent Button; zmień jego tekst (również w polu Caption) na Pokaż tekst.
5. Kliknij podwójnie na przycisku, a następnie wpisz w treści procedury taki oto tekst:
procedure TForm1.Button1Click(Sender: TObject);
begin
if label1.visible=true then begin {label1 oznacza nazwe komponentu label, ktora
mozemy edytowac w polu 'Name'. Visible oznacza czy dany komponent ma byc po uruchomieniu
programu widoczny (True), czy tez nie (False)}
label1.visible:=false; {po nacisnieciu komponent staje sie niewidoczny}
end else {W przeciwnym wypadku (jezeli komponent jest niewidoczny) komponent sie pojawia}
label1.visible:=true;
end;
6. Zaznacz komponent Label, a następnie w Inspektorze Obiektów zmień pole Visible na False.
To już praktycznie wszystko - uruchom program naciskając klawisz F9 lub wybierz polecenie: Run-> Run.
Ok., należy Ci się wyjaśnienie niektórych funkcji Inspektora Obiektów.
Funkcja |
Opis |
Active Control |
Ustawia domyślny komponent tj. w wypadku przycisku będzie on aktywny i po naciśnięciu Enter'a zostanie wykonany kod w funkcji OnClick przycisku. |
Align |
Ustawia położenie komponentu; alNone - brak; alClient - na całej powierzchni;alBottom - na samym dole obszaru; alTop - na samej górze; alRight - po prawej stronie; alLef - po lewej stronie. |
Cursor |
Ustawia kursor który będzie widoczny po najechaniu myszą nad dany komponent. |
Enabled |
Gdy wartość jest False - komponent będzie nieaktywny; gdy True - przeciwnie. |
Caption |
Tekst, który będzie wyświetlany na komponencie lub ( w przypadku formularza głównego) na niebieskiej belce. |
Font |
Ustawienie czcionki. |
Name |
Nazwa komponentu. |
Visible |
Ustawia czy komponent będzie widoczny (True), czy też nie (False) po uruchomieniu programu. |
Height, Width |
Pozwala na dokładne ustawienie szerokości i wysokości komponentu. |
To są najpopularniejsze opcje w Inspektorze Obiektów. Innymi zajmę się w dalszych częściach kursu.
Teraz postaram się wyjaśnić jak napisać prostą grę - będzie to popularna gra dla dwóch osób - Kółko i krzyżyk.
Zacznijmy, więc:
1. Zmień nazwę w polu Caption głównego formularza na: Kółko i krzyżyk.
2. Zmień pole Name na: Main1stGame.
3. Umieść na formularzu 9 przycisków Speedbutton (na palecie Additional). Uwaga! By nie klikać za każdym razem na komponencie, a następnie na formularzu to podczas pierwszego kliknięcia przytrzymajcie przycisk SHIFT. Po umieszczeniu wszystkich przycisków należy kliknąć na ikonie ze strzałką.
4. Ok., teraz zaznacz wszystkie przyciski (obrysowując je), a następnie w Inspektorze Obiektów w polu Width i Height wpisz 25.
5. Omieść je blisko siebie (przyciski przesuwać można zaznaczając je, a następnie przytrzymując klawisz CTRL i przemieszczać je kursorami).
6. Przyciski te nazwij kolejno: s1, s2, s3... itd. aż do s9.
7. Umieść na formularzu kolejne dwa przyciski speedbutton i zmień tekst na: „Gracz1” i „Gracz2”, a w polu Name wpisz: speedbutton1 i speedbutton2.
8. Zmień właściwość Flat tych przycisków na True, a w polu właściwości GroupIndex wpisz 1. Właściwość Flat oznacza, że przycisk będzie „płaski”, a jego kontury będzie widać po najechaniu nań myszą. Właściwość GroupIndex oznacza, że wciśnięty będzie tylko jeden przycisk jednocześnie tj. w czasie gdy wciśniemy jeden to drugi wciśnięty już nie będzie.
9. Zmień właściwość Down jednego przycisku na True. Oznacza to, że przycisk zaraz po uruchomieniu programu będzie „wciśnięty”.
10. Teraz możesz uzupełnić kod w procedurze OnClick przycisku si.
procedure TMain1stGame.s1Click(Sender: TObject);
begin
if speedbutton1.down=true then begin {Jeżeli przycisk speedbutton1 będzie wciśnięty to na przycisku s1 ujrzysz literę `X' - w przeciwnym wypadku - `O'.}
s1.caption:='X';
end;
if speedbutton2.down=true then begin
s1.caption:='O';
end;
end;
11. Powyższy kod wpisz dla pozostałych przycisków z tą różnicą, że zamiast s1 wpisuj kolejne przyciski: s1, s2 itd.
Teraz możesz już uruchomić program, lecz zapewne zauważysz, że po każdym naciśnięciu na przycisku trzeba zmieniać gracza. Trzeba to poprawić!
12. Zaznacz przycisk s1, a następnie w Inspektorze Obiektów wybierz zakładkę Events.
13. Znajduje się tam opcja onMouseDown. Kliknij w puste białe pole; pojawi się edytor kodu, który uzupełnij następująco:
if speedbutton1.down=true then begin
speedbutton2.down:=true;
end else
speedbutton1.down:=true;
14. Teraz zaznacz przycisk s2 poczym w Inspektorze Obiektów wybierz zakładkę Events, a następnie rozwiń pole onMouseDown i wybierz s1MouseDown.
15. Postąp tak z pozostałymi przyciskami.
Odpal program. Hurra! Działa!
Fajnie by było gdyby program posiadał przycisk który spowoduje iż będziemy mogli grać od początku. Trzeba się więc tym zająć.
1. Umieść na formularzu jeszcze jeden przycisk:Button.
2. Zmień jego tekst na: Ponowna tura. Rozszerz przycisk tak, aby widoczny był cały napis.
3. Kliknij dwukrotnie na przycisku i umieść w nim następujący kod:
procedure TMain1stGame.Button1Click(Sender: TObject);
begin
s1.caption:='';{spowoduje to wymazanie tekstu z przycisków}
s2.caption:='';
s3.caption:='';
s4.caption:='';
s5.caption:='';
s6.caption:='';
s7.caption:='';
s8.caption:='';
s9.caption:='';
end;
Zajmiemy się jeszcze dodaniem okna z informacją o prawach autorskich. Postępuj według poniższych wzkazówek:
1. Z menu Plik wybierz New Form.
2. Zmień tekst na: O programie.
3. Zmień nazwę na: about. Dostosuj okno do rozmiarów, jakie uważasz za odpowiednie.
4. Z Inpektora Obiektów rozwiń menu BorderIcons, a następnie zmień polecenia biMinimize, biMaximize na False. Spowoduje to wyświetlenie w oknie jedynie okony Zamknij.
5. Umieść na formularzu komponent Label. Zmień jego tekst na: © Copyright 2000. Uwaga! Znak „©” uzyskuje się przytrzymując lewy Alt i (przy włączonej klawiaturze numerycznej) wystukaniu na klawiaturze numerycznej cyfr 0169.
6. Umieść kolejny komponent Label i zmień jego tekst na: Adam Boduch; zmień rozmiar czcionki klikając na krzyżyku. Rozwinie się podmenu w którym to w polu Size wpisz 12. Rozwiń pole Style i zmień wartość fsBold na True.
7. Umieść na formularzu komponent Image(na palecie Additional) i zmniejsz jego rozmiary. W tym kwadracie umieszczony będzie rysunek. W Inspektorze Obiektów wybierz menu Picture, następnie kliknij na symbol trzykropka.
8. Naciśnij Load i wybierz jakiś rysunek. Naciśnij OK.
9. Teraz dodaj przycisk BitBtn (na palecie Additional) , a w Inspektorze Obiektów rozwiń pole Kind i wybierz bkOk.
Pojawił się tam taki „ptaszek”. Po naciśnięciu przycisku okno samo się zamknie.
10. Teraz już tylko kosmetyczne poprawki. Wybierz komponent Bevel i obrysuj obszar który ma być wzięty w ramke. Zmień jego wygląd w polu Shape na bsFrame.
Teraz powróć do formularza głównego i umieść w nim komponent Label; zmień jego tekst na:
wersja 1.0. Kliknij na nim podwójnie, a następnie w edytorze kodu wpisz następujący tekst:
procedure TMain1stGame.Label1Click(Sender: TObject);
begin
about.showmodal;{powroduje wyświetlenie okno about}
end;
Teraz ponownie zaznacz komponentLabel1i w Inspektorze Obiektów w polu Cursor wybierz kursor crHandPoint. Gdy najedziesz myszą na komponent to kursor zmieni kształt. Zapisz wszystko i spróbuj odpalić program. Zostaniesz zapewne zapytany czy dodać formularz about do programu. Odpowiedz twierdzącą i spróbuj uruchomić go jeszcze raz.
Jeżeli coś nie działa to porównaj swój program z tym co jest dołączonydo tego kursu.
To już wszystko w tym odcinku programowania. W kolejnych częściach zajmiemy się unowocześnianiem programy `Kółko i krzyżyk', dodamy do niego grafikę, dźwięk oraz parę innych opcji. Nie wahajcie się pisać. Jeżeli macie jakieś problemy, pytania:
ROZDZIAŁ 3
Gdy zapiszecie swój program na dysku to zapewne zwrócicie uwagę na sporą liczbę plików powstałych wraz z programem. Oczywiście nie musisz dawać kumplom tych wszystkich plików - wystarczy tylko ten z rozszerzeniem *.exe.
Jedna uwaga: Gdy dasz program koledze, który nie ma zainstalowanego Delphi, to program się nie uruchomi. Dzieje się tak dlatego, że twój kumpel nie posiada pliku vcl50.bpl. Oczywiście możesz dołączać ten plik do każdego programu, lecz z racji jego rozmiaru zalecane jest zrobić coś takiego:
Z menu Project wybierz Options.
Wybierz zakładkę Packages
Zaznacz opcje Bulid with runtime packages
Naciśnij OK i z menu Project wybierz Bulid
Okno Options zawiera inne pożyteczne zakładki takie jak:
application - dzięki tej zakładce możemy wybrać ikonę i wpisać tytuł naszego pliku wykonywalnego.
version info - po zaznaczeniu opcji Include version information in project możesz sprawić iż do twojego pliku wykonywalnego w zakładce Właściwości pojawi się okno o wersji produktu. Możesz wpisać w nim podstawowe dane jak: Nazwa firmy, wersja, komentarz itd. Po zaznaczeniu opcji Auto-Increment bulid number wersja pliku będzie się zwiększała o jedną tysięczną przy każdym budowaniu (Bulid) programu.
Teraz pora aby przejść do dalszej nauki Object Pascala.
Operatory
Spójrz na poniższy przykład:
if (x>20) and (y>20) then
{kod programu}
Operatorami w powyższym przykładzie są: ">" i "and". Operatory to inaczej przypisanie, porównywanie jakiś wartości.
Operator |
Opis |
:= |
Przypisanie zmiennej jakiś wartości, np: x:=10 |
= |
Znak równości, np. if x=10 then begin Gdybyś w tym przykładzie użył operatora przypisania to program nie skompilował by się i wygenerował by wyjątek ponieważ nie przypisujemy x wartości 10 lecz chcemy jedynie sprawdzić to wyrażeniem if |
<> > < <= >= |
Oznacza to kolejno: różny od (np. if x<>10), większy niż, mniejszy niż, mniejszy równy niż, większy równy niż. |
and |
Od angielskiego: i Sprawdza warunek zawarty przed tym słowem jak i po tym słowie. |
or |
Od angielskiego: lub. if (x=10) or (x=20) then |
not |
Jeżeli nie. if not prawda then |
Instrukcja goto
Instrukcja ta oznacza tyle co: idź do. Umożliwia ona skok do umieszczonej w kodzie etykiety poprzedzonej słówkiem Label, ale nie jest to komponent label.
var
label powtarzanie;
begin
powtarzanie;
{kod instrukcji goto}
{dalszy kod programu}
if x<69 then
goto powtarzanie;
end;
Jeżeli nie zostanie spełniony warunek, w tym wypadku, jeżeli x nie jest większe od 69 to następuje skok do słowa powtarzanie i tym samym wykonanie instrukcji po słowie powtarzanie.
Instrukcja case
Spójrz na poniższy przykład:
case Ilosc_paliwa of
0: paliwo:=0;
10: paliwo:=1;
50: paliwo:=3;
end;
Jeżeli Ilosc_paliwa przyjmie wartość 0, to wykonana zostanie funkcja paliwo:=0; Uwaga! Wynik musi być typu Integer, Byte itd., nie może być natomiast typu przecinkowego lub typu Srting. Nie możesz zapisać:
case combobox1.itemindex of
0: memo.lines.add('To nie przejdzie ponieważ jest to wartość typu String');
Continue i Break
Te dwie komendy używane są wraz z pętlami. Komenda Continue powoduje natychmiastowy skok do punktu stopu tj. do końca procedury.
if speedbutton1.down=true then continue
{tutaj wykonywany zostaje kod po komendzie contiunue}
Komenda Break powoduje całkowite zakończenie działania pętli:
if done=true then begin
{kod}
end else
break;
____
Na zakończenie tego rozdziału zrób prosty program, który będzie dodawał, odejmował i mnożył:
Umieść na formularzu 3 komponenty Edit
Umieść na formularzu przycisk i zmień jego właściwość Caption na OK
Umieść na formularzu komponent RadioGroup; naciśnij w Inspektorze Obiektów właściwość Items i w oknie wpisz jeden pod drugiem: dodawanie, odejmowanie, mnożenie.
Właściwosć Itemindex komponentu RadioGroup ustaw na 1.
Uzupełnij procedure Button1Click następująco:
procedure TForm1.Button1Click(Sender: TObject);
begin
case RadioGroup1.itemindex of
0: edit3.text:=
inttostr(strtoint(edit1.text)+(strtoint(edit2.text)));
1: edit3.text:=
inttostr(strtoint(edit1.text)-(strtoint(edit2.text)));
2: edit3.text:=
inttostr(strtoint(edit1.text)*(strtoint(edit2.text)));
end;
end;
Jeżeli program nie działa prawidłowo porównaj swój kod z moim.
Teraz możecie już przejść do następnego rozdziału, w którym to zajmiemy się udoskonalaniem programu "Kółko i Krzyżyk"
ROZDZIAŁ 4
Ostatnim razem stworzyłeś program "Kółko i Krzyżyk". Teraz dodamy do niego grafikę muzykę.
Potrzebne nam będą 3 rysunki: jeden z krzyżykiem, z kółkiem i pusty.
Do stworzenia rysunków potrzebny nam będzie jakiś program graficzny (nam całkowicie wystarczy Paint)
Rozmiary rysunków muszą być zbliżone do rozmiaru przycisków w twoim programie; rysunki muszą mieć także szare tło (takie jak kolor przycisków).
Trzeci przycisk musi mieć jedynie szare tło; gdy stworzyłeś już przyciski to umieść je w katalogu z programem.
Umieść przycisk, który będzie służył jako rozpoczęcie nowej tury; treść jego procedury zmodyfikuj następująco:
procedure TMain1stGame.Button10Click(Sender: TObject);
var
Bitmap5:TBitmap;
begin
bitmap5:=TBitmap.create;
bitmap5.LoadFromFile('nic.bmp');
button1.glyph:=bitmap5;
button2.glyph:=bitmap5;
button3.glyph:=bitmap5;
button4.glyph:=bitmap5;
button5.glyph:=bitmap5;
button6.glyph:=bitmap5;
button7.glyph:=bitmap5;
button8.glyph:=bitmap5;
button9.glyph:=bitmap5;
speedb.down:=true;
speedb2.down:=false;
end;
Wyjaśnienie: Na samym początku deklarowana jest zmienna Bitmap5. Później następuje stworzenie bitmapy przy pomocy polecenia bitmap5:=TBitmap.create; Następnie następuje wczytanie uprzednio stworzonej bitmapy: bitmap5.loadfromfile('nic.bmp'); Kolejną funkcją jest przypisanie każdemu z przycisków bitmapę nic.bmp.
Teraz musisz zastąpić starą procedure nową:
procedure TMain1stGame.Button1Click(Sender: TObject);
var
Bitmap:TBitmap;
Bitmap2:TBitmap;
begin
bitmap:=TBitmap.Create;
bitmap.LoadFromfile('krzyzyk.bmp');
bitmap2:=TBitmap.Create;
bitmap2.LoadFromFile('kolko.bmp');
if speedb.down then
button1.glyph:=bitmap;
if speedb2.down then
button1.glyph:=bitmap2;
end;
Skopiuj ten kod i wstaw do pozostałych przycisków z tą różnicą, że w przedostatniej i czwartej od końca linii zastąp button1 na nazwę przycisku.
Teraz możesz uruchomić program - działa! Fajnie by było gdyby program posiadał funkcje odtwarzania muzyki. Zróbmy więc to!
Umieść komponent MediaPlayer (na palecie System ); zmień jego właściwość visible na False; nie ma potrzeby aby był widoczny.
Umieść komponent CheckBox; zmień jego właściwość Caption na Włącz muzykę, a właściwość Name na muzyka.
Kliknij podwójnie na komponent i uzupełnij procedure:
if muzyka.checked=true then begin
MediaPlayer.filename:='muzyka.mid';
MediaPlayer.open;
MediaPlayer.play;
end else
MediaPlayer.stop;
Teraz umieść w katalogu z programem plik muzyczny i zmień jego nazwę na muzyka.mid.
To już wszystko tym razem. W kolejnej części zajmiemy się dokończeniem programu Kółko i Krzyżyk i zaczniemy całkiem nowy program. Zapraszam następnym razem!
ROZDZIAŁ 5
Przejdźmy od razu do nauki Object Pascala.
Funkcja Pred i Succ
Funkcja Pred zwraca poprzednik swojego argumentu np. Pred liczby 50 da 48. [ Pred(50) da 49 ] np:
var
x: integer;
begin
x:=10;
for i:=0 to Pred(x) do begin
memo.lines.add('To zdanie powtórzy się 9 krotnie');
Funkcja Succ natomiast odwrotnie - odlicza to tyłu. Succ(100) daje 101.
Łańcuchy
Istnieje kilka rodzajów łańcuchów: shortstrings, longstrings.
Łańcuchy typu shortstrings nie mogą przekroczyć 255 znaków, np:
var
lancuch: shortstring; // Nie może przekraczać 255 znaków.
lancuch2: string[5]; //Nie może przekroczyć 5 znaków
Wystarczy, że będziesz pisał samo string wtedy łańcuch nie będzie miał ograniczeń (długi łańcuch).
Komentarze
Mało pisałem o komentarzach w Delphi. Stosuje się je, aby przekazać innym programistą jakąś wiadomość np.
{Staszek, ten kod jest do d***}
Istnieje kilka rodzajów komentarzy: (* treść *), {treść}, //komentarz jednej linii
Kody ASCII
Każdy znak ma swój odpowiednik w kodach ASCII. Chciałbyś np. postawić znak "©"? Nie ma sprawy. Naciśnij lewy Alt i przy wyłączonej klawiaturze numerycznej wystukaj 0169. Skąd to wiem? Taki jest odpowiednik tego znaku w kodzie ASCII. Zrób coś takiego:
Umieść na formularzu przycisk i komponent Memo.
Treść procedury uzupełnij następująco:
procedure TForm1.Button1Click(Sender: TObject);
var
y,i:integer;
begin
for i:=32 to 255 do
memo1.lines.add(inttostr(0)+inttostr(i)+'='+chr(i));
end;
Teraz po naciśnięciu przycisku na ekranie zobaczysz znak i odpowiadający mu znak ASCII.
Pliki dołączone
Pliki dołączone to pliki zawierające kod źródłowy który w trakcie kompilacji dołączony jest do twojego projektu.
W tym celu z menu File wybierasz New, a następnie wybierasz plik tekstowy. Piszesz w nim np.
const
Szerokosc=300;
Wysokosc=200;
Wybierasz filtr "Any File" i wpisujesz nazwę z rozszerzeniem *.INC. Żeby dołączyć taki plik d do projekru zrób coś takiego:
{ $I PLIK.INC }
Wbrew pozorom to nie jest komentarz, a tzw. dyrektywa. Kompilator traktuje to tak, gdyby kod programu został tu wklejony.
Nie wspomniałem jeszcze o jednej rzeczy. Pisząc na przykład tak:
edit1.text:='Tekst który właśnie czytasz jest baaaaaardzo długi
i dlatego nie mieści się w jednej linii';
kompilator wygeneruje błąd. Oba wersy musimy z sobą połączyć znakiem "+".
edit1.text:='Tekst który właśnie czytasz jest baaaaaaardzo długi '+
'i dlatego nie mieści się w jednej linii
ROZDZIAŁ 6
Tym razem zajmiemy się jeszcze jedną opcją w programie "Kółko i Krzyżyk". Dodamy opcje wpisywania imion. W końcu głupio jest jak na przyciskach widnieje napis "Gracz 1", "Gracz 2".
Zrób tak:
Umieść na formularzu dwa komponenty Edit i przycisk
Treść procedury:
procedure TMain1stGame.Button11Click(Sender: TObject);
begin
speedb.caption:=edit1.text;
speedb2.caption:=edit2.text;
end;
Prawda, że proste? Przydałaby się jakaś pomoc tj. Pomoc na pasku stanu. Jeżeli umieściłeś na formularzu komponent StatusBar zrób coś takiego.
Zmień jego właściwość AutoHint na True.
Zaznacz wszystkie przyciski (oprócz przycisku: "Nowa tura", "Gracz 1", "Gracz 2" i wpisz w Inspektorze Obiektów w pole Hint np. coś takiego:
Kliknij nań | Kliknij przycisk, aby postawić kółko lub krzyżyk.
Zauważ, że oba zdania oddziela znak "|" - Pipeline. To co jest przed tym znakiem pojawiać się będzie gdy ktoś najedzie myszą na przycisk, a drugi człon pojawiać się będzie na pasku zadań. To już chyba wszystko jeśli chodzi o program Kółko i Krzyżyk. Kod źródłowy tego programu możesz znaleźć na mojej stronie: www.programowanie.of.pl Jeżeli unowocześniliście ten program to przyślijcie mi jego kod źródłowy, a nowa wersja będzie umieszczona na stronie.
Mój adres: programowanie@poczta.onet.pl
Nie napisałem nic o kodach źródłowych. Jeżeli chcesz przenieść na komputer kolegi kod źródłowy wystarczą pliki z rozszerzeniem *.pas, *.dpr, *.dfm. Pozostałe kompilator odbuduje podczas kompilacji.
Teraz należałoby wspomnieć coś o innych funkcjach Delphi. Istnieją tzw. wyjątki. Dzięki temu zawsze możesz poinformować o błędzie np.
try
//kod programu
except
//wyjątek
Objaśnienie: Słowo try (od ang. Spróbuj) oznacza akcje po której nastąpi wykonanie funkcji która jest pod słowem try
Po słowie except następuje kod wyjątku. Istnieje także słowo finally które wstawia się zamiast słowie except. Po nim można umieścić funkcje która zostanie wykonana niezależnie od tego czy nastąpił wyjątek.
Przydatną funkcją jest funkcja losowania.
x:=10;
randomize;
edit1.text:=inttostr(random(x));
W oknie Edit następi wylosowanie liczb z zakresu od 1 do 9. Procedurę losującą oznacza się słówkiem random.
Często zachodzi potrzeba wyświetlenia drugiego okna. W tym celu należy z menu File wybrać New Form i zapisać ją. Później w procedurze np. Button1 napisać:
Form2.showmodal;
w przypadku gdy drugie okno jest nazwane Form2. Słówko showmodal oznacza, okno modalne tj. takie, które będzie można modelować, czy zmieniać położenie. W przeciwnym wypadku wystarczy tylko słówko show.
ROZDZIAŁ 7
Do tej pory zajmowaliśmy się przede wszystkim funkcjami Object Pascala. Tym razem poznamy funkcje jakie oferuje nam Delphi.
Na początek zajmijmy się Inspektorem Obiektów. Tak to co widzicie po lewej stronie to Inspektor Obiektów. Tutaj właśnie mamy możliwość zarządzania komponentami; to tutaj znajdują się opcje dzięki którym zmienimy właściwości komponentu. Opcje Inspektora Obiektów zostały przedstawione w tabeli poniżej:
Active Control |
Z listy możesz wybrać komponent który będzie aktywny zaraz po uruchominiu programu. Np.: chcesz, aby zaraz po uruchomieniu programu aktywne było pole edycyjne - wybierasz z menu komponent np. Memo. |
AutoScroll |
Jeżeli właściwość ta ma wartość True to na formularzu pojawią się paski przewijania w przypadku gdy formularz jest za mały, aby pomieścić wsztkie komponenty. Z właściwością tą związane są też inne: HorzScrollBar i VertScrollBar. Określają one właściwość pionowego i poziomego paska przewijania. |
Border Icons |
Określa które z systemowych przycisków ma być widoczna na tytułowym pasku podczas działania programu. |
Border Style |
Ustala się typ ramki jaka będzie używana podczas pracy programu. bsDialog i bsNone oznaczają, że nie będzie możliwa zmiana rozmiarów okna. Przy wybraniu bsToolWindow formularz będzie zawsze na wierzchu i będzie można z niego korzystać nie wywołując go. |
Constrains |
Określa max. i min. wymiary formularza. |
DefaultMonitor |
Właściwość ta określa na którym monitorze ma być wyświetlany formularz. |
DockSite |
Właściwość ta określa czy w formularzu można dokować (umiejscawiać w innym miejscu) komponenty. |
Font |
Określa czcionkę jaka będzie używana przez formularz. |
Icon |
Możesz określić ikonę jaka będzie używana przez program (wyświetlnana na pasku stanu). |
KeyPreview |
Gdy ta właściwość ustawiona jest na True, będzie generowane zdarzenie formularza OnKeyPress i OnKeyDown. |
Position |
Właściwość ta określa położenie formularza po uruchomieniu. poDesigned oznacza, że formularz będzie tak ustawiony jak podczas jego projektowania. poDefault daje możliwość ustawienia okna programu według algorytmu Windows. Nowe okno jest ustawione nieco na prawo i nieco niżej od poprzedniego. poScreenCenter oznacz, iż program ustawiony będzie na samym środku ekranu. |
WidowsState |
Określa czy okno programu zaraz po uruchomieniu ma być zmaksymilizowane, zminimalizowane czy normalne. |
Visible |
Określa czy formularz jest widoczny True czy też nie: False |
ROZDZIAŁ 8
W tym rozdziale zajmiemy się sylwetką komponentu MediaPlayer.
Zaczniemy od komponentu MediaPlayer. Komponent ten znajduje się na palecie System. Służy on do odtwarzania muzyki w formacie *.mid i *.wav oraz filmów w formacie *.avi. Gdy umieścicie ten komponent na formularzu zobaczycie kilka przycisków służących do sterowania. Niekiedy zajdzie potrzeba ukrycia komponentu MediaPlayer. Wtedy należy wartości Visible przypisać wartość False. Zróbmy teraz programik, który będzie odrywał dźwięk po naciśnięciu przycisku:
Umieść na formularzu komponent MediaPlayer i zmień jego właściwość na False.
Umieść na formularzu przycisk i w procedurze OnClick wpisz następujący tekst:
procedure TForm1.GrajClick(Sender: TObject);
begin
MediaPlayer1.FileName:='muzyczka.wav'; //przypisanie komponentowi nazwy utworu
MediaPlayer1.Open; //otwarcie pliku
MediaPlayer1.Wait:=True; //otwarcie pliku w sposób synchroniczny
MediaPlayer1.Play; //odtwarzanie pliku muzycznego
MediaPlayer1.FileName:='muzyczka1.wav';
MediaPlayer1.Open;
MediaPlayer1.Wait:=True;
MediaPlayer1.Play;
end;
Objaśnienie: Zwróć uwagę na przypisanie wartości Wait komponentowi. Jest to niezbędne gdy chcemy odtwarzać jeden utwór za drugim. Gdyby wartość Wait miała wartość False to odtwarzanie kolejnego utworu nastąpiłoby zaraz po zakończeniu odtwarzania pierwszego (przerwa pomiędzy utworami trwałaby kilka milisekund). W przypadku muzyki z rozszerzeniem *.mid kod byłby taki sam z tymże nazwy utworów byłyby inne.
Niekiedy zachodzi konieczność odtworzenia pliku z rozszerzeniem *.wav w tle grającej muzyki.
W powyższym kodzie zmień właściwość FileName na muzykę z rozszerzeniem *.mid.
Zaznacz przycisk pojedynczym kliknięciem; w Inspektorze Obiektów kliknij na zakładkę Events
Odszukaj pole OnMouseMove i kliknij na nie. Najedź kursorem obok tego pola - kursor powinien zmienić się na tekstowy. Kliknij dwukrotnie.
Treść procedury OnMouseOver uzupełnij następująco:
procedure TForm1.GrajMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
PlaySound('C:\Moje dokumenty\click.wav',0,SND_FILENAME);
end;
5. Do listy modułów (uses) dodaj słowo MmSystem.
Uruchom program.
Zwróć uwagę na parametr SND_FILENAME. Używaj tego parametru gdy chcesz odtworzyć plik znajdujący się na dysku. Możliwe jest użycie innego parametru np.
PlaySound('MailBeep',0,SND_ALIAS);
Powoduje to odtworzenie pliku MailBeep o ile takowy jest przypisany w systemie Windows.
Zajmiemy się teraz odtwarzaniem filmów *.avi. Napiszemy program, który ma za zadanie wyświetlać filmy właśnie z rozszerzeniem *.avi.
Umieść na formularzu komponent MediaPlayer i zmień jego nazwę na Player
Umieść na formularzu komponent Panel (na palecie Standart), usuń tekst z właściwości Caption.
Umieść na formularzu przycisk Button
Umieść na formularzu komponent OpenDialog (na palecie Dialogs), zmień jego nazwę na OpenDialog.
Procedure OnClick przycisku uzupełnij następuąco:
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if OpenDialog.Execute then //wywołanie okna "Otwórz"
Player.FileName:=OpenDialog.FileName;
PLayer.Open;
Player.Display:=Panel1; //Panel1 będzie wyświetlaczem filmu
Player.DisplayRect:=Panel1.ClientRect; //Dostosowanie rozmiarów filmu do rozmiaru Panelu
end;
Objaśnienie: Na początku następuje wyświetlenie okna dialogowego "Otwórz". Później nazwa jaką wybrałem zostaje przydzielona komponentowi Player, następuje otwarcie pliku (zauważ, że przyciski komponentu MediaPlayer stały się aktywne). Jeżeli chcesz obejrzeć film na panelu to musisz dokonać przypisania: Player.Display:=Panel1; Wtedy jednak film zostanie obcięty do rozmiarów panelu. Żeby temu zapobiec musisz dokonać przypisania: Player.DisplayRect:=Panel1.ClientRect
Dokończenie tematu komponentu MediaPlayer w kolejnej części. Powyższy program możecie ściągnąć pod adresem:
www.programowanie.of.pl (naturalnie wraz z kodem źródłowym).
ROZDZIAŁ 9
Teraz dokończę omawiany ostatnio temat komponentu MediaPlayer. W tabeli poniżej przedstawiłem właściwości tegoż komponentu.
AutoRewid |
Określa, czy po zakończeniu odtwarzania wzkaznik pozycji ma być przesunięty na sam początek. Dzieje się tak gdy wartością będzie True. |
DeviceType |
Wartość bsAutoSelect powoduje automatyczny wybór urządzenia na podst. rozszerzenia pliku. |
Display |
Służy do określenia komponentu, które będzie służyć jako okno podczas wyświetlania (tak jak np. program który pisaliśmy ostatni, razem - w tym wypadku oknem jest Panel). |
DisplayRect |
Służy do dopasowania rozmiaru okna na którym wyświetlany będzie np. film (tak jak w poprzednim programie). |
EnabledButtons |
Określa, które przyciski powinny być dostępne podczas odtwarzania. |
EndPos |
Końcowy punkt plików multimedialnych. Dane takiego pliku odtwarzanie są od punktu StartPos do punktu oznaczonego EndPos. |
Frames |
Liczba klatego jaka będzie przesunięta po naciśnięciu przycisku Next lub Back. |
Mode |
Stan aktualny urządzenia. mbNotReady, mpStopped, mpPlaying, mpRecording, mpSeeking, mpPaused, mpOpen. Możesz wykorzystywać to w procedurach do badania w jakim stanie znajduje się urządzenie i ew. do zapobiegania błędom. |
Notify |
Jeżeli wartością jest True to z zakończeniem odtwarzania generowana będzie procedura właśnie OnNotify. |
NotifyValue |
Możliwe są wartości: nvSuccessful, nvSupersed, nvAborted, nvFailure. Możesz wykorzystywać te metody do badania z jakim skutkiem zakończone zostało odtwarzanie. |
Position |
Aktualna pozycja odtwarzanych danych multimedialnych. |
StartPos |
Patrz: EndPos. |
Wait |
Właściwość tę omawaiłem w poprzednim rozdziale. Gdy wartościąj est True - kolejny utwór odtwarzany będzie po kolejnym w pewnym odstępie czasu. Gdy wartością jest False kolejny utwór odtwarzany będzie natychmiast. |
Przy odtwarzaniu filmu lub/i muzyki ważną rzeczą może być odgrywanie utworu w pętli.
Otwórz program, który pisaliśmy ostatnio. Kliknij na komponencie MediaPlayer i z Inspektora Obiektów wybierz zakładkę Events
Kliknij na procedurze OnNotify i najedź kursorem obok. Powinien pojawić się kursor tekstowy - kliknij wówczas dwukrotnie. Procedurę tą uzupełnij następująco:
procedure TForm1.playerNotify(Sender: TObject);
begin
if player.NotifyValue= nvSuccessful then //gdy odtwarzanie dobiegnie końca.....
Player.Position:=0; //...przewiń do początku....
Player.Play; //... i zacznij odtwarzać.
end;
To nie koniec unowocześniania programu. Wyobraź sobie, że chciałbyś, aby użytkownik mógł powiększać lub pomniejszać twój panel w zależności od jego zachcianek. Zrób to tak:
Na formularzu umieść dwa przyciski SpeedButton (na palecie Additional).
Możesz umieścić na nich jakieś bitmapy. W Inspektorze Obiektów odszukaj właściwość Glyph i kliknij na symbol trzykropka zamieszczony obok. Naciśnij przycisk 'Load' i wybierz jakąś bitmapę.
Wartość GroupIndex obu przycisków zmień na 1. Oznacza to, że tylko jeden przycisk w dane chwili może być wciśnięty.
Kliknij dwukrotnie na pierwszym przycisku i treść procedury uzupełnij tak:
procedure TForm1.ButtonClick(Sender: TObject);
begin
if Button.Down=True then begin //Jezeli 1 przycisk jest wcisniety...
Panel1.Cursor:=crDrag; //to panelowi przypisz kursor - drag
end else //jezeli nie...
Panel1.Cursor:=crArrow; //pozotaw taki jak byl
end;
W tej procedurze następuje przypisanie Panelowi kursora - w tym wypadku o nazwie Drag. Istnieje możliwość załadowania własnego kursora, ale o tym kiedy indziej. Jeżeli przycisk jest "normalny" to kursor jest standardowy - Arrow.
5. Idziemy dalej - kliknij dwukrotnie na przycisku drugim i treść jego procedury uzupełnij następująco:
procedure TForm1.Button1Click(Sender: TObject);
begin
if Button1.Down=True then begin //j/w
Button1.Down:=False;
Panel1.Cursor:=crCross;
end else
Panel1.Cursor:=crArrow;
end;
W tym wypadku procedura ma bardzo podobną postać z tym, że tym razem panelowi przypisywany jest kursor o nazwie Cross.
6. Z polecenia File wybierz New Form. Umieść na nim Panel i jego właściwość Align zmień na alClient. Spowoduje to rozciągnięcie Panelu na cały obszar formularza. Po co tworzymy kolejny formularz? Gdy urzytkownik będzie powiększał Panel i przybierze on taki duży rozmiar w tedy ukazywany będzie formularz drugi i to właśnie na nim wyświetlany będzie film.
7. Kliknij teraz dwukrotnie na Panelu 1 naszego głównego formularza. Treść procedury uzupełnij następująco:
procedure TForm1.Panel1Click(Sender: TObject);
begin
//W przypadku klikniecia na panel...
//Jezeli nastapi klikniecie, a kursor to drag...
if Panel1.Cursor=crDrag then begin
Panel1.Width:=Pred(Panel1.Width - 5); //...zmniejsz szerokosc Panelu...
Panel1.Height:=Pred(Panel1.Height - 5); //... i wysokosc panelu.
Player.DisplayRect:=Panel1.ClientRect; //dostosuj roamiar filmu do rozmiaru Panelu
if ((Panel1.Width<=90) or (Panel1.Height<=80)) then //Jezeli wymiary sa mniejsze niz tu podane...
//...nastepuje wyswietlenie komunikatu:
ShowMessage('Cholera, jak jeszcze bardziej zmniejszysz to okno to nic nie zobaczysz :)');
end;
//Jezeli kursor to Cross...
if Panel1.Cursor=crCross then begin
//Nastepuje powiekszenie szerokosci...
Panel1.Width:=Succ(Panel1.Width + 5);
Panel1.Height:=Succ(Panel1.Height + 5); //...i wysokosci
Player.DisplayRect:=Panel1.ClientRect; //dostosowanie szerokosci Panlu do rozmiaru filmu
//Jezeli wymiary sa wieksze od tych tutaj podanych...
if ((Panel1.Height>=241) or (Panel1.Width>=345)) then
begin
//Wtedy nastepuje przypisanie okna wyswietlania
//Panelowi w oknie Form2
Player.Display:=Form2.Panel1;
Player.DisplayRect:=Form2.Panel1.ClientRect;
//no i w koncu wyswietlenie okna Form2
form2.Showmodal;
end;
end;
end;
OBJAŚNIENIE:
Trochę długa ta procedura, nie? N samym początku "badany" zostaje kursor. Jeżeli jest to Drag - wysokość i szerokość Panelu zostaje pomniejszona. Funkcję Pred omawiałem w poprzednich rozdziałach, ale mała powtórka nie zaszkodzi. Otóż ta funkcja pomniejsza w tym wypadku rozmiar Panelu o jeden. Czyli: Pred(100) daje liczbę 99 itd. Jako że rozmiar Panelu zmniejszał by się tylko o jeden (żeby zmniejszyć Panel należałoby się nieźle naklikac :)) odejmujemy od rozmiarów jeszcze 5 punktów.
Kolejny warunek (if ((Panel1.Width<=90) or (Panel1.Height<=80)) then) "sprawdza", czy rozmiary nie są zbyt małe. Jeżeli osiągną wymiary mniejsze od tych tutaj podanych - wtedy wyświetla się komunikat. (O komunikatach w następnym rozdziale.).
Jeżeli kursor to Cross - wtedy rozmiar Panelu powiększa się. Funkcja Succ powiększa o jeden, czyli: Succ(100) daje 101 itd. Do rozmiaru dodawane są jeszcze 5 punktów. I tak samo, gdy Panel będzie większy od podanych rozmiarów wtedy otwiera się okno Form2 i to właśnie na nim odtwarzany jest film.
ROZDZIAŁ 10
W poprzednim rozdziel zastosowałem komunikat ShowMessage. Możesz stosować taki komunikaty w zapobieganiu ew. błędów jakie wykona użytkownik programu. Konstrukcja jest prosta - najpierw słówko ShowMessage, a później treść komunikatu.
Istnieją jeszcze dwa typy komunikatów.
Umieść na formularzu dwa przyciski. W treści procedury pierwszego wpisz takie oto polecenie:
MessageDlg('To jest komunikat pierwszy :)', mtInformation, [mbOK], 0);
Ten komunikat wydaje Ci się trudniejszy? W pierwszym parametrze podawana jest treść komunikatu, w kolejnym jego typ (może być także mtError - wtedy obok komunikatu wyświetli się znana ikona Windowsa informująca o błędzie) - w tym wypadku mtInformation - obok komunikatu pojawi się "dymek". Parametr [mbOK] informuje, że pojawi się przycisk OK.
2. W treści drugiej procedury umieść taki oto kod:
Application.MessageBox('To jest komunikat 2', 'Błąd programu.',MB_OK);
W tym komunikacie masz możliwość ustalenia napisu jaki pojawi się w oknie komunikatu na pasku. Możesz też zrobić coś takiego:
var
Odp : Integer;
begin
Odp:= Application.MessageBox(
'Wystąpił błąd w programie. Czy chcesz poczytać Help'a?','Błąd', MB_YESNOCANCEL);
if Odp=IDYES then
{treść procedury}
if Odp=IDNO then
Close; {zakończenie programu}
if Odp=IDCANCEL then
Exit; {zamknięcie okna komunikatu}
To by było na tyle jeśli chodzi o komunikaty. Teraz zajmijmy się wyjątkami.
Pisząc program, a później oddając go do użytku nie jesteś w stanie przewidzieć zachowania osoby korzystającej z tego programu. Zawsze przecież taka osoba może zrobić coś, co nie jest tolerowane przez program. Wtedy ażeby zapobiec takim przypadkom powinieneś stosować wyjątki. Powróćmy do programu pisanego w Rozdziale 8. Procedura, która otwierała plik video wyglądała następująco:
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if OpenDialog.Execute then //wywołanie okna "Otwórz"
Player.FileName:=OpenDialog.FileName;
PLayer.Open;
Player.Display:=Panel1; //Panel1 będzie wyświetlaczem filmu
Player.DisplayRect:=Panel1.ClientRect; //Dostosowanie rozmiarów filmu do rozmiaru Panelu
end;
Zmodyfikujmy tę procedurę to takiej oto postaci:
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
try
if OpenDialog.Execute then //wywołanie okna "Otwórz"
Player.FileName:=OpenDialog.FileName;
PLayer.Open;
Player.Display:=Panel1; //Panel1 będzie wyświetlaczem filmu
Player.DisplayRect:=Panel1.ClientRect; //Dostosowanie rozmiarów filmu do rozmiaru Panelu
except
ShowMessage('To nie jest plik video lub wystąpił jakikolwiek inny bląd');
end;
OBJAŚNIENIE: Słówko try oznacza "spróbuj". Program wykonuje instrukcje zawarte po tym słowie. Jeżeli operacja się nie powiedzie następuje wykonanie instrukcji zawartych pod słowem except.
Istnieje jeszcze słowo finally, które wykorzystuje się wraz ze słowem try. Instrukcje zawarte po słowie finally zostaną wykonane niezależnie od czy operacja powiodła się, czy też nie. Zapytasz zapewne "Jaki jest sens stosowania tego słowa skoro instrukcje po nim zawarte wykonane będą niezależnie, czy operacja się powiedzie?". Słowo to stosuje się, aby upewnić się, że zostanie zwolniona pamięć jaka została przydzielona. Np:
var
Pamiec : Pointer;
begin
try
Pamiec:=AllocMem(1024);
finally
FreeMem(Pamiec);
end;
end;
W tym przypadku zostaje przydzielona pamięć, która zostanie zwolniona po zakończeniu działania procedury. To już wszystko tym razem. Już niebawem kolejny kurs. Odwiedzajcie tę stronę częściej lub wpiszcie się, aby być informowany emailem o uaktualnieniach.
ROZDZIAŁ 11
W tym rozdziale zajmiemy się grafiką. Przy programowaniu grafiki wykorzystywać będziemy klasę TCanvas. Jeżeli chcesz np., aby na formularzu wyświetlił się tekst - robisz coś takiego:
Canvas.TextOut(50,50,'Napis nr 1');
Dwa pierwsze parametry to (jak nietrudno się domyśleć) współrzędne X i Y napisu. W apostrofie umieszczony jest tekst który będzie wyświetlany na formularzu. Powyższy kod podstaw do procedury OnPaint głównego formularza. Jeżeli teraz uruchomisz program zauważysz, że rzeczywiście tekst jest, ale na białym tle. Przyznasz, ze nie wygląda to zachęcająco. Aby temu zapowiedz należy ustawić tło na przeźroczyste. Zrób więc coś takiego:
Canvas.Brush.Style:=bsClear;
Canvas.TextOut(50,50,'Napis nr 2');
Zanim ruszymy dalej poznaj funkcję klasy TCanvas.
Brush |
Kolor stosowany do wypełniania figur lub kolor pędzla. |
Pen |
Określa styl i kolor linii. |
PenPos |
Zawiera pozycje rysowania wyrażoną za pomocą X i Y |
BrushCopy |
Wyświetla bitmapę z przeźroczy tym tłem. |
Elipse |
Rysuje elipse |
LineTo |
Rysuje linie od punktu X do punktu Y |
MoveTo |
Wyznacza pozycję punktu rysowania. |
Rectangle |
Rysuje prostokąt. |
RoundRect |
Rysuje prostokąt z zaokrąglonymi narożnikami. |
TextOut |
Wpisuje tekst na płótnie. |
Oczywiście to tylko podstawowe funkcje. W procedurze np. OnPaint napisz słowo 'Canvas' i postaw kropkę. Poczekaj chwilę, powinna ukazać się lista z dostępnymi funkcjami.
Poeksperymentuj trochę z komponentem Shape (na palecie Additional). Możesz tam spokojnie dobierać kolory, style itp.
Oczywiście możesz także wyświetlić bitmapę i na niej umieścić jakiś tekst.
var
MojStyl : TBrushStyle;
Bitmap: : TBitmap;
begin
Bitmap:=TBitmap.Create;
Bitmap.LoadFromFile('C:\Image.bmp');
Bitmap.Draw(10,10,Bitmap);
MojStyle:=Canvas.Brush.Style;
Canvas.Brush.Style:=bsClear;
Canvas.TextOut(20,20,'Obrazek z wakacji :)');
Canvas.Brush.Style:=MojStyl;
Bitmap.Free;
end;
Objaśnienie: Na początku deklarujemy dwie zmienne: MojStyl i Bitmap. Pierwsza linia po begin oznacza stworzenie bitmapy. Kolejna ma za zadanie załadować bitmapę z określonej lokalizacji. Kolejna umieszcza ją na formularzu (współrzędne w tym wypadku wynoszą 10 i 10). Poźniej zmiennej MojStyl zostaje przypisany dotychczasowy styl. Robi się to po to, aby później nie trzeba było przywracać domyślnych ustawień, gdy chcesz stworzyć napis o innym stylu. W przedostanie i przedprzedostaniej następuje przywrócenie starego stylu i zwolnienie pamięci.
Funkcja DrawText
To jest trochę trudniejsza funkcja, której nie posiada klasa TCanvas. Pozwala ona na wpisanie tekstu w prostokąt i wyśrodkowanie ją w pionie i w poziomie. Najpierw zerknij na poniższy kod, a później wytłumaczę o co tu chodzi.
procedure TForm1.FormPaint(Sender: TObject);
var
R:TRect;
begin
Canvas.Brush.Color:=clBlue;
Canvas.Font.Color:=clWhite;
R:=Rect(20,20,300,80);
Canvas.Rectangle(20,20,300,80);
DrawText(Canvas.Handle,
'Funkcja DrawText',
-1,R,DT_SINGLELINE or DT_VCENTER or DT_CENTER);
end;
Prawda, że bardziej skomplikowane? Zmienna typu Rect zawiera współrzędne prostokąta. Dwie pierwsze liczby określają współrzędne lewego górnego rogu, a dwie ostatnie prawego dolnego. Te współrzędne są wymagane, aby okreslić punkty w jakich wyświetlany będzie test. Następny parametr rysuje prostokąt na ekranie według powyższych wartości koloru wypełniania i czcionki. Następnie następuje narysowanie tekstu przy pomocy funkcji DrawText. Słowo Handle oznacza uchwyt urządzenia biblioteki Windows API. Omówienie tego w innych rozdziałach. Cyfra -1 oznacza liczbę znaków które zostaną wyświetlone. Wartość -1 oznacza wszystkie znaki. Kolejna wartość 'R' to wspomniany wcześniej prostokąt w którym narysowany będzie tekst. Ostatnie 3 parametry oznaczają wyświetlenie tekstu pośrodku w pionie i w poziomie oraz w jednej linii. To by było na tyle na dzień dzisiejszy. Dokończenie tego tematu kolejnym razem. Teraz zapraszam do następnego rozdziału w którym to zrobimy przeglądarke.
ROZDZIAŁ 12
Napiszmy prostą przeglądarkę graficzną. Co Wy na to?
Uruchom Delphi; zmień wartość Caption formularza na 'Przeglądarka plików graficznych'; ustaw właściwość Forms Style na fsMdiForm.
Wybierz z menu plik 'New Form'. Zmień właściwość FormStyle nowego okna na fsMDIChild. We właściwości Name wpisz np. 'New'; umieść komponent Image - zmień jego wartość Stretch na True oraz wartość Aligin na alClient. Zapisz formularz pod nazwą 'NewWindow';
Zapisz wszytko; na głównym formularzu umieść komponent MainMenu. Kliknij na niego podwójnie - otworzy się nowe okno. W Inspektorze Obiektów w polu Caption wpisz 'Plik'. Naciśnij podwójnie na ten napis - powinno rozwinąć się menu.
W rozwiniętym menu w polu Caption wpisz np. 'Otwórz' i 'Zapisz jako'. Zamknij to okno.
Umieść na formularzu głównym komponent OpenPictureDialog i SavePictureDialog. Będą one odpowiedzialne jak zapewne się domyślasz za zapisywanie i otwieranie plików.
W formularzy głównym wybierz menu Plik -> Otwórz i uzupełnij je następującym kodem:
procedure TMainFrom.Open1Click(Sender: TObject);
var
NewWindows : TNewWindow; //W moim przypadku tak nazywa się nowe okno, które zrobiłem.
begin
if OpenPictureDialog1.Execute then begin //Metoda Eecute wywołuje okno - w tym wypadku OpenPictureDialog1
NewWindow:= TNewWindow.Create(Self); //utworzenie nowego okna - musi być przypisany wskaźnik Self
with NewWindow.Image1.Picture do begin
LoadFromFile(OpenPictureDialog1.FileName); //Załadowanie nowego pliku ze ścieżki jaką używa //komponent OpenPictureDialog
NewWindow.ClientWidth:=Width; //dopasowanie rozmiarów okna do rozmiarów obrazka
NewWindow.ClientHeight:=Height; //j/w
end;
NewWindow.Caption:=ExtractFileName(OpenPictureDialog1.FileName); //patrz niżej w objasnieniach
NewWindow.Show; //pokazanie nowego okna
end;
end;
OBJAŚNIENIE: Polecenie ExtractFileName oddziela ścieżkę dostępu do pliku od nazwy samego pliku. W tym wypadku na pasku stanu nowego okna będzie widniała nazwa pliku. Istnieją jeszcze inne podobne funkcje:
ExtractFileDir - wyświetla pełną ścieżkę dostępu do pliku.
ExtractFileExt - wyświetla rozszerzenie pliku
ExtractFileDrive - wyświetla literę dysku
Wydaje mi się, że pozostałe polecenia nie wymagają objaśnień. Jeżeli coś wydaje sie Ci nie jasne - pisz: boduch@poland.com
Nadszedł czas, aby stworzyć polecenie dla menu: Plik -> Zapisz jako. Przyjrzyj się poniższemu kodowi, a później to objaśnie:
if SavePictureDialog1.Execute then
with ActiveMDIChild as TNewWindow do
Image.Picture.SaveToFile(SavePictureDialog1.FileName);
OBJAŚNIENIE: Funkcja ActiveMDIChild oznacza aktywne okno. Nie bez powodu w formularzu głównym ustawialiśmy właściwość FormStyle na fsMDIFrm. Dzięki temu właśnie zachodzi możliwość otwierania kilku okien naraz.
W powyższej procedurze użyty został operator as. Jest to operator wiążący. Spróbuj napisać ten kod bez tego operatora - program się nie skompiluje gdyż kompilator nie wie czym jest Image. Trzeba połączyć to z TNewWindow, aby mieć dostęp do komponentu Image. Dalej następuje zapisanie obrazka do pliku, który wskazuje w oknie SavePictureDialog.
Teraz możesz już uruchomić program. Uwaga! Jeżeli program Ci się nie uruchomił a kompilator wskazuje błąd (nie wie co to jest TNewWindow) przejdź kursorem przed listę implementation i za nią dodaj taką linie:
uses TNewWindow;
Zostały jeszcze tylko drobne poprawki. Zauważ, że zaraz po uruchomieniu programu uruchamia się także nowe okno MDI. Nie chcemy żeby tak się działo więc z menu Project wybierz Options i kliknij na zakładkę 'Forms'. Kliknij na drugim formularzu MDI i naciśnij przycisk >
Zauważ również, że po otwarciu nowego okna i naciśnięciu krzyżyka okno się nie zamyka tylko minimalizuje. Przejdź do drugiego okna MDI i z Inspektora Obiektów wybierz zakładkę Events. Odszukaj polę OnClose i kliknij podwójnie. W edytorze kodu wpisz następująco linie:
Action := caFree;
Dzięki temu takie okno będzie się zamykało.
Nara!
ROZDZIAŁ 13
Pamiętasz jak w Rozdziale 11 pisałem o funkcji DrawText? Nie wspomniałem wówczas o tym, że funkcja ta posiada jeszcze jedną fajną rzecz:
var
R : TRect;
begin
R := Rect(100,100,120,120);
DrawText(Canvas.Handle,
'To jest długi tekst, który może się nie zmieścić.',
-1, R, DT_END_ELLIPSIS);
Tekst zostanie wówczas "obcięty", a na końcu pojawi się symbol trzykropka. To jest długi tekst,...
Istnieje jeszcze jeden znacznik, mianowicie DT_CALCRECT. Powoduje on dopasowanie tekstu do szerokości i wysokości prostokąta:
var
R : TRect;
S : String;
begin
R := Rect(10,10,100,100); //Wymiary prostokąta
S := 'Barrrrrrrrrrrrdzzzooooooooooooo długiiiiiiii tekst, któryyyyy może się nie zmieścić w jednej i '+
' dlatego zostanie umieszcony w kilku liniach'; //Tekst
DrawText(Canvas.Handle, PChar(S), -1, R, DT_CALCRECT or DT_WORDBREAK);
Canvas.Recttangle(R.Left, R.Top, R.Right, R.Bottom); //Narysowanie prostokąta o wymiarach podanych w zmiennej //Rect
DrawText(Canvas.Handl, PChar(S), -1, DT_WORDBREAK);
end;
OBJAŚNIENIE: Omówię tutaj tylko te znaczniki których nie omawiałem w poprzednim rozdziale. Na początek zwróć uwagę na typ PChar. Funkcja DrawText wymaga rzutowania tekstu w postaci zmiennej PChar, a nie String. Zauważ także to, że dwa razy napisałem DrawText. Wymaż przedostanią linie, uruchom program i zobacz co się stało. Owszem jest prostokąt, tekst jest dopasowany, ale prostokąt jest za duży. Gdy napisz to jeszcze raz bez użycia DT_CALCRECT obszar prostokąta zostanie dopasowany do ilości linijek tekstu.
Bitmapy
Rysowanie bitmap nie jest trudne - spójrz na poniższy przykład:
var
Bitmap : TBitmap;
begin
Bitmap := TBitmap.Create;
Bitmap.LoadFromFile('C:\obrazek1.bmp');
Bitmap.Draw(0,0,Bitmap);
Bitmap.Free;
end;
Na początku następuje stworzenie bitmapy, następnie załadowanie jej z określonej lokalizacji. Później następuje narysowanie bitmapy w lewym, górnym rogu. Na końcu następuje zwolnienie pamięci.
To jest dobry zposób jeżeli chcesz zachować domyślne rozmiary obrazka. Jeżeli chcesz mieć większą kontrole nad jego rozmiarem powinieneś zrobić raczej coś takiego:
var
Bitmap : TBitmap;
R : TRect;
begin
Bitmap := TBitmap.Create;
Bitmap.LoadFromFile('C:\obrazek1.bmp');
R := Rect(0,0,50,50);
Canvas.StretchDraw(R,Bitmap);
end;
W tym wypadku funkcja StretchDraw Rysuje bitmapę o określonych rozmiarach.
ROZDZIAŁ 14
Pamiętasz - w poprzednim rozdziale pisałeś przeglądarkę plików graficznych? Teraz napiszemy inną przeglądarkę - zapraszam.
1. Umieść na formularzu komponent Panel - wymaż jego właściwość Caption.
2. Umieść na formularzu komponent ToolBar.
2. Przejdź do zakładki 'Win 3.1'. Na Panelu umieść następujące komponenty:
- DirectoryListBox
- FileListBox
- DriveComboBox
- FilterComboBox
3. Umieść je na Panelu w kolejności podanej powyżej
4 We właściwości DirectoryListBox1 zmień właściwość FileList na FileListBox1.
5. We właściwości DriveComboBox1 zmień właściwość DirList na DirectoryListBox1.
6. We właściwości FilterComboBox1 zmień właściwość FileList na FileListBox1
6 Właściwość Align Panelu zmień na alLeft.
7. Umieść na formularzu komponent Image, zmień jego właściwość Align na alClient.
8. Kliknij pojedynczo na FilterComboBox1 i kliknij na właściwość Filter. Następnie naciśnij na symbol trzykropka - uruchomi się edytor filtrów. Po lewej stronie wpisuje się nazwę filtrów, a po prawej sam filtr. Wymaż filtry, które są tam napisane. Po lewej stronie wpisz np. "Pliki JPG", a po prawej: "*.jpg". Zrób tak jeszcze z rozszerzeniem *.ico, *.wmf itp.
9. Kliknij pojedynczo na komponent FileListBox1. W Inspektorze Obiektów kliknij na zakładkę 'Events' i odnajdź pole OnClick. Kliknij dwukrotnie na obszar obok tego pola - kod zdarzenia uzupełnij następująco:
procedure TForm1.FileListBox1Click(Sender: TObject);
begin
try
Image1.Picture.LoadFromFile(FileListBox1.FileName);
except
ShowMessage('To nie jest prawidłowy format plików.');
end;
Myślę, że objaśnienia są tu zbędne. Po prostu wyświetlony zostaje obrazek na który postawiony został kursor. Jeszcze jedna sprawa - do listy uses dodaj słówko: jpeg - pozwoli to na wyświetlanie obrazków w formaie *.jpg. (Funkcja ta niestety nie działa w Delphi 2).
Pozostało jedynie dodanie przycisków na Pasku ToolBar. Kliknij więc w jego obrębie prawym przyciskiem myszy i z menu wybierz NewButton. Stwórz w ten sposób jeszcze dwa przyciski.
Zmień właściwość Name pierwszego z nich na Save, a drugiego na Edit.
Umieść na formularzu komponent SavePictureDialog.
Treść procedury OnClick pierwszego uzupełnij tak:
if SavePictureDialog1.Execute then begin
Image1.Picture.SaveToFile(SavePictureDialog1.FileName);
end;
4. Treść procedury 2 przycisku uzupełnij następująco:
ShellExecute(Handle,'open',PChar(FileListBox1.FileName),nil,nil,SW_SHOWMAXIMIZED);
Metoda ShellExecute otwiera dany program - w tym wypadku domyślny program graficzny jaki przypisany jest danemu rozszerzeniu. Pierwszy parametr jest uchwytem okna gdyż jest to funkcja API. Następnie następuje rzutowanie nazwy pliku FileListBox1 na PCHar. Dwa kolejne parametry to wskaźniki (będziemy mówić o nich później). Ostatni parametr otwoera okno w postaci zmaksymilizowanej. Dostępne są też SW_HIDE, SW_SHOW, SW_SHOWNORMAL, SW_SHOWMINIMALIZE.
Dodaj jeszcze do listy uses słówko SHELLAPI Program możesz już odpalić. Pozostały jeszcze tylko kosmetyczne poprawki.
Fajnie by było gdyby na przyciskach widniały jakiś ikony, nie? Na palecie Win 32 znajduje się komponent ImageList - umieść go na komponencie. Naciśnij dwukrotnie na niego - otworzy się edytor w którym Importujemy ikony. Naciśnij na przycisku 'Add' i wybierz ikonę.Gdy wybierzesz dwie naciśnij na OK. Zaznacz komponent ToolBar1, w Inspektorze Obiektów z menu Images wybierz ImageList1. Ikony zostaną przypisane - program gotowy!
Cześć!
ROZDZIAŁ 15
Regiony
Nadszedł czas, aby zająć się regionami. Regiony są to wydzielone obszary płótna, w którym ograniczone są wszelkie operacje graficzne. Przykładowo:
W procedurze OnPaint formularza wpisz coś takiego:
var
Bitmap : TBitmap;
Region : HRGN;
begin
Bitmap := TBitmap.Create;
Bitmap.LoadFromFile('C:\Image.bmp');
Region := CreateEllipticRgn(50, 50, 200, 200);
SelectClipRgn(Canvas.Hande, Region);
Canvas.Draw(0,0, Bitmap);
Bitmap.Free;
end;
W tym wypadku zadeklarowana została zmienna Region. Następnie zmiennej przyporządkowane zostają dane współrzędne. W tym wypadku region będzie kołem o wymiarach 50, 50, 200, 200.
Istnieją także inne wymiary:
CreateRectRgn - tutaj regionem będzie kwadrat.
Istnieje też możliwość zadeklarowanie własnego regionu:
const
Punkty : array[0..3] of TPoint = ((X:50;Y:0), (X:0;Y:50), (X:70; Y: 150), (X: 150; Y:70));
{tak jak wyżej}
Region := CreatePolygonRgn(Punkty, 4, ALTERNATE);
Zadeklarowana zostaje tutaj tablica, która określa pozycje czterech punktów. Zauważ, że najpierw następuje zadeklarowanie zmiennej array, która określa tablice. Zauważ również, że są jedynie zadeklarowane 3 cyfry. Czwartym punktem jest cyfra 0.
Następnie następuje zapisanie współrzędnych X i Y.
Powoli zbliżamy się do końca omawiania grafiki. Z przyczyn ode mnie nie zależnych ten rozdział jest taki krótki. Spotkamy się za dwa tygodnie.
Na razie!
ROZDZIAŁ 16
W tym rozdziale zajmiemy się jeszcze tablicami i innymi temu podobnymi, ale już od przyszłego rozdziału zaczniemy pisać edytor plików HTML.
Tablice
Do czego służą tablice? Załóżmy, że chcesz w pamięci komputera umieścić tablicę w której chcesz zapisać 10 liczb typu Integer. Taka deklaracją wyglądałaby następująco:
var
Tablica : array[0..9] of Integer;
Zauważ specyficzną budowę tablicy. Rozmiar tablicy poprzedzony jest słówkiem array. W nawiasach kwadratowych następuje wpisanie cyfr (rozmiaru tablicy). Na końcu następuje przypisanie zmiennej.
Każdy element tablicy zajmuje 4 bajty. Łatwo więc wyliczyć, że deklaracja powyższej tablicy zajmować będzie w pamięci 40 bajtów.
Teraz gdy chcesz się odwołać do poszczególnego elementu np. w celu przypisania jej jakiejś liczby należy zrobić to tak:
Tablica[0] := 200;
Tablica[1] := 40;
Tablica[5] := -150;
itd....
Tablice możesz wypełniać także po jej zadeklarowaniu, lecz wtedy musisz użyć stałej const.
const
Tablica : array[0..2] of Integer = (100, 200, 300);
W Delphi 4 wprowadzono Tablice Dynamiczne, czyli takie których pamięć można przydzielać w zależności od potrzeb.
var
Tablica : array of Integer;
begin
SetLength(Tablica, 20);
Zauważ, że na początku nie podano rozmiarów tablicy. Nastąpiło to dopiero wtedy gdy użyta została funkcja SetLength - nastąpiło wówczas wpisanie rozmiaru - 20.
W czasie wykonywania programu możesz zwiększać rozmiar tablicy przy pomocy funkcji Copy.
Copy(Tablica, 400);
W powyższym przypadku nastąpiło zwiększenie rozmiarów tablicy do 400.
W połączeniu z tablicami używane są także funkcję Low i Height. Funkcja Low zwraca indeks pierwszego elementu tablicy, a funkcja Height ostatniego.
var
Pierwszy, Ostatni : Integer;
Tablica : array[2..4] of Integer;
begin
Pierwszy := Low(Tablica);
Ostatni := Height(Tablica);
Metody i klasy
Na pewno podczas programowania w Delphi zauważyłeś tajemnicze słówka private, public. Metody są to funkcje, procedury, które są składnikami klasy. Klasa natomiast jest obiektem składającym się z procedur i funkcji. Klasy posiadają swoje deklarację, które to umieszcza się zawsze w sekcji type. Żeby lepiej to zrozumieć wykonajmy program, a konkretnie animację. Wykorzystasz w ten sposób wiedzę zdobytą w poprzednich rozdziałach:
Umieść na formularzu dwa przyciski. Przejdź teraz do edytora kodu (F12) i przesuń kursor przed sekcję Implementation. Odszukaj wyraz private. Pod nim umieść następującą zmienną:
Done : Boolean;
Na formularzu umieść także komponent Gauge (na palecie Samples).
Treść procedury pierwszego przycisku uzupełnij następująco:
Done := False;
while not Done do begin
Application.ProcessMessages;
Sleep(100);
Gauge1.Progress := Succ(Gauge1.Progress);
if (Done) then
Break;
Treść procedury OnClick drugiego z przycisków uzupełnij następująco:
Done := True;
OBJAŚNIENIE: Na samym początku zmiennej Done przypisywana jest wartość False. W następnej linii wykorzystana jest pętla while. Użyty jest tutaj operator not, całe wyrażenie w tłumaczeniu oznacza: "Jeżeli Done nie jest wartością True wykonuj następujące polecenia". Wydaje mi się, że 3 kolejne linie nie wymagają objaśnień. Warto wspomnieć o dwóch ostatnich liniach. Zauważ, że wartości done nie jest przypisywana wartość True tzn. jest, ale nie musisz tego pisać - jest to wartość domyślna.
Teraz rozumiesz o co chodzi? W sekcji private możesz umieszczać nazwy zmiennych, które używasz w wielu procedurach. Nie musisz za każdym razem deklarować tej zmiennej w każdej procedurze.
Metody prywatne (private) - jak sama nazwa wskazuje są to metody do które nie są widoczne na zewnątrz klasy, nie można się do nich odwoływać z funkcji i procedur będących w innej klasie.
Metody publiczne (public) - zawierają funkcję za pomocą których możesz "komunikować" się ze światem zewnętrznym
published - ten poziom dostępu używany jest przy pisaniu komponentów. Zawiera właściwości które znajdą się w Inspektorze Obiektów.np:
published
property Align;
Zapraszam do lektury kolejnego rozdziału w którym zajmiemy się pisaniem odtwarzacza filmów *.avi.
ROZDZIAŁ 17
Pamiętacie kiedy pisaliśmy program AVI Films Player? Teraz go trochę ulepszymy:
Najlepiej będzie jeżeli zaczniesz wszystko od początku. Stwórz więc nowy projekt i ustaw jego właściwość Height na 411. Właściwość Width zmień na 360.
W Inspektorze Obiektów rozwiń pole Border Icons i zmień właściwość biMaximize na False.
Umieść na formularzu komponent Panel i jego wymiary i położenie zmień według tu podanych: Height: 225, Left: 8, Top: 0, Width: 329. Zmień kolor tła Panelu na czarny, a kolor używanej czcionki na biały.
Umieść na formularzu komponenty: PopupMenu, MainMenu, Timer, OpenDialog, MediaPlayer, BitBtn, ScrollBar, Panel, TrackBar, Label, StatusBar.
MediaPlayer: Width: 197, Height: 30, Left: 8, Top: 227; VisibleButtons: btRecord, btEject = False.
BitBtn: Width: 115, Height: 30, Left: 222, Top: 227, Caption = Otwórz
ScrollBar: Height: 17, Width: 331, Top: 261, Left: 6, Name = Scroll
Panel: Name: Panel2, Left: 6, Top: 280, width: 331, Height: 27; kolor tła: czarny, kolor tekstu: biały
TrackBar: Left: 224, Width: 113, Height: 29, Top: 312, Max: 5, TrickMarks: tmBoth, TrickStyle: tsAuto
Label: Caption = Ustaw głośność; umieść go obok komponentu TrackBar (po jego lewej stronie).
Dobra, teraz program powinien już jakoś wyglądać. Kliknij na komponencie MainMenu. W rozdziale w którym pisaliśmy przeglądarkę omawiałem jak tworzyć menu więc nie będę się tutaj na ten temat rozpisywał. Stwórz menu 'Plik', a w nim pola: Otwórz, Zamknij, Zakończ. Następnie stwórz menu 'Widok', a w nim: Standardowy, Minimalny, wstaw poziomą linie (w pole Caption wpisz znak '-'), Pełny ekran, Zawsze na wierzchu.
Teraz zajmiemy się uzupełnianiem kodu. Zacznijmy od przycisku 'Otwórz':
//wywolanie okna dialogowego "Otworz"
if openDialog.Execute then begin
//przypisanie nazwy jakiej uzywa OpenDialog
Player.FileName:=OpenDialog.FileName;
//otwarcie pliku
PLayer.Open;
Player.Enabled := True;
//przypisanie obrazu panelowi
Player.Display:=Panel1;
Player.DisplayRect:=Panel1.ClientRect;
Panel1.Caption := ExtractFileName(OpenDialog.FileName);
Panel2.Caption := 'Stan: Film zatrzymany';
end;
Wydaje mi się, że ta procedura nie wymaga większych objaśnień.
Kliknij teraz dwukrotnie na komponencie MediaPlayer. Tereść procedury jest następująca:
{Komponentowi ScrollBar przypisywana jest długość filmu}
Scroll.Max := Player.Length;
{Dopasowanie pomocy i napisu na panelu}
Panel2.Caption := 'Trwa odtwarzanie ' + ExtractFileName(OpenDialog.FileName) + '...';
Panel1.Hint := 'Odtwarzanie filmu | Trwa odtwarzanie filmu: '+ ExtractFileName(OpenDialog.FileName);
if Button = btStop then begin
{Jezeli nacisniety zostanie przycisk Stop film zostanie zatrzymany
dopasowane zostana napisy oraz Timer stanie sie nieaktywny}
Player.Stop;
Panel2.Caption := 'Stan: Film zatrzymany';
Timer1.Enabled := False;
end
else
Timer1.Enabled := True;
Panel2.Caption := 'Stan: Film uruchomiony';
if Button = btPlay then begin
{Jezeli film zostanie odtworzony - zmieni sie tresc napisu na
panelu}
Panel2.Caption := 'Stan: Film uruchomiony';
end;
if Button = btStop then begin
{Zatrzymanie filmu zpowosuje zmiane napisu}
Panel2.Caption := 'Stan: Film zatrzymany';
end;
Uzupełnij tak procedurę OnScroll komponentu ScrollBar:
if Player.Enabled = False then
{Jezeli Player jest nieaktywny - nic sie nie dzieje..}
Exit;
{...jezeli film jest otwarty - jego pozycja jest przypisana
pozycji komponentu ScrollBar}
Player.Position := Scroll.Position;
Teraz kliknij dwukrotnie na komponencie TrackBar. Będzie to regulacja głośności:
{Ustawienie glosnosci obu glosnikow na...}
case TrackBar1.Position of
1:
WaveOutSetVolume(0, $40004000);{4000}
2:
WaveOutSetVolume(0, $60006000); {6000}
3:
WaveOutSetVolume(0, $80008000); {8000}
4:
WaveOutSetVolume(0, $90009000); {9000}
5:
WaveOutSetVolume(0, $FFFFFFFF);{dzwkek na maxa}
end;
OBJAŚNIENIE: Tutaj zatrzymam się na chwilę, aby objaśnić tę funkcję. Użyta została tutaj instrukcja case. W przypadku gdy suwak ustawiony jest na pierwszym "ząbku" ustawiony zostaje dźwięk na obu głośników na wartość 4000. Dźwięk jest typu Integer, ale jego wartość musi mieć 4 cyfry. W tym przypadku głośność obu głośników jest jednakowa.
Kliknij dwukrotnie na komponencie Timer. Treść procedury wyglądać będzie następująco:
SCroll.Position := Player.Position;
Kliknij podwójnie na komponencie MainMenu; kliknij na zakładkę 'Widok'; kliknij na przycisku 'Standardowy' i zmień jego właściwość RadioItem na True oraz GroupIndex na 1. Zrób to samo z przyciskiem 'Minimalny'.
Kliknij podwójnie na przycisku 'Standardowy' i procedurę uzupełnij tak:
Standardowy1.Checked := not Standardowy1.Checked;
if Standardowy1.Checked = True then
Label1.Visible := True;
TrackBar1.Visible := True;
Panel2.Visible := True;
{Pokazanie komponentow}
Form1.Height := 420;
{Zwiekszenie formy}
Kliknij dwukrotnie na przycisku minimalny i jego procedurę uzupełnij następująco:
Minimalny1.Checked := not Minimalny1.Checked;
if Minimalny1.Checked = True then begin
Label1.Visible := False;
TrackBar1.Visible := False;
Panel2.Visible := False;
Form1.Height := 350;
end;
Myślę, że do tej pory wszystko było jasne. Teraz nadszedł czas, aby uzupełnić procedurę 'Zawsze na wierzchu'.
Na_wierzchu.Checked := not Na_wierzchu.Checked;
if Na_wierzchu.Checked = True then
Form1.FormStyle := fsStayOnTop {Jezeli wlasciwosc jest prawdziwa
wlaczona zostaje opcja "Na wierzchu"}
else
Form1.FormStyle := fsNormal;
Teraz nadszedł czas, aby stworzyć drugą formę. Zrób to, a na drugim formularzu umieść komponent Panel - zmień właściwość Align na alClient. Uzupełnij kod procedury 'Pełny ekran':
Form2.BorderStyle := bsNone;{ukrycie gornego paska}
Form2.WindowState := wsMaximized;{maximilizacja okna}
Player.Display := Form2.Panel1;{przypianie obrazu do Panelu na Formie drugiej}
Player.DisplayRect := Form2.Panel1.ClientRect;{dopasowanie rozmiaru
filmu do rozmiarow Panelu}
Form2.PopupMenu := Form1.PopupMenu1;{Przypisananie Panelowi Menu rozwijalnego}
Form2.ShowModal;{ukazanie okna Form2}
OBJAŚNIENIE: Najpierw ukrywana zostaje "belka" formy, a formularz zostaje zmaksymilizowany - odnosimy wówczas wrażenie, że film wyświetlany jest na pełnym ekranie.
Kliknij teraz na komponencie PopupMenu. Stwórz w nim tylko jedno pole o nazwie: 'Pełny ekran'; zmień właściwość Checked na True.
{Ta procedura przywrca "normalny" rozmiar okna tj. zamyka zmaksymilizowany film}
Form1.Player.Display := Form1.Panel1;
Form1.Player.DisplayRect := Form1.Panel1.ClientRect;
Timer1.Enabled := True;
Form2.Close;
Program jest prawie skończony. Pozostało jeszcze tylko napisanie właściwości zamykającej film:
Player.Stop; {Zatrzymanie odtwarzania}
Player.Enabled := False;{dezaktywacja...}
Timer1.Enabled := False;
Scroll.Position :=0;
Panel1.Caption := 'Zamknięto film';{Przypisanie panelowi teksu}
Panel2.Caption := 'Stan: Zamknięto film';
Procedurę zamykająca program (Plik -> Zakmknij): Application.Termiante;
Mamy już napisaną procedurę otwierającą plik video, lecz ta procedura nie jest przypisana do menu: Plik -> Otwórz. Myślę, że sami potraficie to zrobić.
ROZDZIAŁ 18
Ten rozdział będzie całkowicie poświęcony dystrybucji sieciowej twoich programów.
Załóżmy, że masz program i chciałbyś, aby można go było umieścić na stronie tj. używać bezpośrednio na stronie WWW. Tak to jest możliwe. Przejdź do sekcji programy na tej stronie i wybierz program "Kółko i Krzyżyk". Zauważ, że oprócz przycisku "Pobierz" znajduje się również napis: "Uruchom ze strony". Naciśnij go - program "Kółko i Krzyżyk" uruchomi się bezpośrednio ze strony WWW. W tym rozdziale opiszę co zrobić, aby można było umieścić program na stronie WWW.
Wybierzcie z menu File polecenie New.
Kliknijcie na zakładkę 'Active X'.
Kliknijcie dwukrotnie na przycisk 'Active Form'.
Otworzy się okno które musicie wypełnić. W polu New ActiveX Name wpisz np. 'Main1stFormX'. Pozostałe pola zmieniły się - możesz zostawić tak jak jest. Nim klikniesz na przycisku 'OK' zaznacz pole Include Version Information.
Delphi zbuduje formularz na którym możesz umieszczać komponenty jak na zwyczajnym formularzu. zrobimy przykładowy program np. jakiś mały przykładowy programik. Niech będzie to na przykład forma z przyciskiem. Po naciśnięciu program automatycznie tworzy losowo rozmieszczane komponenty Edit.
Stwórz przycisk i treść jego procedury OnClick uzupełnij następuąco:
var
Edit : TEdit; //Deklaracja zmiennych
Y,i : Integer;
X : Integer;
begin
for i:=0 to 5 do begin //zastosowanie petli For
Edit := TEdit.Create(Self); //Tworzenie komponentu Edit
Edit.Parent := Self; //Przypisanie rodzica kompoenntu
x:=Random(400); //Losowanie liczb...
Y:=Random(400);
Edit.Left := X; {Przypisanie wartości X i Y dla położenia kontrolek Edit
Edit.Top := Y;
Edit.Text := 'Kontrolka nr '+IntToStr(I); //Nadanie właściwości Text kontrolek
end;
OBJAŚNIENIE: Zastosowana zostaje tutaj pętla for dlatego, że stworzonych zostaje 5 kontrolek. Wyjaśnienia wymagają dwie kolejne linie. To dzięki nim następuje stworzenie kontrolek. Możliwe jest również tworzenie kontrolek we wnętrzu innych komponentów. Deklaracja taka wyglądałaby wówczas tak:
Edit := TEdit.Create(Self);
Edit.Parent := Memo;
W powyższym wypadku kontrolka Edit stworzona zostanie we wnętrzu komponentu Memo. W przypadku gdy zdeklarowany jest wskaźnik 'Self' rodzicem zostaje formularz.
Następnie następuje losowanie liczb z zakresu od 0 do 399. Zmienne X i Y zostają przypisane położeniu kontrolek. Chciałbym także podkreślić znaczenie przedostatniej linii. Powoduje ona iż każdej kontrolce zostaje przypisany inny numer. Można by to było zrobić również tak:
Edit.Text:=Format('Kontrolka nr nr %d',[I]);
Znak " %d " informuje kompilator, że "w tym miejscu umieszczona zostanie zmienna typu Integer. Możliwe jest zastosowanie także znaku " %s " który informował by kompilator, że "w tym miejscu umieszczona zostanie zmienna typu String".
Gdy już masz gotowy formularz zapisz go. Z menu Run wybierz Register ActiveX Server. Następnie zbuduj projekt (Project -> Bulid). Z menu Component wybierz Import ActiveX Control. Z listy, która się ukaże wybierz swoją kontrolkę. W polu Palette page wybierz ActiveX (Jeżeli nie posiadasz takiego pola - to je wpisz). Następnie kliknij na przycisku Install - pojawi się okno instalacji. W polu FileName powinna znajdować się nazwa DCLUSR50.BPl. Jeżeli tak nie jest wybierz ją z listy. Kliknij na przycisku Ok i potwierdź budowę (Yes). Ok, teraz mamy już gotową kontrolkę ActiveX.
Wybierz polecenie Project -> Web Deployment Options - jest to okno konfiguracji. W polu traget dir wpisz nazwę katalogu gdzie ma być skopiowana kontrolka po jej zbudowaniu. Traget URL służy do określenia gdzie na serwerze ma być zamieszczona kontrolka. W polu HTML Dir wpisujesz gdzie Delphi ma zapisać gotową stronę WWW z programem.
Zaznacz polę Use CAB file compression. Pole to określa czy program ma być skompresowany, czy też nie.
Pole Include file version information decyduje o tym, czy Delphi powinno włączać numer wersji. Niektóre przeglądarki nie załadują kontrolki jeżeli włączony jest numer wersji (NN).
Auto increment relase number - zaznaczenie tego pola powoduje, że za każdym razem przy rozpowszechnianiu zwiększany jest numer wersji.
Czas abyś wreszcie zbudował kontrolkę. Kliknij na przycisku OK zamykając to okno. Z menu Project wybierz Web Deploy - kontrolka zostanie zbudowana. Przejdź do katalogu w którym postanowiłeś umieścić kontrolkę. Znajduje się tam strona WWW i plik *.cab z programem. Teraz pozostaje już uruchomienie strony w edytorze HTMLa i odpowiednie jej "upiększenie". Później możesz już opublikować stronę na serwerze.
ROZDZIAŁ 19
Jeszcze trochę na temat wyjątków
Omawiając wyjątki nie wspomniałem wówczas o jeszcze jednej ważnej rzeczy. Mianowicie o selektywnej obsługi wyjątków. Spójrz na poniższy kod:
try
Image1.Picture.LoadFromFile('C:\Image.jpg');
except
on EInvalidGraphic do begin
MessageDlg('To nie jest plik graficzny!', mtError, [mbOK], 0);
end;
on EInvalidImage('Ten opbrazek jest uszkodzony!',mtError, [mbOK], 0);
end;
Jak widzisz program może obsłużyć wiele wyjątków w zależności od zaistniałej sytuacji. W pierwszym przypadku jeżeli obrazek nie będzie miał formatu graficznego wywołany zostanie pierwszy komunikat. Jeżeli obrazek jest uszkodzony wywoływany jest komunikat drugi. Poniżej napisałem kilka najpopularniejszych typów:
EFOpenError - W przypadku błędu podczas otwarcia pliku.
EFCreateError - W przypadku złego np. zapisania pliku.
EWriteError - W przypadku złego wpisania np. do pliku.
EComponentError - W przypadku błędu komponentu.
EInvalidOperation - W przypadku błędu podczas wykonywania jakiejś operacji.
Możliwe jest także napisanie własnego wyjątku.
W sekcji interface przed sekcją implementation wpisz taką linie kodu:
type
EMojWyjatek = class(Exception);
Teraz możesz pisać:
except
on EInvalidGrapihic do begin
{tu wpisz obsługę wyjątku};
end;
on EMojWyjatek do begin
{tu wpisz obsługę swojego wyjątku}end;
W powyższym przykładzie zadeklarowałeś własny typ wyjątku (nowa klasa).
Trochę na temat wywoływania okien komunikatów
Pamiętacie jak pisałem o wywoływaniu okien?
MessageDlg('Hej!', mtInformation, [mbOK], 0);
Można także ustawić położenie takiego okna:
MessageDlgPos('Hej',mtInformation, [mbOK], 0, 20,2);
W powyższym przypadku okno zostanie ustawione o pozycji 20 i 2. Można też zrobić tak:
ShowMessagePos('Hej',20,2);
Przeciążanie
Przeciążanie to nowość w Delphi 4. W poprzednich wersjach Delphi musiałeś pisać coś takiego:
function Dodawanie(L1, L2 : Integer) : Integer;
function Dodawanie2(L1, L2 : Double) : Double;
Teraz możesz pisać tak:
function Dodawanie(L1, L2 : Integer) : Integer; overload;
function Dodawanie(L1, L2 : Double) : Double; overload;
Rozumiesz w czym rzecz? W poprzednich wersjach Delphi nie tolerowało nazw funkcji o takich samych nazwach. Teraz jest to możliwe dzięki zastosowaniu słówka overload.