Wiadomości wstępne
Wiadomości wstępne
Wprowadzenie.
W epoce DOS-u tworzenie aplikacji za pomocą języka programowania takiego jak Turbo Pascal zajmowało bardzo dużo czasu. Dużą jego część poświęcano na tworzenie interfejsu użytkownika.
W momencie pojawienia się systemu Windows programista dostał do ręki nowe narzędzia. Mógł wykorzystać gotowe funkcje, które tworzyły podstawowe elementy aplikacji , takie jak: okna, przyciski, grupy opcji itp. Niestety, programowanie w WinAPI było zadaniem bardzo trudnym i wymagało sporej wiedzy i umiejętności.
Wkrótce jednak pojawiło się rozwiązanie: Rapid Application Development (RAD)(szybkie tworzenie aplikacji). Narzędzia te oferowały już na starcie gotowe okno aplikacji. Aby dodać do niego jakieś elementy, np. przyciski, wystarczy przeciągnąć je myszką z paska narzędzi. Za pomocą myszki można dowolnie zmienić ich położenie i rozmiary.
Borland Delphi jest narzędziem RAD umożliwiającym szybkie tworzenie aplikacji działających w systemie Windows. Ma dwie podstawowe cechy:
jest wizualny tzn. pozwala przenosić myszką elementy aplikacji (np. przyciski) i układać je w oknach.
jest obiektowy tzn. oparty jest na obiektowej wersji Pascala (Object Pascal).
Doświadczenie zdobyte podczas programowania w Borland Pascalu będzie w Delphi owocować i ułatwi pracę z nowym narzędziem. Język Object Pascal wchodzący w skład Delphi jest zgodny z językiem Borland/Turbo Pascal . W czasie programowania nie można odwoływać się do takich modułów jak: Crt, DOS, Graph itp. Ze starej biblioteki zachowano jedynie moduł System, który został znacznie rozwinięty. Istnieją też różnice w nazwie funkcji, np. zamiast Close, jest CloseFile. W Object Pascalu został wprowadzony nowy model typu obiektowego definiowany za pomocą słowa kluczowego class.
Tworzenie aplikacji w Delphi jest dwutorowe (ang. two-way-tools). Pierwszym torem są narzędzia wizualne, drugim - pisanie kodu źródłowego. Najważniejsze jest to, że wszystko co zrobisz za pomocą narzędzi wizualnych jest automatycznie uwzględniane w kodzie źródłowym. Obydwie drogi są równie ważne: narzędzia wizualne służą do szybkiego projektowania interfejsu użytkownika, jednak aby aplikacja robiła coś konkretnego, musimy to napisać za pomocą języka Object Pascal.
Środowisko programistyczne.
Elementy środowiska programistyczne: formularz, paleta komponentów, Inspektor obiektów, edytor kodu
Środowisko Delphi (menu, okna itd.), w którym tworzymy aplikacje, jest zintegrowane (IDE - Integrated Development Environment). Zawiera wiele potrzebnych narzędzi do ułatwienia pracy programiście
Elementy widoczne po uruchomieniu Delphi
Formularz
Formularz używamy jako kanwy lub umieszczamy na nim komponenty, tworząc w ten sposób interface użytkownika. Komponenty są swoistymi klockami, z których możemy budować aplikację. Są one umieszczone na Palecie komponentów. Można myśleć o formularzu jako o komponencie, który może zawierać inne komponenty. Główny formularz Twojej aplikacji wraz z innymi formularzami (np. oknami dialogowymi) tworzy interface Twojej aplikacji. Formularz wygląda i zachowuje się jak każde standardowe okno Windows.
Właściwości formularza (określające np. tekst na pasku tytułu) można zmieniać korzystając z Inspektora Obiektów (Object Inspector). Określając właściwości dowolnego komponentu określamy jego wygląd i zachowanie
Tworzenie formularzy ułatwiają nam
Szablony projektów (Project Templates -umożliwiają wybór aplikacji) i formularzy (Form Templates ).
Expert projektów (Project Experts ) i Expert formularzy (Form Experts ) tworzą projekt i formularz zgodnie z naszymi wyborami. Np. Database Form Expert tworzy formularz wyświetlający dane z zewnętrznej bazy danych.
Paleta komponentów (Component palette)
Komponenty są elementami, z których budujemy aplikację. Mogą być widoczne (przyciski, pola tekstowe, etykiety) lub niewidoczne w czasie działania aplikacji.
Komponenty są pogrupowane na różnych stronach (fiszkach) palety komponentów. Można tworzyć własne komponenty i umieszczać je na palecie komponentów.
Inspektor obiektów (Object Inspector)
Inspektor obiektów służy do łatwego określania wyglądu i zachowania komponentów. W oknie inspektora obiektów pojawiają się właściwości wyróżnionego obiektu na stronie Properties (właściwości) . Na stronie Events (zdarzenia) umieszczony jest spis zdarzeń, na które reaguje komponent. Możemy tu dołączyć do odpowiedniego zdarzenia procedurę obsługi zdarzenia (event handlers ).
Selektor obiektów(Object selector)
Jest to rozwijana lista na górze inspektora obiektów, która zawiera spis wszystkich komponentów formularza (także sam formularz) i umożliwia wygodne przełączanie pomiędzy nimi.
Edytor kodu (Code Editor)
Wpisujemy tu kod programu. Każdy moduł ma swoją zakładkę. Wystarczy na nią kliknąć aby oglądać kod odpowiedniego modułu.
Pasek szybkiego dostępu (SpeedBar)
Umożliwia dostęp do najczęściej używanych komend z menu File, Edit, View.
Wybrane elementy niewidoczne podczas pierwszego uruchomienia.
Menadżer projektów (Project Manager)
Menadżer projektów wyświetla listę plików, które wchodzą w skład aktualnie tworzonej aplikacji. Umożliwia łatwą nawigację pomiędzy plikami. Przyciski dostępne w Menadżerze projektów umożliwiają tworzenie nowych formularzy i modułów, oglądanie plików aktualnego projektu, zachowanie wszystkich plików.
Projektant Menu (Menu Designer)
Dzięki niemu możemy w łatwy sposób dodawać menu do formularzy.
Debuger (Integrated debugger)
Delphi ma wbudowany debuger służący pomocą przy wykrywaniu błędów w programie.
Tworzenie przykładowej aplikacji.
tworzenie nowego formularza.
Dodawanie komponentów do formularza
Ustawianie właściwości formularza i komponentów w Inspektorze obiektów
Zostanie tu zaprezentowana bardzo prosta aplikacje, która umożliwia zmianę koloru formularza po kliknięciu przycisku. Przykład ten ma na celu zaprezentowanie tworzeniu aplikacji w Delphi:
Projektowanie formularza
Obsługa zdarzeń
Projektowanie formularza
Projektowanie formularza polega na prostym rozmieszczeniu obiektów (komponentów) w oknie (formularza).
Kolejne kroki wykonywane przy tym to:
Tworzenie nowego formularza
Przy uruchomieniu Delphi otrzymujemy już pusty formularz (projekt).
ä Uruchamiamy Delphi.
Dodanie komponentów do formularza
Pierwsza przykładowa aplikacja ma tylko jeden komponent - przycisk (button component).
ä Kliknij Button component na standardowej stronie palety komponentów, następnie kliknij w miejscu, gdzie chcesz umieścić komponent np. na środku formularza.
Ustawienie właściwości
Właściwości określają wygląd obiektu i jego zachowanie. Można je ustawiać w Inspektorze obiektów lub w kodzie programu.
W naszym przykładzie ustawimy tytuł (caption) dla formularza i dla przycisku.
ä Zmień właściwość Caption dla Form1 na 'Mój program demonstracyjny'. Potem zmień właściwość Caption dla Button1 na 'Kolor'. Zauważ, że efekty dokonywanych zmian są od razu widoczne na pasku tytułu formularza i na przycisku.
Atrybut (właściwość) Name
Ta właściwość identyfikuje komponent i jest wykorzystywana przede wszystkim w kodzie programu. Bardzo dobrą praktyką jest nadawanie komponentom czytelnych nazw i unikanie takich jak Form1 lub Button1.
Uwaga Nazwa komponentu jest identyfikatorem i nie może zawierać polskich liter ani spacji. Tytuł jest tekstem i może zawierać dowolny ciąg znaków.
Kompilowanie i uruchamianie projektu.
Kompilowanie i uruchamianie projektu
Za każdy razem, gdy dodajesz nowy komponent, Delphi tworzy odpowiedni kod programu.
Po wybraniu komendy Run tworzony jest wykonywalny program .EXE.
ä Uruchom program wybierając Run
Zauważ, że dodane komponenty zachowują się zgodnie z oczekiwaniami: przycisk się wciska (choć nic się nie dzieje), można zmieniać myszką rozmiary okna formularza itp. Każdy komponent ma już wbudowane typowe reakcje, których nie musisz programować.
Powinniśmy jednak zaprogramować zachowanie programu w odpowiedzi na pewne zdarzenia (events) takie jak np. kliknięcie przycisku. Dokonujemy tego w kodzie programu.
ä Zakończ działanie aplikacji (zamknij okno aplikacji).
Obsługa zdarzeń.
Obsługa zdarzeń
Zdarzenia (events) reprezentują działania użytkownika (albo przerwania systemowe), które twoja aplikacja może rozpoznać np. kliknięcie myszką. Kod programu, który określa jak komponent powinien odpowiedzieć na zdarzenie nazywa się obsługą zdarzenia (event handler).
Strona Events w Inspektorze obiektów wyświetla wszystkie zdarzenia przyporządkowane do wybranego komponentu.
Możesz użyć Inspektora obiektów do utworzenia obsługi zdarzenia dla dowolnego komponentu. Po dwukrotnym kliknięciu na wybrane zdarzenie Delphi tworzy część kodu. Na przykład następujący kod jest początkowym zarysem obsługi zdarzenia, które Delphi tworzy dla zdarzenia OnClick przycisku Button1 na formularzu Form1:
procedure TForm1.Button1Click(Sender: TObject);
begin
end;
Kod programu, który ma być wykonany zawsze, gdy zajdzie odpowiednie zdarzenie zapisujemy pomiędzy begin i end (w bloku procedury).
n Tworzenie obsługi zdarzenia,
1 Zaznacz komponent, wybierz w Inspektorze obiektów zakładkę Events.
2 Dwukrotnie kliknij obok właściwego zdarzenia. Zostanie utworzona procedura obsługi zdarzenia w Edytorze kodu i kursor zostanie automatycznie umieszczony w bloku begin..end.
3 Wpisz teraz polecenia, które chcesz, aby były wykonane kiedy wystąpi to zdarzenie.
ä Utwórz procedurę obsługi zdarzenia dla zdarzenia OnClick przycisku, i wpisz następujący kod w bloku procedury:
Form1.Color := clAqua;
Oznacza to, że w momencie kliknięcia przycisku właściwość Color formularza zostanie zmieniona na clAqua.
Cała procedura obsługi zdarzenia wygląda teraz tak:
procedure TForm1.Button1Click(Sender: TObject);
begin
Form1.Color := clAqua;
end;
ä Wypróbuj procedurę obsługi zdarzenia, którą właśnie napisałeś. (Uruchom program).
Pliki wchodzące w skład projektu.
Elementy projektu: plik projektu, plik modułu, plik formularza
Najprostszy projekt, na przykład domyślny Project1 zawiera plik z kodem w Pascalu (moduł) .PAS i plik zawierający zapisany w postaci tekstowej „obraz” formularza (.DFM). Oba te pliki są niezbędne do utworzenia formularza.
Plik projektu (.DPR)
Jest również tworzony dla każdego projektu. Zawiera program główny, łączący w jedną całość wszystkie plik projektu. Domyślny plik projektu zawiera:
Domyślną nazwę projektu (np. Project1).
Deklarację modułów (także należących do projektu formularzy, które są modułami).
Część główną programu uruchamiającą aplikację.
n Aby obejrzeć plik projektu .DPR:
1 Wybierz View|Project Source
Plik projektu jest tworzony automatycznie. W przypadku dodania nowego formularza plik projektu jest automatycznie aktualizowany.
ä Dodaj nowy, pusty formularz do projektu i obejrzyj zmiany w pliku projektu.
Zostanie dodany nowy moduł (Unit2), plik (UNIT2.PAS) oraz identyfikator formularza (Form2).
Plik modułu (.PAS)
Domyślny plik modułu zawiera:
Domyślną nazwę modułu.
Powinna być zmieniona na bardziej znaczącą np. główny moduł programu może się nazywać MainForm. Nazwę modułu można zmienić za pomocą polecenia File|Save As lub przy pierwszym zachowywaniu projektu.
Część interface zawierającą:
Deklaracje modułów uses
Deklaracja typu formularza (klasa - formularz)
Deklaracja zmiennej obiektowej (obiekt - formularz)
Po utworzeniu nowego formularza deklaracja potrzebnych modułów jest wykonywana automatycznie.
Część implementation z kodem źródłowym formularza.
n Aby obejrzeć plik modułu formularza .PAS:
1 Wybierz zakładkę z nazwą odpowiedniego pliku w oknie edytora kodu (Code Editor). Jeśli w oknie Edytora kodu jej nie ma, wybierz View|Units....
Plik formularza (.DFM)
Plik .DFM jest plikiem binarnym i na ekranie jest widoczna jego graficzna reprezentacja.
Można jednak oglądać plik formularza w postaci tekstowej otwierając go w oknie edytora kodu (Code Editor).
Moduły nie związane z formularzem
Większość modułów jest związana z formularzem, ale można też tworzyć moduły niezależne.
Przy tworzeniu niezależnego modułu Delphi generuje tylko następujący kod
unit Unit2;
interface
implementation
end.
Sami musimy zadeklarować użycie potrzebnych modułów.
Zachowywanie projektu
Zachowywanie projektu
Można zachować wybrany formularz lub cały projekt.
n Aby zachować bieżący formularz (i jego moduł), wybierz File|Save lub kliknij na przycisk Save.
n Aby zachować projekt i wszystkie pliki wchodzące w jego skład wybierz File|Save All.
n Aby zachować kopię projektu w nowym położeniu wybierz polecenie File|Save Project As i podaj nowy katalog i ewentualnie nową nazwę projektu.
Jeśli chcemy, aby pliki modułów również zostały skopiowane w nowe położenie musimy dla każdego z nich indywidualnie wybrać polecenie File|Save File As.
Każdy plik projektu powinien mieć unikatową nazwę, mówiącą jednocześnie o jego przeznaczeniu. Najlepiej jeżeli główny plik projektu nosi nazwę odpowiadającą przeznaczeniu aplikacji. Wszystkie pliki danego projektu powinny być umieszczone w oddzielnym katalogu.
Nazwy plików powinny być poprawnymi identyfikatorami, tzn. nie mogą zawierać polskich liter i spacji.
Komponenty.
Możemy je znaleźć na palecie komponentów. Komponenty są typu wizualnego i niewizualnego. Komponenty wizualne pojawiają się na formularzu dokładnie w takiej samej postaci, jak podczas uruchomienia aplikacji. Niewizualne takie jak np. MainMenu wyglądają zupełnie inaczej w trakcie projektu i podczas uruchomienia. W projekcie widać komponent MainMenu, podczas uruchomienia nie widać komponentu tylko menu.
Komponent - formularz
Formularz jest komponentem, który zwiera inne komponenty. Domyślnie komponent formularza nie pojawia się na palecie komponentów, ale można go tam umieścić.
Paleta komponentów.
Paleta komponentów
Zostaną tu przedstawione tylko dwie strony z palety komponentów.
Uwaga Ikona wskaźnika pojawia się na każdej stronie palety komponentów. Wybór wskaźnika umożliwia wybranie komponentów z palety.
Komponenty na stronie standardowej
Wizualny |
Nazwa komponentu |
Zastosowanie |
|
MainMenu
|
Menu. Tworzy pasek menu wraz z rozwijanym menu. |
|
PopupMenu |
Menu podręczne. Tworzy podręczne menu rozwijane po kliknięciu prawym klawiszem myszki na formularzu lub komponentach |
|
Label |
Etykieta. Tworzy etykietę wyświetlającą teksy. Zwykle opisuje inne komponenty na formularzu. |
|
Edit |
Pole tekstowe. Tworzy na formularzu obszar, gdzie użytkownik może wprowadzać i modyfikować pojedynczą linię tekstu. |
|
Memo |
Memo. Wyświetla obszar w którym użytkownik może wprowadzać i modyfikować wiele linii tekstu. |
|
Button
|
Przycisk. Tworzy przycisk. |
|
CheckBox
|
Pole wyboru. Prezentuje opcje typu Tak/ Nie, Wł/Wył, True/False itp. |
|
RadioButton |
Przycisk opcji. Zwykle używane w grupach opcji, w których można wybrać tylko jedną opcję. |
|
ListBox |
Pole listy. Wyświetla listę, z której można wybrać jeden lub kilka elementów. |
|
ComboBox |
Pole kombi. Łączy pole edycji z listą wyboru. Użytkownik może pisać tekst w pole edycji lub wybrać element z listy. |
|
ScrollBar |
Pasek przewijania. Pasek przewijania, który przewija na przykład elementy na liście lub może służyć do zmiany jakiejś wartości. |
|
GroupBox
|
Pole grupy. Grupuje inne komponenty na formularzu. |
|
RadioGroup
|
Grupa opcji. |
|
Panel |
Panel. Grupuje inne komponenty, zwykle używamy go do utworzenia paska statusu lub paska narzędzi. |
Komponenty na stronie Additional (dodatkowej)
Wizualny |
Nazwa komponentu |
Zastosowanie |
|
BitBtn
|
BitBtn. Tworzy przycisk, na którym dodatkowo można umieścić bitmapę. |
|
SpeedButton |
Przyciski z bitmapą (ale bez tekstu), umieszczone na panelu tworzą paski narzędzi. |
|
MaskEdit |
Podobny do pola tekstowego, ale dodatkowo potrafi formatować wyświetlaną informację i tworzyć maskę wprowadzania dla danych. |
|
StringGrid
|
Wyświetla informacje tekstowe w postaci tabeli. |
|
DrawGrid
|
Wyświetla informacje inne niż teksty w postaci tabeli. |
|
Image
|
Wyświetla bitmapy, ikony lub pliki w formacie WFM. |
|
Shape
|
Rysuje geometryczne kształty: elipsę, prostokąt, zaokrąglony prostokąt. |
|
Bevel
|
Tworzy linie lub prostokąty, które są wypukłe lub wklęsłe (efekt 3D). |
|
ScrollBox |
Tworzy obszar, w którym automatycznie pojawiają się paski przewijania, gdy wyświetlany obiekt jest większy niż ten obszar. |
Komponenty na stronie Windows 95
Zostaną omówione później.
Komponenty na stronie Data Access
Umożliwiają operację na bazie danych.
Komponenty na stronie Data Controls
Ułatwiają operacje na danych w bazie danych. Są tu takie elementy kontrolne jak: pola tekstowe, pola kombi, pola listy, grupa opcji i inne.
Komponenty na stronie Windows 3.1
Znajdują się tu komponenty występujące w wersji Delphi 1.0, wykorzystywane w Windows 3.1. W Windows 95 stosujemy ich odpowiedniki przystosowane do tego systemu (znajdują się one na stronie Windows 95).
Komponenty na stronie System
Wizualny |
Nazwa komponentu |
Zastosowanie |
|
Timer |
Komponent wywołuje zdarzenie OnTimer w określonych przedziałach czasu. |
|
PaintBox |
Oferuje prostokątny obszar, na którego kanwie (czyli na nim) możemy rysować, bez obawy wyjścia poza ten obszar. |
|
FileListBox |
Wyświetla przewijaną listę plików znajdujących się w bieżącym katalogu. |
|
DirectoryListBox |
Wyświetla listę katalogów bieżącego napędu. Zmiana katalogu na liście powoduje zmianę bieżącego katalogu. |
|
DriveComboBox |
Wyświetla rozwijaną listę dostępnych napędów. Można tu zmienić bieżący napęd. |
|
FilterComboBox |
Służy do tworzenia filtrów, ograniczających zbiór wyświetlanych plików. |
|
MediaPlayer |
Wyświetla panel kontrolny do odtwarzania i nagrywania plików AVI, MID i WAV. |
|
OLEContainer |
Tworzy obszar do łączenia i osadzania obiektów OLE |
|
DDEClientConv |
Komponent do nawiązania połączenia DDE (obszar klienta) |
|
DDEClientItem |
Komponent do nawiązania połączenia DDE (określa dane do wymiany - klienta) |
|
DDEServerConv |
Komponent do nawiązania połączenia DDE (określa serwer) |
|
DDEServerItem |
Komponent do nawiązania połączenia DDE (określa dane do wymiany - serwera). |
Komponenty na stronie Dialogs
Wyświetlają okna dialogowe wspólne dla środowiska Windows. Zostaną omówione później.
Manipulowanie komponentami na formularzu.
Właściwość Name
Umieszczanie komponentów na formularzu
Wycinanie, kopiowanie i wklejanie komponentów
Grupowanie komponentów
Wyrównywanie komponentów
Właściwość Name
Każdy element aplikacji (komponent) musi mieć unikalną nazwę. Nazwa komponentu musi spełniać te same zasady co identyfikatory w Pascalu.
Uwaga Po zmianie nazwy komponentu w Inspektorze obiektów, zmianie ulegnie również nazwa tego komponentu w Edytorze kodu. Ale nie odwrotnie! Po zmianie nazwy komponentu w edytorze kodu Delphi może mieć kłopoty z załadowaniem formularza.
Przykład: tworzenie formularza About.
ä Na początku rozpocznij nowy projekt.
ä Ustaw właściwości formularza:
Name - ustaw AboutBox.
Caption - ustaw About .
BorderStyle - ustaw na bsDialog .To ustawienie usuwa z formularza przycisk Minimize i Maximize i sprawia, że nie będzie można zmienić rozmiarów formularza.
Position - ustaw na poScreenCenter . Nasz formularz pojawi się na środku ekranu. To ustawienie nie jest widoczne w trybie projektu.
Dodawanie komponentów do formularza
n Aby dodać komponent do formularza:
1 Wybierz komponent na palecie a następnie kliknij na formularzu w miejscu, gdzie ma się on znaleźć.
ä Ze strony Additional wybierz komponent BitBtn i umieść go w dolnej środkowej linii formularza AboutBox.
Delphi dodaje komponent jako pole do definicji klasy formularza.
type
TAboutBox = class(TForm)
BitBtn1: TBitBtn; { ten kod dodaje Delphi )
end; { reszta kodu ominięta dla większej przejrzystości }
Podobnie - jeżeli komponent zostanie usunięty z formularza, deklaracja komponentu jest automatycznie usuwana z deklaracji klasy formularza.
Zmiana rozmiaru komponentu
n Tworzenie komponentu o wybranym rozmiarze:
1 Wybierz komponent na palecie komponentów.
2 Zaznacz myszką obszar na formularzu, który ma zająć komponent i puść klawisz myszki.
ä Dodaj komponent Image w dolnym lewym rogu formularza ustalając od razu jego rozmiar.
Wybieranie komponentów na formularzu
Można to zrobić na kilka sposobów
n Aby zaznaczyć pojedynczy komponent :
Kliknij na komponent na formularzu.
Wybierz go z Selektora obiektów znajdującego się na górze Inspektora obiektów.
Mając zaznaczony dowolny inny element na formularza wciskaj odpowiednio długo klawisz Tab.
n Aby zaznaczyć grupę obiektów:
Trzymając wciśnięty klawisz Shift klikaj na komponenty, które chcesz zaznaczyć.
Zaznacz myszką obszar, w który znajdują się wybrane komponenty. .(Jeśli komponenty znajdują się wewnątrz komponentu Panel lub GroupBox najpierw wciśnij Ctrl)
n Aby zaznaczyć wszystkie komponenty na formularzu, wybierz Edit|Select All.
Zmiana rozmiaru komponentów
Kiedy komponent jest zaznaczony na formularzu, na jego brzegu znajdują się małe kwadraciki, zwane uchwytami rozmiaru.
n Aby zmienić rozmiar pojedynczego elementu, zaznacz go, a następnie uchwyć myszką uchwyty rozmiaru i przeciągnij do uzyskania satysfakcjonującego rozmiaru.
n Aby zmienić rozmiar kilku elementom (wyrównać ich wielkość):
1 Zaznacz wybrane komponenty, wybierz Edit|Size , a następnie wybraną opcję.
ä Dodaj komponent Panel , a następnie powiększ go tak, aby nie wypełniał większość formularza, ale nie zakrywał innych komponentów.
Dodanie wielokrotnych kopii komponentu
n Aby dodać kilkakrotnie ten sam komponent:
1 Podczas wybierania komponentu z palety trzymaj wciśnięty klawisz Shift
2 Aby odblokować wybór komponentu kliknij przycisk wskaźnika na Palecie komponentów.
ä Dodaj dwa komponenty Label w dolnej części formularza AboutBox, z prawej strony przycisku BitBtn.
Grupowanie komponentów
Oprócz formularza w Delphi jest kilka komponentów, które służą do grupowania innych w jedną całość. Takie komponenty noszą nazwę zbiorczych (container components ). Są nimi np. GroupBox, Panel, ScrollBox.
Kiedy umieszczamy komponent wewnątrz komponentu zbiorczego, tworzona jest w ten sposób relacja rodzic - potomek pomiędzy komponentem zbiorczym i jego elementami. Zmiany dokonywane na rodzicu takie jak kopiowanie, usuwanie czy przesuwanie odnoszą się również do jego potomków.
Uwaga Formularz jest właścicielem dla komponentów w nim zawartych.
Zazwyczaj najpierw dodajemy do formularza komponent zbiorczy np. Panel, a dopiero potem wybieramy z palety komponentów jego elementy, podobny sposób jak dodajemy je do formularza. Dodanie kilku elementów tego samego typu możemy sobie ułatwić przez wciśnięcie klawisza Shift (podobnie jak przy dodawaniu kilku komponentów tego samego typu do formularza). Jeżeli na formularzu już mamy komponent, który chcemy dodać do komponentu zbiorczego, to możemy to zrobić wycinając do, a następnie wklejając do komponentu zbiorczego.
äDodaj dwa komponenty typu Label do komponentu Panel component.
Wycinanie, kopiowanie i wklejanie komponentów
Podczas kopiowania są również kopiowane właściwości komponentu wraz z procedurami obsługi zdarzeń. Zmieniana jest jedynie nazwa komponentu, tak, aby każdy element na formularzu miał unikatową nazwę.
Przy zaznaczaniu obiektów do kopiowania należy pamiętać, że mogą być zaznaczone tylko obiekty posiadające tego samego rodzica.
Wklejane komponenty pojawią się obok kopiowanych komponentów
Procedury obsługi zdarzeń kopiowanych obiektów nie są kopiowane, jedynie w kopiach obiektów jest umieszczane odwołanie do oryginalnych procedur
n Aby skopiować (wyciąć) obiekty wybierz Edit|Copy (Edit|Cut ).
n Aby wkleić obiekty zaznacz formularz lub komponent zbiorczy w którym chcesz umieścić kopiowane obiekty wybierz Edit|Paste .
ä Wytnij dwie etykiety (Label) znajdujące się na formularzu i wklej je do komponentu Panel. A następnie wytnij obiekt Image i wklej go w lewym górnym rogu Panelu.
Kasowanie i odtwarzanie komponentów
n Aby skasować komponent zaznacz go i wciśnij Del lub wybierz Edit|Delete.
n Aby odtworzyć komponent, który właśnie został skasowany wybierz Edit|Undelete. Uwaga: komponent można odtworzyć tylko natychmiast po skasowaniu, zanim zostaną wykonane inne operacje.
Wyrównywanie komponentów
n Aby wyrównać komponenty:
1 Zaznacz komponent (komponenty).
2 Wybierz View|Alignment Palette, a następnie kliknij na odpowiednią ikonę lub wybierz Edit|Align a następnie wybraną opcję. Możesz kontynuować wyrównywanie komponentów tak długo, jak długo są zaznaczone.
ä Wyrównaj do lewej dwie górne etykiety (Label). Zrób to samo dla dwóch dolnych etykiet
Wykorzystywanie siatki formularza do wyrównywania
Siatka formularza ułatwia wyrównywanie komponentów. Domyślnie siatka oraz opcja Snap To Grid (powodująca automatyczne wyrównywanie obiektów do najbliższego oczka siatki) są włączane.
Można też zmieniać odstęp pomiędzy oczkami siatki.
n Aby zmieniać ustawienia siatki formularza wybierz Tools|Options , a następnie stronę Preferences.
Blokowanie pozycji komponentów
Jeżeli już ustawimy komponenty możemy je zabezpieczyć przed przypadkowym przemieszczeniem.
n Aby zablokować pozycję komponentu wybierz Edit|Lock Controls .
Ustawianie właściwości komponentów.
Wyświetlanie i ustawianie właściwości jednocześnie dla kilku komponentów
Wykorzystanie edytora właściwości
ä Zmień właściwości komponentów na formularzu About zgodnie z tabelką:
Komponent |
Właściwość |
Wartość |
Panel |
Name |
PanelTla |
|
BevelOuter |
BvLowered |
|
Caption |
<Blank> |
Image |
Name |
IkonaProgramu |
Label1 |
Name |
NazwaProduktu |
Label2 |
Name |
Wersja |
Label3 |
Name |
Copyright |
Label4 |
Name |
Komentarz |
|
AutoSize |
False |
|
WordWrap |
True |
BitBtn |
Name |
PrzyciskOK |
Wyświetlanie i ustawianie właściwości jednocześnie dla kilku komponentów
n Aby wyświetlić i ustawić właściwości jednocześnie dla kilku komponentów
1 Zaznacz kilka komponentów. W Inspektorze obiektów zostaną wyświetlone ich wspólne właściwości, które można zmienić. Jeśli komponenty mają różne właściwości wyświetlana jest właściwość pierwszego zaznaczonego elementu. Właściwość Name nie jest wyświetlana.
ä Wypróbuj zaznaczanie kilku obiektów:
1 Zaznacz komponent BitBtn i Panel. Obejrzyj ich wspólne właściwości.
Wykorzystanie edytora właściwości
Aby wpisać nową wartość właściwości możemy ją wpisać, wybrać z listy lub skorzystać z edytora właściwości.
Dla niektórych właściwości dwukrotne kliknięcie w kolumnie Value otwiera okno dialogowe, ułatwiające zmianę wartości właściwości. Właściwości, dla których są takie okna są oznaczone w Inspektorze obiektów trzema kropkami (...). Dla niektórych komponentów dwukrotne kliknięcie na komponent na formularzu otwiera takie okno. Przykładem takiego komponentów jest Image.
n Aby umieścić obrazek na formularzu:
1 Dodaj komponent Image i dwukrotnie na nim kliknij.
2 W oknie dialogowym Picture Editor kliknij przycisk Load..
3 W oknie dialogowym Load Picture zaznacz opcję bitmapa (.BMP), ikona (.ICO), lub Windows
Metafile (.WMF).
4 Wybierz obraz, który chcesz wstawić i kliknij OK. lub powtórz poprzednie kroki by wybrać inny obraz.
ä Wstaw obraz z biblioteki Delphi (Image Library) do komponentu Image.
ä Zachowaj projekt.
Domyślna nazwa |
Zmień na: |
UNIT1.PAS |
ABOUT.PAS |
UNIT2.PAS |
MAINFORM.PAS |
PROJECT1.DPR |
MYPROJ.DPR |
Ustawianie właściwości w czasie uruchomienia aplikacji
Każdą właściwość można zmieniać nie tyko w czasie projektu, ale również w czasie uruchomienia aplikacji wykorzystując kod programu. Są również właściwości, które można ustawiać tylko za pomocą kodu (run-time-only ). Aby ustawić właściwość w kodzie musimy podać nazwę komponentu, nazwę odpowiedniej właściwości i podać nową wartość. Jeśli komponent ma ustawioną właściwość i w czasie projektu i w kodzie to aktualna jest ta ustawiona w kodzie.
Praca z kodem
Większość kodu pisanego w Delphi to procedury obsługi zdarzeń lub jest przez nie wykorzystywane. Najczęściej dwukrotnie klikamy przy odpowiedniemu zdarzeniu w oknie Inspektora obiektów, aby napisać procedurę obsługi tego zdarzenia. Możemy też pisać procedury i funkcje niezależne, które pełnią najczęściej rolę pomocniczą.
Generowanie procedury dla domyślnego zdarzenia
Dla większości komponentów jest określone zdarzenie domyślne. Dwukrotne kliknięcie na takim komponencie powoduje generowanie procedury obsługi takiego zdarzenia. Na przykład dwukrotne kliknięcie na przycisku (Button) powoduje generowanie procedury obsługi zdarzenia OnClick .
Praca z edytorem kodu
Kiedy otwierasz nowy projekt Delphi automatycznie generuje stronę w Edytorze kodu dla pierwszego pliku projektu. Z każdym razem. gdy dodajesz do projektu nowy moduł czy formularz Delphi dodaje kolejną stronę do Edytora kodu.
Oglądanie stron w Edytorze kodu
n Aby obejrzeć stronę w Edytorze kodu, wybierz jedną z następujących metod:
Kliknij fiszkę z nazwą odpowiedniej strony.
Wybierz View|Units (lub kliknij na przycisk View Unit) aby otworzyć okno dialogowe View Unit dialog i wybrać moduł, który chcesz oglądać.
n Aby wrócić do formularza wybierz jedną z następujących metod:
Kliknij na dowolny fragment formularza widoczne spod Edytora kodu.
Wybierz View|Form (lub kliknij na przycisk View Form) aby otworzyć okno dialogowe View Form i wybierz formularz. który chcesz oglądać.
Wyszukiwanie istniejącej procedury obsługi zdarzenia
n Aby wyszukać istniejącą procedurę obsługi zdarzenia w Edytorze kodu:
1 W formularzu zaznacz komponent, którego procedury poszukujesz.
2 W Inspektorze obiektów dwukrotnie kliknij obok zdarzenia, które obsługuje poszukiwana procedura.
n Aby wyszukać istniejącą procedurę obsługi domyślnego zdarzenia danego komponentu dwukrotnie kliknij ten komponent na formularzu.
Powiązanie zdarzenia z istniejącą procedurą obsługi zdarzeń
Jedną procedurę obsługi zdarzenia można powiązać z kilkoma zdarzeniami. Na przykład jedna procedura może być powiązana z odpowiednią pozycją w menu i z odpowiednim przyciskiem na pasku narzędzi.
Wykorzystanie parametru Sender
Parametr Sender informuje Delhi, który komponent otrzymał zdarzenie i wywołał procedurę. Można napisać procedurę obsługi zdarzeń połączoną z kilkoma komponentami wykorzystując ten parametr do identyfikacji komponentu, który otrzymał zdarzenie.
ä Procedura obsługująca zdarzenie OnClick dla przycisku Kolory:
procedure TMainForm1.KoloryClick(Sender: TObject);
begin
if Sender = Kolory then
Edit1.Text := 'Wybrałeś kolory '
else Edit1.Text := 'Inny przycisk';
end;
n Aby połączyć nowy komponent z istniejącą procedurą obsługi zdarzeń:
1 W Inspektorze obiektów przejdź do odpowiedniego zdarzenia komponentu, dla którego chcesz dodać procedurę.
2 Wybierz z listy odpowiednią procedurę. Lista wyświetla procedury, które mogą być połączone z danym zdarzeniem
ä Połącz zdarzenie OnClick przycisku Button2 z procedurą Button1Click. Zauważ, że Delphi nie duplikuje procedury a jedynie umieszcza jej wywołanie.
ä Uruchom program i kliknij Button1. Nazwa aplikacji pojawia się w nagłówku okna. Zamknij okno dialogowe i kliknij Button2 . W nagłówku okna nie ma nazwy aplikacji.
Wyświetlanie i kodowanie procedur dla kilku zaznaczonych komponentów
n Aby powiązać zdarzenie kilku komponentów z istniejącą procedurą obsługi zdarzenia:
1 Zaznacz odpowiednie komponenty i w Inspektorze obiektów wyświetl stronę Events.
2 Wybierz z rozwijanej listy przy właściwym zdarzeniu właściwą procedurę.
n Aby stworzyć procedurę obsługi zdarzenia dla kilku komponentów:
1 Zaznacz odpowiednie komponenty i w Inspektorze obiektów wyświetl stronę Events.
2 Wpisz nazwę nowej procedury i wciśnij Enter lub dwukrotnie kliknij, aby Delphi sam utworzył nazwy dla procedur.
3 Wpisz odpowiedni kod w bloku begin..end procedury.
ä Aby zobaczyć powyższe w przykładzie:
1 Dodaj komponent do formularza MainForm.
2 Zaznacz Button1 i wyświetl stronę Events w Inspektorze obiektów.
3 Zaznacz dodatkowo (tak, aby dwa komponenty były zaznaczone).
4 Przy zdarzeniu OnClick wybierz z listy procedurę Button1Click.
ä Uruchom program i kliknij SpeedButton. Powinno się ukazać okno dialogowe About.
Modyfikowanie procedur obsługi zdarzeń kilku zaznaczonych komponentów
Jeśli zaznaczymy klika komponentów i przejdziemy do procedury obsługi dowolnego zdarzenia to modyfikowanie jest takie jak w przypadku jednego zdarzenia. Należy jednak pamiętać, że zmieniając procedurę modyfikujemy ją dla wszystkich zdarzeń komponentów, które ją wywołują (także te, które nie zostały zaznaczone).
n Aby zmodyfikować procedurę obsługi zdarzenia dla kilku zaznaczonych komponentów:
1 Zaznacz odpowiednie komponenty i w Inspektorze obiektów wyświetl stronę Events.
2 W Edytorze kodu zmień procedurę obsługi zdarzenia
ä Zmodyfikuj procedurę obsługi zdarzenia OnClick dla Button1 poprzez dodanie następującej linii przed wywołaniem metody ShowModal , gdzie <path> jest ścieżką do katalogu \BIN Delphi:
AboutBox.ProgramIcon.Picture.LoadFromFile('<path>\TDW.ICO');
ä Uruchom program i kliknij na dowolny przycisk. Pojawi się okno dialogowe About ze zmienioną ikoną w komponencie Image.
Można się zabezpieczyć przed zmianą okna dialogowego About w aplikacjach wywołujących te okno.
Usuwanie procedury obsługi zdarzenia
Kiedy usuwasz komponent Delphi usuwa jego deklarację w definicji typu klasy formularza. Ale nie usuwa związanych z tym komponentem metod. Dzieje się tak, bo te metody mogą być powiązane z innymi komponentami.
n Aby ręcznie usunąć procedurę obsługi zdarzenia usuń kod procedury i jej deklarację.
n Aby pozwolić Delphi na usunięcie procedury usuń wszystkie instrukcje z ciała procedury (także komentarze). Podczas kompilowania lub uruchamiania projektu cała procedura zostanie usunięta.
Opis podstawowych komponentów i ich właściwości
Zostaną tu przedstawione najważniejsze właściwości.
Właściwości wspólne dla wielu komponentów
Caption
Nagłówek. Jest to tekst opisujący dany komponent. Dla formularza jest to tekst pojawiający się na pasku tytułu formularza. Właściwość Caption etykiety określa jej zawartość.
Label1.Caption:='Pierwszy poziom';
Font
Czcionka. Kontroluje atrybuty tekstu pojawiającego się na komponencie. Po dwukrotnym kliknięciu obok tej właściwości pojawi się typowe okno dialogowe, w którym będziemy mogli zmienić czcionkę. W kodzie programu oddzielnie zmieniamy właściwości Color, Name, Size i Style obiektu Font.
Label1.Font.Name:='Times New Roman';
Color
Kolor. Określa tło formularza lub kolor komponentów.
Edit1.Color:=clRed;
Enabled
Dostępny. Właściwość ta określa, czy obiekt ten jest dostępny, np. czy można kliknąć na przycisk. Ustawienie właściwości na True, powoduje, że obiekt jest dostępny, ustawienie na False sprawia, że obiekt jest niedostępny. Jest wówczas wyświetlany na szaro.
Visible
Widoczny. Właściwość ta określa. czy komponent jest widoczny czy nie (True - komponent jest widoczny, False - komponent jest niewidoczny).
Edit1.Visible:=False; // Pole tekstowe będzie niewidoczne
Hint, ShowHint
Wskazówka. Pojawia się, gdy użytkownik najedzie kursorem myszki nad komponent. Do właściwości Hint wpisujemy tekst, który powinien się wtedy pojawić. Aby wskazówka się pojawiała należy jeszcze ustawić właściwość ShowHint na True.
Height, Width, Top, Left
Wysokość, szerokość, od góry, od lewej. Określają rozmiar i położenie komponentu w pikselach. Położenie jest określane jako odległość lewego górnego rogu komponentu odpowiednie od góry i od lewego brzegu komponentu, który je zawiera (najczęściej jest to formularza).
Zazwyczaj modyfikujemy te właściwość za pomocą myszki, ale możemy też to zrobić w kodzie programu.
ListBox1.Height := ListBox1.Height * 2; // powiększa dwukrotnie dotychczasową wysokość pola listy
Button1.Width := Button1.Width * 2; // powiększa dwukrotnie dotychczasową szerokość przycisku
Button1.Top := Button1.Top - 10; // przesuwa przycisk o dziesięć pikseli do góry
Button1.Left := Button1.Left + 10; // przesuwa przycisk o dziesięć pikseli w prawo.
Opis wybranych komponentów
Label
Etykieta. Wyświetla tekst, który użytkownik nie może zmieniać. Tekst wyświetlany w etykiecie określa właściwość Caption . Wyrównanie tekstu wewnątrz etykiety (do lewej, do prawej, wyśrodkowany) określa właściwość Alignment. Etykieta może się dokładnie dopasować do wyświetlanego w niej tekstu, jeśli ustawimy AutoSize na True. Zamiast tego możemy uzyskać efekt zawijania tekstu poprzez ustawienie WordWrap na True.
Jeśli etykieta jest umieszczona na jakimś elemencie graficznym, to przydatne może być określenie jej tła jako przezroczystego poprzez zmianę wartości Transparent na True.
Edit
Pole tekstowe. Wyświetla obszar, w którym użytkownik może zmodyfikować lub wprowadzić pojedynczą linię tekstu. Aby ograniczyć ilość znaków, które użytkownik może wprowadzić, określ właściwość MaxLength. Aby Jeśli chcemy, aby użytkownik nie mógł zmienić wyświetlanego tekstu, ustawiamy właściwość ReadOnly na True. Jeśli pole ma służyć do wprowadzania hasła wpisz do właściwości PasswordChar znak, który ma być wyświetlany zamiast liter hasła (najczęściej *).
Wyświetlanie i wczytywanie danych za pomocą pola tekstowego
Najważniejszą właściwością pola tekstowego jest Text. Zawiera ona tekst, który jest wyświetlany lub wprowadzany przez użytkownika.
n Aby wyświetlić tekst w polu tekstowym zmień wartość właściwości Text.
Edit1.Text:='Nowy tekst';
n Aby odczytać tekst wprowadzony przez użytkownika sprawdź wartość właściwości Text:
if Eidt1.Text='Users'
then Edit2.Text:='Masz uprawnienia użytkownika';
Ponieważ właściwość ta jest typu String, więc jeśli chcemy wyświetlać lub wprowadzać dane innego typu, musimy je przekonwertować. Służą do tego min. funkcje
StrToInt - zamienia tekst na liczbę całkowitą
IntToStr - zamienia liczbę całkowitą na tekst
StrToFloat- zamienia tekst na liczbę rzeczywistą
FloatToStr - zamienia liczbę rzeczywistą na tekst
a:=StrToInt(Edit1.Text); // wczytujemy do zmiennej całkowitej a zawartość pola tekstowego Edit1
Edit2.Text:=FloatToStr(b+' kg'); // wypisuje w polu tekstowym Edit2 wartość zmiennej rzeczywistej b z dodatkiem
`kg' na końcu
TButton
Przycisk. Używany do zainicjowania określonej akcji. Obsługując zdarzenie OnClick decydujemy o tym, jaka jest to akcja.
TCheckBox
Przycisk wyboru. Używamy go, gdy oferujemy użytkownikowi wybór Tak/Nie. Przyciski wyboru można grupować umieszczając je na komponencie Panel, GroupBox lub ScrollBox. Użytkownik może wtedy zaznaczyć dowolną ilość przycisków w grupie.
Tekst opisujący przycisk wyboru jest zawarty we właściwości Caption. Jeśli przycisk jest zaznaczony, to wartością właściwości Checked jest True, w przeciwnym wypadku False. Zmiana wartości przycisku przez użytkownika generuje zdarzenie OnClick.
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
if CheckBox1.Checked then
Label1.Text:='Znasz język angielski'
else
Label1.Text:='Nie znasz języka angielskiego'
end;
TRadioButton
Przycisk opcji. Komponent podobny do komponentu przycisku wyboru. Różnica polega na tym, że jeśli zgromadzimy kilka przycisków opcji na komponencie zbiorczym (formularz, panel, GroupBox) to w danym momencie tylko jeden przycisk może być zaznaczony.
Tak samo jak w przypadku TCheckBox tekst opisujący przycisk opcji jest zawarty we właściwości Caption. Jeśli przycisk jest zaznaczony, to wartością właściwości Checked jest True, w przeciwnym wypadku False. Zmiana wartości przycisku przez użytkownika generuje zdarzenie OnClick.
Dostosowywanie biblioteki komponentów.
Dostosowywanie biblioteki komponentów
Delphi umożliwia samodzielne tworzenie komponentów, a następnie umieszczanie ich na palecie komponentów. Można również poszukać w Internecie potrzebnych nam komponentów.
Do zmian w bibliotece komponentów (a tym samym na palecie) służy okno dialogowe Install Components. Można również przygotować kilka różnych plików bibliotek (.) komponentów i do budowania danej aplikacji wykorzystać jeden z nich.
Uwaga Dostosowywanie Palety komponentów poprzez używanie strony Palette okna dialogowego Tools|Options nie wpływa na zawartość biblioteki .VCL.
Kiedy modyfikujesz bibliotekę pamiętaj o kilku zasadach:
Możesz pracować z projektem tylko wtedy, gdy bieżąca biblioteka zawiera wszystkie komponenty używane w projekcie
Delphi zachowuje ostatnią wersję biblioteki komponentów w pliku o tej samej nazwie i rozszerzeniu .BAK. Dzięki temu zawsze możesz wrócić do poprzedniej wersji biblioteki. Jeśli chcesz mieć więcej wersji bibliotek, każdą z nich zachowaj w pliku o innej nazwie
Unikaj używania tej samej nazwy biblioteki co nazwa projektu.
Dodawanie i usuwanie komponentów z biblioteki
Możesz dodawać (usuwać) komponenty z biblioteki poprzez dodawanie (usuwanie) pliku modułu połączonego z komponentem (komponentami).
n Aby dodać komponenty do biblioteki komponentów:
1 Wybierz Component|Install.
2 Katalog w którym znajduje się moduł, musi być w ścieżce dostępu zapisanej w oknie dialogowym instalatora. Jeśli to potrzebne dodaj ścieżkę do pliku komponentu lub od razu wybierz Add aby otworzyć okno dialogowe Add Module..
3 W oknie dialogowym Add Module wpisz nazwę modułu, który chcesz dodać lub wybierz Browse aby podać ścieżkę dostępu (uwaga, przy wyszukiwaniu modułu zwróć uwagę, że komponenty mogą być w postaci pliku .PAS lub w postaci skompilowanego modułu o rozszerzeniu .DCU).
4 Kliknij OK. aby zamknąć okno dialogowe Add Module.
Nazwa komponentu, który wybrałeś pojawi się na dole listy Installed Units. Na liście są wyświetlane już zainstalowane w bibliotece moduły wraz z nazwami klas. Nowo instalowany moduł jest na dole listy i nie ma nazwy klasy.
5 Wybierz OK., aby zamknąć okno dialogowe Install Components i przebudować bibliotekę. Następnie nowo zainstalowane komponenty są wyświetlane na Palecie komponentów.
Uwaga Nowo zainstalowany komponent pojawi się na stronie przewidzianej przez twórcę komponentów. Można to zmienić.
n Aby usunąć komponent z biblioteki komponentów:
1 Wybierz Component|Install aby otworzyć okno dialogowe Install Components.
2 Na liście Installed Units wybierz moduł, który chcesz usunąć.
3 Wybierz Remove ,aby usunąć moduł z listy.
4 Wybierz OK aby zamknąć okno dialogowe Install Components. Biblioteka zostanie przebudowana. Usunięte komponenty nie będą już widoczne na Palecie komponentów.
Obsługa kompilacji, która nie zakończyła się sukcesem
Zanim biblioteka zostanie przebudowana, Delphi sprawdza, czy wszystkie moduły dodane do biblioteki mogą się poprawnie kompilować. Tylko w przypadku pomyślnej kompilacji nowe komponenty zostaną umieszczone na Palecie komponentów. Jeśli w czasie kompilacji wystąpi błąd jest wyświetlane okno Edytora kodu, tak, aby błąd mógł zostać poprawiony. Czasem źródłem błędów jest brak katalogu na ścieżce path. Delphi pozostawia Unit list nie zmieniony, tak że można ponowić próbę kompilacji w późniejszym terminie. Można również wybrać polecenie Revert, które odtworzy poprzednią wersję biblioteki.
Po naprawieniu błędów trzeba ponownie uruchomić Instalatora, aby przebudować bibliotekę
Zachowywanie kodu źródłowego biblioteki
Po wykonaniu zmian w bibliotece, możesz zachować kod źródłowy biblioteki w pliku projektu biblioteki (.DPR).
n Aby zachować kod źródłowy biblioteki:
1 Wybierz Tools|Options, a następnie kliknij stronę Library.
2 Wybierz Save Library Source Code . Blok uses tego pliku źródłowego biblioteki zawiera listę wszystkich modułów (.DCU), które zostały wykorzystane do zbudowania biblioteki.
Korzystanie z dostosowanych bibliotek
n Aby stworzyć nowy plik biblioteki:
1 Wybierz Component|Install.
2 Wpisz pełną ścieżkę i nawę nowego pliku biblioteki w polu Library Filename.
3 Wybierz OK aby stworzyć i skompilować nowy plik biblioteki. Możesz teraz zainstalować tę dostosowaną bibliotekę kiedy tylko zechcesz lub ustawić ją jako bibliotekę domyślną.
n Aby zastąpić bieżącą bibliotekę inną:
1 Wybierz Component|Open Library.
2 Wybierz plik biblioteki. który chcesz zainstalować i wybierz OK. Delphi zastąpi bieżącą bibliotekę wybraną i umieści komponenty z nowej biblioteki na Palecie komponentów.
Programowanie obiektowe w Delphi
Obiekty w Delphi.
Obiekt formularz
Komponent jako obiekt
Co to jest obiekt?
Obiekt jest typem danych, który łączy dane i procedury w jedną całość.
Obiekty, podobnie jak rekordy, zawierają pola, które przechowują dane i które mają określony typ. W przeciwieństwie do rekordów, obiekty mogą zawierać procedury i funkcje, które operują na polach obiektów. Te procedury i funkcje są nazywane metodami. W przeciwieństwie do rekordów, obiekty mogą też zawierać właściwości (properties). Właściwości obiektów Delphi zawierają domyślne wartości. Można je zmieniać albo w trybie projektu lub w kodzie programu.
Badanie obiektu Delphi
Po utworzeniu nowego projektu, Delphi wyświetla nowy formularz. W oknie Edytora kodu, Delphi deklaruje nowy obiekt formularz i tworzy kod tworzący ten obiekt. (Później zostanie wyjaśnione, dlaczego dla każdego nowego formularza jest deklarowany nowy typ obiektu.)
unit Unit1;
interface
uses WinTypes, WinProcs, Classes, Graphics, Forms, Controls, Apps;
type
TForm1 = class(TForm) { Tu rozpoczyna się deklaracja typu }
private
{ Private declarations }
public
{ Public declarations }
end; { A tu kończy deklaracja typu }
var
Form1: TForm1;
implementation { Początek części implementacyjnej }
{$R *.DFM}
end. { Koniec części inicjacyjnej i koniec modułu}
Nowy typ obiektu to TForm1, dziedziczy on po typie TForm, który również jest obiektem. Na początku typ TForm1 nie zwiera żadnych pól ani metod, ponieważ nie dodaliśmy jeszcze do formularza komponentów.
Jest też zadeklarowana zmienna Form1 nowego typu obiektowego:
var Form1: TForm1;
Form1 jest nazywana instancją (instance) typu TForm1. Zmienna Form1 odpowiada formularzowi, do którego dodajesz komponenty i projektujesz jego wygląd. Można zadeklarować kilka instancji typu obiektowego. Jest to potrzebne na przykład wtedy, gdy tworzysz aplikację wielodokumentową (MDI np. w Wordzie można otworzyć wiele okien, w których edytujemy dokumenty) i potrzebujesz wielu okien potomnych. Każda instancja może zawierać różne dane.
Nawet jeśli nie dodasz żadnego komponentu, możesz uruchomić aplikację. Wyświetli ona pusty formularz, ponieważ typ formularza nie zwiera żadnych pól, ani żadnej metody.
Dodajmy do formularza przycisk i procedurę obsługi OnClick , która zmienia kolor formularza na zielony:
procedure TForm1.Button1Click(Sender: TObject);
begin
Form1.Color := clGreen;
end;
Deklaracja typu obiektu formularza ulegnie zmianie:
unit Unit1;
interface
uses WinTypes, WinProcs, Classes, Graphics, Forms, Controls, Apps;
type
TForm1 = class(TForm)
Button1: TButton; { Nowe pole }
procedure Button1Click(Sender: TObject); { Deklaracja nowej metody }
private
{ Private declarations }
public
{Public declarations }
end;
var Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject); { Kod nowej metody }
begin
Form1.Color := clGreen;
end;
end.
Obiekt TForm1 ma teraz nowe pole: Button1 (przycisk, który został dodany). Typ TButton jest typem obiektowym, więc Button1 także jest obiektem. Typy obiektowe, takie jak TForm1, mogą zawierać inne obiekty (tu: Button1) jako pola. Za każdym razem, gdy dodajesz do formularza nowy komponent, nazwa komponentu pojawia się w deklaracji typu obiektu. Wszystkie procedury obsługi zdarzeń są metodami w obiekcie formularza. Typ TForm1 zawiera nową metodę - Button1Click, zadeklarowaną w deklaracji typu TForm1. Definicja tej metody (kod) znajduje się w części implementation modułu.
Zmiana nazwy komponentu
Zwykle do zmiany nazwy komponentu używany Inspektora obiektów. Jeśli z jego pomocą zmienimy nazwę komponentu, to zmiana nazwy zostanie automatycznie uaktualniona w kodzie programu. Na przykład, jeśli zmienimy nazwę formularza na ColorBox zmieniony kod będzie wyglądał tak:
unit Unit1;
interface
uses WinTypes, WinProcs, Classes, Graphics, Forms, Controls, Apps;
type
TColorBox = class(TForm) { Zmiana nazwy formularza z TForm1 na TColorBox }
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
ColorBox: TColorBox; { Zmiana z Form1 na ColorBox }
implementation
{$R *.DFM}
procedure TColorBox.Button1Click(Sender: TObject);
begin
Form1.Color := clGreen; { Odwołanie do Form1 nie uległo zmianie! }
end;
end.
Zauważ, że uaktualnieniu uległa zmiana nazwy typu formularza (na TColorBox ), a także nazwa zmiennej formularza (na ColorBox). Delphi jednak uaktualnia tylko te fragmenty programu, które sam wygenerował. Ponieważ instrukcje pomiędzy begin i end zostały przez nas napisane (a nie przez Delphi), więc odwołanie formularza Form1 pozostało niezmienione. Sami musimy zmienić tę nazwę:
procedure TColorBox.Button1Click(Sender: TObject);
begin
ColorBox.Color := clGreen;
end;
Nazwy komponentów najlepiej jest zmieniać za pomocą Inspektora obiektów.
äPrzećwicz to jeszcze raz
1 Ustaw tak Form1 i Unit1 na ekranie, aby oba okna były widoczne.
2 Znajdź w oknie edytora kodu opis klasy Form1.
3 Dodaj przycisk do formularza i zauważ, co dzieje się z deklaracją klasy Form1. Jeśli usuniesz przycisk z formularza, deklaracja tego komponentu zniknie z deklaracji Form1.
4 Dodaj przycisk jeszcze raz. Zmień jego dowolną właściwość i sprawdź, czy ta zmiana jest widoczna w deklaracji klasy Form1.
Uwaga W przypadku zmiany właściwości komponentów, nie jest generowany żaden kod, ponieważ ustawienia tych właściwości są przechowywane w pliku DFM file.(Widać jedynie zmiany właściwości Name).
Dziedziczenie danych i kodu w obiekcie.
dziedziczenie danych i kodu w obiekcie
Typ formularza opisany poprzednio jest bardzo prosty. Zawiera tylko jedno pole (przycisk) i jedną metodę (Button1Click), i żadnych właściwości. Możesz jednak zmieniać rozmiar formularza, dodawać, usuwać, zmieniać rozmiary przycisków itd. Jak jest możliwe dokonanie tego wszystkiego z formularzem, który zawiera tylko jedno pole i jedną metodę?
Odpowiedź leży w zjawisku dziedziczenia. Wyobraźmy sobie, że mamy „obiekt rower”. Możemy nim jeździć, bo ma pedały, koła, kierownicę i siodełko. Podobnie, kiedy dodajesz nowy formularz do projektu, ma on wszystkie właściwości dowolnego formularza. Na przykład, ma miejsce na umieszczenie w nim komponentów, ma metody do jego otwierania, zamykania i chowania itd. Przypuśćmy, że pragniesz udoskonalić swój rower: dokupujesz światła, błotniki, bagażnik, fotelik dla dziecka itp. Podobnie możesz przystawać do swoich potrzeb formularz: dodać kilka komponentów, dopisać parę metod.
Udoskonalając swój rower nie zaczynasz od zera, a od podstawowego modelu roweru. Podobnie z formularzem Delphi - nie zaczynasz od zera, tylko od podstawowego modelu formularza Delphi.
Dostosowując dowolny obiekt (formularz, nową wersję komponentu czy okna dialogowego), rozpoczynasz od stworzenia obiektu, który będzie dziedziczył po istniejącym obiekcie. Delphi automatycznie tworząc nowy typ formularza (obiekt) , określa go jako obiekt potomny po TForm . Na początku ten nowy formularz jest identyczny z typem. Po dodaniu do niego komponentu, zmianie właściwości, czy utworzeniu procedur obsługi zdarzeń, nie są już to typy identyczne. Ale, podobnie jak w przypadku udoskonalonego roweru, formularz potrafi to wszystko, co potrafi typ TForm. Dzieje się tak, ponieważ nowy obiekt formularz dziedziczy wszystkie pola, metody, właściwości i zdarzenia po typie TForm.
Kiedy dodajesz nowy formularz do projektu, Delhi tworzy nowy typ obiektu TForm1, określając go jako potomka typu TForm . Określa to pierwsza linia deklaracji typu TForm1.
TForm1 = class(TForm)
Ponieważ TForm1 dziedziczy po TForm, wszystkie elementy należące do typu TForm , stają się częścią typu TForm1 . Jeśli zajrzysz do podręcznej pomocy (kliknij na formularz i wciśnij F1) zobaczysz listę wszystkich właściwości, metod i zdarzeń w typie TForm . Możesz je wykorzystywać w typie TForm1 . Tylko te elementy, które dodasz sam do formularza („ulepszenia”) są widoczne w deklaracji typu TForm1 .
Bardziej ogólny typ obiektu (bazowy) jest nazywany obiektem rodzicem, obiekt dziedziczący jest nazywany potomkiem. Obiekty mogą mieć tylko jednego bezpośredniego rodzica i dowolną ilość potomków. Na przykład typ TForm jest rodzicem typu TForm1, a typ TForm1 jest potomkiem typu TForm . Wszystkie formularze są potomkami typu TForm i może ich być wiele.
Obiekty, komponenty i kontrolki
Kiedy zajrzysz do pomocy, zauważysz, że TForm jest nazywany komponentem. Wszystkie komponenty są także obiektami. Na diagramie jest przedstawiona podstawowa hierarchia komponentów z Delphi Visual Component Library.
Wszystko elementy tej hierarchii to obiekty. Komponenty, które dziedziczą dane i kod z typu TObject , są obiektami z dodatkowymi właściwościami, metodami i zdarzeniami, które pozwalają na zapisywanie ich stanu w pliku. Kontrolki (Controls), które dziedziczą po typie TComponent (a tym samym dziedziczą pola i metody również z typu TObject , posiadają dodatkowe własności, takie jak możliwość wyświetlania pewnych elementów.
Nawet jeśli np. TCheckBox nie dziedziczą bezpośrednio po typie TObject, to zachowują wszystkie jego atrybuty, ponieważ dziedziczą po tym typie pośrednio. Mają więc elementy pochodzący z klas: TObject, TComponent, i TControl, a także swoje własne indywidualne cechy.
Zasięg obiektu.
Zasięg obiektu
Zasięg obiektu determinuje możliwość dostępu do pól, właściwości i metod tego obiektu. Wracając do analogii z rowerem, jeżeli dodamy światła do naszego, dostosowanego roweru, tylko ten rower ma światła, ale gdy dodamy światła do modelu podstawowego, światła będą miały wszystkie rowery.
Wszystkie elementy umieszczone w obiekcie, będą dostępne dla tego obiektu oraz dla jego potomków. Kod metod tworzymy poza obiektem ( w części implementacyjnej), o ich przynależności do obiektu decyduje ich deklaracja w typie obiektu. Mogą więc one odwoływać się do właściwości tego obiektu, metod i pól i nie musimy poprzedzać tych odwołań nazwą obiektu. Na przykład, jeżeli umieściłeś na nowym formularzu przycisk i pole tekstowe, możesz napisać taką procedurę obsługi zdarzenia OnClick:
procedure TForm1.Button1Click(Sender: TObject);
begin
Color := clFuchsia;
Edit1.Color := clLime;
end;
Pierwsza instrukcje zmienia kolor formularza. Mógłbyś napisać ją tak:
Form1.Color := clFuchsia
Nie jest jednak konieczne podawanie nazwy obiektu formularza Form1, ponieważ ta procedura należy do tego obiektu, podobnie jak właściwość Color .
Druga instrukcja odwołuje się do właściwości Color obiektu TEdit . W tym wypadku należy podać kwalifikator TEdit1 , ponieważ jeśli go nie będzie zostanie zmieniony kolor formularza, a nie pola tekstowego.
Nie trzeba jednak przed Edit1 podawać nazwy obiektu, do którego to pole należy (Form1), ponieważ procedura też należy do tego obiektu.
Odwołanie do komponentu z innego formularza
Jeśli Edit1 znajdowałby się na innym formularzu, musielibyśmy poprzedzić nazwę pola tekstowego, nazwą jego obiektu formularza. Jeśli np. Edit1 znajdowałby się na formularzu Form2, zmianę jego koloru zapiszemy tak:
Form2.Edit1.Color := clLime;
W ten sam sposób możemy wywołać metodę komponentu, znajdującego się na innym formularzu, np.:
Form2.Edit1.Clear;
Aby móc się odwoływać do właściwości, metod i zdarzeń znajdujących się na innym formularzu, musisz zadeklarować użycie modułu, w którym znajduje się ten formularz (np. Unit2 )
Zasięg i dziedziczenie obiektów
Zasięg obiektu rozciąga się na wszystkie obiekty potomne. Na przykład w obiekcie TForm1, który dziedziczy po TForm, możemy odwoływać się do pól, właściwości metod i zdarzeń obiektu TForm . Jeśli jest wyświetlany komunikat o powtórzeniu identyfikatora, możliwe jest, że nadana została nazwa pola, która już występuje w obiektach, będących przodkami deklarowanego właśnie obiektu.
Można jednak użyć nazwy metody, która już istnieje w obiektach bazowych. Postępuje się tak w przypadku, gdy metoda ma wykonywać to samo, co metoda w klasie przodku, ale wykonuje to w inny sposób. Zwykle nie ma potrzeby redefinicji metod, chyba że jest tworzony nowy komponent.
Deklarowanie pól i metod w obiekcie
Jeśli potrzebna jest zmienna, w której będą przechowywane dane wykorzystywane przez metody, to najlepszym miejscem dla niej będzie część prywatna klasy formularza. Obiekt bowiem powinien łączyć w całość metody i potrzebne im dane.
Metody odwołujące się do tego pola nie muszą stosować żadnych kwalifikatorów np.
NazwaPliku:='dane.txt';
Odwołując się z innego formularza, musimy podać nazwę formularza, w którym jest zadeklarowane to pole np.:
Form1.NazwaPliku:='nowa.txt';
Oczywiście zmienne pomocnicze, potrzebne w metodzie jak np. zmienna sterująca w pętli, powinny być deklarowane jako zmienne lokalne.
Procedury i funkcje nie będące procedurami obsługi zdarzeń, które powinny mieć dostęp do pól i metod formularza najlepiej jest zadeklarować jako metody w klasie formularza. Można je wykorzystać np. do uproszczenia procedur obsługi zdarzeń.
Nagłówki metod umieszczamy w definicji klasy formularza np.
type TForm1 = class
.....
procedure WyswietlPola;
end;
Definiujemy metodę w części implementation modułu, przed nazwą metody umieszczamy nazwę klasy formularza i oddzielamy ją kropką.
implementation
..........
procedure TForm1.WyswietlPola;
begin
Edit1.Visible:=True;
end;
Najpierw deklarujemy pola, potem metody.
Publiczne i prywatne deklaracje.
Publiczne i prywatne deklaracje
Kiedy jest tworzona nowa aplikacja, dodajemy pola i metody do potomka klasy TForm. Można także dodawać pola i metody nie tylko dodając komponenty w trybie projektu, ale też bezpośrednio modyfikując typ obiektu formularza.
Nowe pola i metody można dodawać albo w części publicznej obiektu (public ), albo w części prywatnej (private). Każdy nowy formularz ma już zapisane te dyrektywy:
type
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
Używaj części publicznej (public) do
Deklarowania pól, do których metody z innych modułów powinny mieć dostęp
Deklarowania metod, które powinny być wywoływane w innych modułach
Deklaracje w części prywatnej (private) powodują, że obiekty te są niedostępne w innych modułach. Użyj części prywatnej do
Deklarowania pol. do których dostęp powinny mieć tylko metody zadeklarowane w tym samym module
Deklarowania metod, które mogą być wywołane tylko w bieżącym module
Na przykład:
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
Number: Integer;
function Calculate(X, Y: Integer): Integer;
public
{ Public declarations }
procedure ChangeColor;
end;
Implementacje procedur Calculate i ChangeColor umieść w części implementacyjnej modułu. Pole Number i metoda Calculate są zadeklarowane w części prywatnej. Tylko obiekty znajdujące się w tym module, mogą używać Number i Calculate. Zwykle to ograniczenie oznacza, że tylko obiekty należące do tego formularza mają do nich dostęp, ponieważ każdy moduł Delphi zawiera tylko jeden typ obiektu formularza.
Metoda ChangeColor jest zadeklarowana jako publiczne, i może być wywoływana w innych modułach.
Uwaga Umieszczaj deklaracje pól przed deklaracjami metod, zarówno w części prywatnej, jak i w publicznej.
Przypisywanie wartości polom w obiekcie
Odwołanie do pól i metod
Zmiana właściwości obiektu (komponentu) w kodzie programu
Odwołanie do komponentu z innego formularza
Jeśli chcemy zmieniać wartość właściwości, czy pola lub wywołać metodę z innego obiektu, który jest polem w bieżącym obiekcie, podajemy nazwę tego obiektu, kropkę i nazwę odpowiedniej właściwości czy metody:
Edit1.Text := 'Nowy tekst';
Edit1.ClearSelection;
Jeśli chcesz zmienić kilkanaście właściwości lub wywołać kilka metod, przydatna może być instrukcja with . Powoduje ona uproszczenie kodu. Zamiast pisać:
procedure TForm1.Button1Click(Sender: TObject);
begin
ListBox1.Clear;
ListBox1.MultiSelect := True;
ListBox1.Items.Add(`Jeden');
ListBox1.Items.Add(`Dwa');
ListBox1.Items.Add(`Trzy');
ListBox1.Sorted := True;
ListBox1.Font.Style := [fsBold];
ListBox1.Font.Color := clPurple;
ListBox1.Font.Name := 'Times New Roman';
ListBox1.ScaleBy(125, 100);
end;
Używając instrukcji with, zapiszemy powyższą procedurę tak:
procedure TForm1.Button1Click(Sender: TObject);
begin
with ListBox1 do
begin
Clear;
MultiSelect := True;
Items.Add(`Jeden);
Items.Add(`Dwa');
Items.Add(`Trzy');
Sorted := True;
Font.Style := [fsBold];
Font.Color := clPurple;
Font.Name := 'Times New Roman';
ScaleBy(125, 100);
end;
end;
Przypisywanie wartości do zmiennych obiektowych
Przypisywanie wartości do zmiennych obiektowych
Można przypisać wartość jednej zmiennej obiektowej innej, jeżeli są one tego samego typu lub są zgodne w sensie przypisania. Na przykład, jeżeli obiekty TForm1 i TForm2 dziedziczą po typie TForm, i zostały zadeklarowane zmienne Form1 i Form2 , możesz przypisać:
Form2 := Form1;
Możesz także przypisać jedną zmienną obiektową potomka do zmiennej obiektowej przodka. Na przykład, mamy następujące deklaracje:
type
TDataForm = class(TForm)
Button1: TButton;
Edit1: TEdit;
DataGrid1: TDataGrid;
Database1: TDatabase;
TableSet1: TTableSet;
VisibleSession1: TVisibleSession;
private
{ Private declarations }
public
{ Public declarations }
end;
var
AForm: TForm;
DataForm: TDataForm;
Legalne jest następujące przypisanie:
AForm := DataForm;
Dlaczego jest to ważne? Pomyślmy co się dzieje, gdy aplikacja wywołuje procedurę obsługi zdarzenia. Załóżmy, że utworzyliśmy procedurę obsługi zdarzenia OnClick przycisku. Każda procedura obsługi zdarzenia ma parametr Sender typu TObject.
procedure TForm1.Button1Click(Sender: TObject);
begin
end;
Operatory is i as.
Operatory is i as.
Typ jest na TObject na górze hierarchii Delphi Visual Component Library. Jest więc przodkiem wszystkich obiektów Delphi. Tym samym każdy obiekt może być przypisany parametrowi TObject, a więc parametr ten może przechowywać dowolny obiekt lub komponent, dla którego zaszło to zdarzenie. Na ile użyteczna jest ta informacja? Można sprawdzić wartość parametru Sender , aby odnaleźć typ komponentu, który wywołał to zdarzenie, poprzez użycie słowa is. Na przykład:
if Sender is TEdit then
DoSomething
else
DoSomethingElse;
Przykład: metoda Memo1DragOver sprawdzająca typ zmiennej obiektowej.
procedure TForm1.Memo1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
Accept := Source is TLabel;
end;
Parametr Source (także typu TObject) jest przyporządkowany obiektowi, który jest przeciągany. Zadaniem tej metody jest upewnienie się, że jest przeciągana etykieta. Jeśli wartością jest True komponent może być przeciągany, jeśli False użytkownik nie może przeciągać obiektu. Wyrażenie logiczne
Source is TLabel
sprawdza czy Source jest typu TLabel . To wyrażenie jest prawdziwe tylko, gdy użytkownik usiłuje przeciągnąć etykietę.
Następna procedura obsługi zdarzeń - Memo1DragDrop także ma parametr Source . Jej zadaniem jest zmienić czcionkę (Font) pola memo na taką, jaką ma przeciągnięta nad te pole etykieta:
procedure TForm1.Memo1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
Memo1.Font := (Source as TLabel).Font;
end;
Podczas pisania tej instrukcji przypisanie, programista nie wie, którą etykietę użytkownik będzie przeciągać. Poprzez odwołanie do jej nazwy (Source as TLabel), czcionka przeciąganej etykiety jest przypisywana czcionce pola memo (Memo1.Font ), ponieważ Source zawiera nazwę przeciąganego i upuszczanego obiektu. Tylko jeśli Source jest etykietą, to przypisanie zostanie wykonane.
Podsumowując: jeśli ta sama procedura obsługi zdarzenia jest przypisana dla kilku komponentów to przydatne mogą się okazać operatory is i as.
Jeśli chcemy sprawdzić, czy komponent, który wywołał procedurę jest określonego typu, np. czy jest etykietą, to wykorzystujemy operator is (np. Source is Tlabel). Powstaje w ten sposób wyrażenie warunkowe.
Jeśli wiemy jakiego typu jest komponent, który wywołał procedurę (np. jest to etykieta) i chcemy wywołać metodę tego komponentu lub przypisać czy sprawdzić wartość właściwości, to stosujemy operator as
np.(Source as TLabel ).Caption:='kliknąłeś tę etykietę';
Tworzenie obiektów niewizualnych.
Tworzenie obiektów niewizualnych
Tworzenie instancji obiektu i usuwanie obiektu
Niektóre komponenty w Delphi są widoczne tylko po uruchomieniu aplikacji. Jeszcze inne nie są widoczne nawet wtedy, jak np. komponenty czasu i daty, ale są gotowe do wykorzystania w naszej aplikacji. Takie niewizualne komponenty możemy też tworzyć sami. Na przykład utwórzmy obiekt TEmployee, który zawiera pola Name, Title i HourlyPayRate oraz metodę: CalculatePay wykorzystującą dane z pola HourlyPayRate do obliczenia wypłaty za podany okres.
type
TEmployee = class(TObject)
Name: string[25];
Title: string[25];
HourlyRate: Double;
function CalculatePayAmount: Double;
end;
TEmployee dziedziczy po TObject, tym samym zawiera wszystkie metody TObject (TObject nie ma pól). Umieść ten zadeklarowany obiekt razem z definicją typu obiektu formularza w części interface modułu. Trzeba też zadeklarować zmienną obiektową:
var
Employee: TEmployee;
Tworzenie instancji obiektu
TEmployee jest tylko typem obiektowym. Obiekt nie istnieje w pamięci, dopóki nie będzie utworzony poprzez wywołanie konstruktora. Konstruktor jest metodą, która przydziela pamięć dla nowego obiektu i wskazuje na ten nowy obiekt, który jest nazywany instancją. Poprzez wywołanie metody Create ta instancja jest przypisywana zmiennej obiektowej.
Jeśli chcesz utworzyć instancję typu TEmployee, musisz wywołać metodę Create, zanim jeszcze odwołasz się do jakiegokolwiek pola obiektu:
Employee := TEmployee.Create;
W deklaracji typu TEmployee nie ma metody Create , ale jest ona zawarta w TObject , została więc odziedziczona. Teraz możesz uzyskać dostęp do pól zmiennej obiektowej Employee.
Usuwanie (destroying) obiektu
Po skończeniu pracy ze zmienną obiektową, powinno się ją zniszczyć (usunąć), czyli zwolnić zajmowaną przez nią pamięć. Dokonujemy tego poprzez wywołanie destruktora , który jest metodą zwalniającą pamięć zajmowaną przez obiekt. Delphi posiada dwa destruktory Destroy i Free. Powinieneś raczej używać metody Free. w tej implementacji metoda Free wywołuje metodę Destroy, ale tylko wtedy, gdy wskaźnik instancji jest różny od nil , czyli wtedy, gdy wskaźnik nadal wskazuje na instancję. Z tych powodów bezpieczniej jest używać metody Free niż Destroy. Ponadto, wywołanie metody Free jest odrobinę bardziej wydajne.
Aby usunąć obiekt Employee ( po skończonej z nim pracy), powinniśmy wywołać Free:
Employee.Free;
Podobnie jak w przypadku metody Create, metoda , Free została odziedziczona po typie TObject.
Do dobrej praktyki programistycznej należy umieszczanie wywołania destruktora w finally bloku try..finally, a kodu wykorzystującego obiekt w części try. Zapewnia to zwolnienie pamięci także wtedy, gdy podczas użytkowania obiektu wystąpi wyjątek (przerywający program).
Tworzenie odpornych aplikacji.
Pojęcie wyjątku
Prosta obsługa wyjątku (blok try...expect...)
Ochrona zasobów (blok try...finally...)
Obsługa wyjątków
Ciche wyjątki
Delphi oferuje mechanizm do tworzenia odpornych aplikacji, tzn. takich, które obsługują pojawiające się błędy, pozwalając np. na poprawne zakończenie bez straty danych i zasobów. Występujące błędy są wykrywane przez wyjątki. Wyjątek to obiekt, który zawiera informację o rodzaju błędu i miejscu jego wystąpienia.
Ochrona bloków kodu
Aby aplikacja była odporna, musi wykrywać wyjątki i odpowiadać na nie. Jeśli nie określisz tej odpowiedzi, zostanie wyświetlone okno komunikatu, zawierające opis błędu. Teraz należy znaleźć w programie miejsce wystąpienia błędu. Pomoże w tym ustawienie opcji, powodującej przerwanie programu w momencie wystąpienia wyjątku (Tools|Options i włącz na karcie Preferences opcję Break on exception)
Następnie możemy obsłużyć wyjątek. Powoduje to usunięcie stanu błędu i zniszczenie obiektu wyjątki, dzięki czemu jest możliwa kontynuacji pracy aplikacji. Przykładami wyjątków, które możesz obsłużyć są: otwieranie do odczytu nie istniejących plików, zapis na przepełnionym dysku. Niektóre z nich, jak as “File not found”, są łatwe do obsłużenia, inne jak przekroczenie dostępniej pamięci mogą być o wiele trudniejsze.
Jeśli mamy serię instrukcji, które wymagają takiej samej odpowiedzi na błąd, można zgrupować je w blok i zdefiniować odpowiedź na błąd, która będzie zastosowana do całego bloku. Blok z odpowiedzią na wyjątek nazywamy blokiem chronionym (protected blocks ). Zaczynamy go słowem try i kończymy słowem end.
Wyjątki nie uczestniczą w normalnym kierunku wykonywania programu. Jeśli wystąpi błąd w bloku chronionym, wykonywanie programu „skacze” do zdefiniowanej odpowiedzi na wyjątek w tym bloku, a następnie opuszcza blok.
Poniższy przykład zawiera blok chroniony. Jeśli w czasie wykonywania instrukcji bloku pojawi się błąd, wykonywana jest część obsługująca wyjątek (beep) i wykonywanie programu wychodzi poza blok.
......
try { początek bloku chronionego }
Font.Name := 'Courier'; { jeśli zdarzy się wyjątek... }
Font.Size := 24; { ...w czasie wykonywania tych instrukcji... }
Color := clBlue;
except { ...wykonanie programu jest przenoszone tutaj }
on Exception do MessageBeep(0); { obsługa wyjątku - dźwięk beep }
end;
... { wykonywanie programu wychodzi tu, poza blok chroniony}
Zagnieżdżona odpowiedź na wyjątek
Ponieważ Pascal pozwala na tworzenie zagnieżdżonych bloków, więc możemy tworzyć również zagnieżdżone bloki chronione. Najprostszy przypadek polega na zagnieżdżeniu bloku ochrony zasobu (zwalniającego pamięć przydzielonej zasobom) wewnątrz innego takiego bloku:
{ przydzielenie pierwszego zasobu }
try
{ przydzielenie drugiego zasobu }
try
{ kod w którym używamy obu zasobów }
finally
{ zwolnienie drugiego zasobu }
end;
finally
{ zwolnienie pierwszego zasobu }
end;
Możemy także zagnieżdżać obsługi wyjątków:
try
{ kod chroniony }
try
{ specjalnie chroniony kod }
except
{ lokalna obsługa wyjątku }
end;
except
{ globalna obsługa wyjątku }
end;
Można także mieszać oba rodzaje: tworzyć blok ochrony zasobów z zagnieżdżonym blokiem obsługi wyjątku i odwrotnie.
Ochrona przydzielonych zasobów
Jedną z podstawowych zasad dotyczących tworzenia zdrowej aplikacji jest zasada: jeśli został przydzielony zasób, to należy go zwolnić. Na przykład, jeśli jest przydzielana pamięć, to powinna być ona zwolniona, jeśli został otwarty plik, to należy go zamknąć.
Nie tylko nasz kod może być źródłem wyjątków. Wyjątek może podnosić wywołana procedura RTL lub inny komponent. Jeśli zaszło jedno z tych zdarzeń, musisz mieć pewność, że przydzielone zasoby zostały zwolnione.
Jakie rodzaje zasobów wymagają ochrony?
Niektóre zasoby, które wymagają ochrony:
Pliki
Pamięć
Zasoby Windows
Obiekty
Następująca procedura obsługi zdarzeń przydziela pamięć, a następnie powoduje błąd, tak, że przydzielona pamięć nie zostaje zwolniona:
procedure TForm1.Button1Click(Sender: TComponent);
var
APointer: Pointer;
AnInteger, ADividend: Integer;
begin
ADividend := 0;
GetMem(APointer, 1024); { przydziela 1Kb pamięci }
AnInteger := 10 div ADividend; { ta linia powoduje błąd }
FreeMem(APointer, 1024); { wykonanie programu nigdy tu nie dojdzie }
end;
Jeśli wystąpi błąd, przydzielona pamięć nie zostanie zwolniona. Aby mięć pewność, że pamięć przydzielona przez GetMem zostanie zwolniona przez FreeMem musimy te procedury umieścić w bloku ochrony zasobu.
Tworzenie bloku ochrony zasobu
Kod używający zasobu umieszczamy w bloku ochrony zasobu, a kod zwalniający zasób w specjalnej części tego bloku. Tak wygląda typowa struktura bloku ochrony zasobu:
{ przydzielenie zasobu }
try
{ instrukcje używające zasobu }
finally
{ zwalnianie zasobu }
end;
Aplikacja zawsze wykonuje instrukcje z części finally , nawet jeśli dowolna instrukcja z części chronionej lub procedura czy funkcja z tej części, podniesie wyjątek. Jeśli program będzie wykonywany poprawnie, instrukcje z części finally będą wykonywane po wykonaniu wszystkich instrukcji z bloku chronionego.
Następująca procedura przydziela pamięć, powoduje błąd, ale mimo to pamięć zostanie zwolniona.
procedure TForm1.Button1Click(Sender: TComponent);
var
APointer: Pointer;
AnInteger, ADividend: Integer;
begin
ADividend := 0;
GetMem(APointer, 1024); { przydziela 1Kb pamięci }
try
AnInteger := 10 div ADividend; { ta linia powoduje błąd }
finally
FreeMem(APointer, 1024); { ta linia zostanie wykonana }
end;
end;
Uwaga Blok ochrony zasobu nie obsługuje wyjątku. Kod z części finally nie zawiera informacji o tym, który wyjątek został podniesiony. Jeśli zostanie podniesiony wyjątek, wykonywana jest najpierw część finally, a następnie blok jest opuszczany - wyjątek jest nadal podniesiony. Obsłużyć wyjątek może blok zawierający blok chroniony.
Zarządzanie wyjątkami RTL
Jeśli wywołujesz procedury lub funkcje z bibliotek run-time (RTL), takie jak funkcje matematyczne, czy procedury do obsługi plików, zwracają one informację o błędzie do aplikacji w postaci wyjątków. Domyślnie wyjątki RTL domyślnie generują komunikat, który jest wyświetlany przez aplikację. Możesz jednak sam zdefiniować obsługę wyjątku. Istnieją także ciche wyjątki, które domyślnie nie powodują wyświetlenia komunikatu o błędzie.
Wyjątki te są zdefiniowane w module SysUtils i dziedziczą one po ogólnym typie wyjątku (Exception).
Wyjątki wejścia / wyjścia
Zdarzają się one, gdy funkcje i procedury RTL próbują uzyskać dostęp do plików lub standardowych urządzeń wejścia - wyjścia. Większość z tych wyjątków odpowiada kodom błędów zwracanych przez Windows (lub DOS). Moduł SysUtils definiuje ogólny wyjątek wejścia / wyjścia nazywany EinOutError, który zawiera pole ErrorCode określające rodzaj błędu. Wartość tego pola można wykorzystać do określenia rodzaju reakcji na wyjątek.
Wyjątki stosu
Mogą się zdarzyć przy próbie przydzielenia pamięci lub operacji na wskaźnikach. Moduł SysUtils definiuje dwa wyjątki zwane EOutOfMemory i EInvalidPointer.
Wyjątek |
Znaczenie |
EOutOfMemory |
Jest zbyt mało pamięci na stosie, aby móc wykonać tę operację |
EInvalidPointer |
Aplikacja próbuje wykorzystać wskaźnik wskazujący poza stos. Zwykle oznacza to, że wskaźnik został zwolniony (dispose) |
Wyjątki operacji matematycznych na liczbach całkowitych
Mogą się zdarzyć podczas obliczeń na liczbach całkowitych. Moduł SysUtils definiuje ogólny wyjątek operacji matematycznych na liczbach całkowitych zwany EIntError. RTL nigdy nie podnoszą tego wyjątku, ale jest on przodkiem dla innych wyjątków matematycznych. Tabelka pokazuje te wyjątki.
Wyjątek |
Znaczenie |
EDivByZero |
Próba dzielenia przez zero. |
ERangeError |
Liczba lub wrażenie przekracza dopuszczalny zakres. |
EIntOverflow |
Przepełnienie operacji na liczbach całkowitych. |
Wyjątki operacji zmienno - przecinkowych
Mogą się one zdarzyć podczas operacji na wyrażeniach rzeczywistych. Moduł SysUtils definiuje ogólny wyjątek operacji zmienno-przecinkowych, zwany EMathError. RTL nigdy nie podnoszą tego wyjątku, jest on przodkiem dla innych wyjątków. Tabelka pokazuje te wyjątki.
Wyjątek |
Znaczenie |
EInvalidOp |
Procesor napotkał niezdefiniowaną operację. |
EZeroDivide |
Próba dzielenia przez zero. |
EOverflow |
Przepełnienie operacji zmienno-przecinkowe (przekroczenie zakresu w górę) |
EUnderflow |
Niedopełnienie operacji zmienno-przecinkowej (przekroczenie zakresu w dół). |
Wyjątek błędnej zmiany typów
Pojawia się podczas próby zmiany typu jednego typu obiektowego w inny, przy wykorzystaniu operatora as. Moduł SysUtils definiuje wyjątek zwany EInvalidCast , który jest wtedy podnoszony.
Wyjątki konwersji
Mogą się zdarzyć podczas konwersji danych z jednego typu na inny, przy użyciu takich funkcji jak: IntToStr, StrToInt, StrToFloat itp.. Moduł SysUtils definiuje wyjątek zwany EConvertError , które podnoszą funkcje RTL, jeśli nie mogą przekonwertować przekazanych im danych.
Wyjątki sprzętowe
Mogą się zdarzyć w dwóch sytuacjach: kiedy procesor wykryje procesor wykryje błąd krytyczny który nie można obsłużyć lub, gdy aplikacja świadomie go generuje, aby przerwać jej wykonywanie. Zwykle rzadko będziesz obsługiwał błędy krytyczne, z wyjątkiem błędu generalnej ochrony (EGPFault) ponieważ reprezentują one poważne błędy w środowisku operacyjnym.
Tworzenie obsługi wyjątku
Obsługa wyjątku jest kodem obsługującym określony wyjątek (lub wyjątki), który wydarzył się wewnątrz chronionego bloku.
n Aby zdefiniować obsługę wyjątku, ujmij kod , który będzie chroniony w bloku obsługi wyjątku, a obsługę wyjątku umieść w części except bloku.
try
{ instrukcje, które będziesz ochraniać }
except
{ instrukcje obsługi wyjątku }
end;
Instrukcje w części except są wykonywane tylko wtedy, gdy podczas wykonywania części try wystąpi wyjątek. Jeśli kod w części try wywołuje procedurę lub funkcję, która nie ma obsługi wyjątku, wykonywanie wraca do bloku obsługi wyjątku, który obsługuje wyjątek.
Kiedy instrukcja w części try podnosi wyjątek, wykonywanie jest przenoszone do części except, gdzie są wykonywane kolejne instrukcje obsługi błędów lub są wykonywane obsługi błędów. Jeśli zostanie wykonana właściwa obsługa błędów, obiekt wyjątku jest automatycznie niszczony.
Instrukcje obsługi błędów
Każda instrukcja w części except bloku try..except definiuje kod, który powinien być wykonany dla określonego rodzaju wyjątku. Forma tych instrukcji jest następująca:
on <typ wyjątku> do <instrukcja>;
Przykład definiujący obsługę zdarzeń dla błędu dzielenia przez zero:
function GetAverage(Sum, NumberOfItems: Integer): Integer;
begin
try
Result := Sum div NumberOfItems;
except
on EDivByZero do Result := 0;
end;
end;
Gdybyśmy nie wykorzystali wyjątków, funkcja musiałaby wyglądać tak:
function GetAverage(Sum, NumberOfItems: Integer): Integer;
begin
if NumberOfItems <> 0 then
Result := Sum div NumberOfItems
else Result := 0;
end;
Użycie wyjątków pozwala na oddzielenie kodu obsługi błędnych sytuacji od właściwego algorytmu. Dzięki temu program z użyciem wyjątków jest bardziej przejrzysty, szczególnie gdy możliwych błędnych sytuacji jest wiele.
Wykorzystanie instancji wyjątku
W większości wypadków, obsługa wyjątku potrzebuje tylko informacji o typie wyjątku. W niektórych przypadkach jest jednak potrzebna dodatkowa informacja, którą zawiera instancja wyjątku( obiekt wyjątku). W tym celu używamy specjalnej odmiany instrukcji on..do. Ta specjalna forma wymaga tymczasowej zmiennej obiektowej, która będzie przechowywać instancję wyjątku.
W nowym projekcie dodaj do formularza pasek przewijania i przycisk. Utwórz procedurę obsługi zdarzenia OnClick dla przycisku:
ScrollBar1.Max := ScrollBar1.Min - 1;
Ta instrukcja podnosi wyjątek, ponieważ wartość maksymalna paska przewijania musi być zawsze mniejsza od minimalnej. Utwórzmy obsługę tego wyjątku:
try
ScrollBar1.Max := ScrollBar1.Min - 1;
except
on E: EInvalidOperation do
MessageDlg('Ignoring exception: ' + E.Message, mtInformation, [mbOK], 0);
end;
Tymczasowa zmienna (E ) jest typu określonego po dwukropku (EInvalidOperation). Możesz też użyć operatora as , aby wymusić zmianę typu.
Uwaga Nigdy nie niszcz tymczasowej zmiennej. Obsługa wyjątku powoduje automatyczne zniszczenie obiektu wyjątku. Jeśli spróbujesz zniszczyć obiekt samodzielnie (destroy), aplikacja spróbuje ponownie usunąć obiekt, co spowoduje błąd krytyczny aplikacji.
Zasięg obsługi wyjątku
Nie musisz starać się obsłużyć każdy rodzaj wyjątku. Obsługujesz tylko te, które wymagają specjalnej obsługi. Jeśli program nie znajdzie obsługi określonego wyjątku, wykonanie programu opuszcza ten blok i wraca do bloku nadrzędnego (lub kodu, który wywołał ten blok) z wyjątkiem, który jest nadal poniesiony. Ten proces jest kontynuowany aż do momentu, gdy albo zostanie odnaleziona odpowiednia obsługa tego wyjątku, albo osiągnięty zostanie najbardziej zewnętrzny blok aplikacji.
Zabezpieczenie domyślnej obsługi błędów
Jeśli w obsłudze błędów dodamy część else , to w efekcie będzie ona obsługiwać wszystkie wyjątki:
try
{instrukcje }
except
on ESomething do { obsługa określonego wyjątku };
else { kod obsługi domyślnego wyjątku };
end;
Dodając część domyślną powodujemy, że wszystkie wyjątki zostaną tu obsłużone w ten sam sposób.
Uwaga! Prawdopodobnie nigdy nie będziesz używać takiej konstrukcji obsługi wyjątku. Część else obsługuje wszystkie wyjątki, nawet te o których nic nie wiesz. Zwykle obsługujemy te wyjątku, które wiemy jak obsłużyć. W innych przypadkach lepiej ewentualnie tylko wykonać finally, jeśli istnieje potrzeba zwolnienia zasobów.
Obsługa klas wyjątków
Ponieważ obiekty wyjątków są częścią hierarchii obiektów, można określić obsługę wyjątków dla części tej hierarchii, obsługując klasę wyjątku, po której te obiekty dziedziczą.
Następujący blok zarządza wszystkimi wyjątkami matematycznych operacji na liczbach całkowitych.
try
{ instrukcje, które wykorzystują matematyczne operacje na liczbach całkowitych }
except
on EIntError do { specjalna obsługa dla wyjątków matematycznych operacji na liczbach całkowitych };
end;
Jeśli umieszczasz obsługę określonego wyjątku, musisz go umieścić na obsługą ogólnego wyjątku. W przeciwnym wypadku wykonywanie kodu nigdy nie dojdzie do tej szczegółowej obsługi, bo będzie pasował ogólny wyjątek.
Przykład: obsługiwany jest wyjątek przekroczenia zakresu, a następnie ogólny wyjątek matematycznych operacji całkowitych:
try
{ instrukcje wykonujące całkowite operacje matematyczne }
except
on ERangeError do { obsługa wyjątku przekroczenia zakresu };
on EIntError do { obsługa dla innych błędów matematycznych operacji na liczbach całkowitych };
end;
Ponowne podniesienie wyjątku
Czasami pragniemy, aby w przypadku wystąpienia pewnych instrukcji został on obsłużony dodatkowo w specjalny sposób (np. wyświetlić odpowiedni komunikat).Możemy wtedy ująć te instrukcje w osobny blok try...except. Niestety, po wyjściu z tego bloku wyjątek jest niszczony, więc główna obsługa wyjątku (bardziej ogólna, w zewnętrznym bloku) nie może już go obsłużyć. Rozwiązanie jest proste. Po obsłudze błędu w wewnętrznym bloku, powinniśmy ponownie ponieść wyjątek, wykorzystując słowo rasie:
try
{ instrukcje }
try
{ specjalne instrukcje }
except
on ESomething do
begin
{ obsługa tylko dla specjalnych instrukcji }
raise; { podniesienie wyjątku }
end;
end;
except
on ESomething do ...; { ogólna obsługa wyjątku - dla wszystkich przypadków }
end;
Po wystąpieniu wyjątku w wewnętrznym bloku try...except.. jest wykonywana obsługa z tego bloku, a następnie wykonywana jest ta zewnętrzna.
Zarządzanie wyjątków komponentów
Komponenty Delphi również podnoszą wyjątki, które obsługujemy podobnie jak wyjątki RTL.
Powszechnym błędem jest błąd przekroczenia zakresu. Na przykład, pole listy zawiera trzy elementy (0..2), a aplikacja próbuje się odwołać do elementu o indeksie 3. Pole listy podnosi wtedy wyjątek “Index out of range” (indeks poza zakresem). Następująca procedura obsługi zdarzeń zawiera obsługę wyjątku, informującą użytkownika o przekroczeniu zakresu.
procedure TForm1.Button1Click(Sender: TObject);
begin
ListBox1.Items.Add('a string'); { dodaje tekst do pola listy}
ListBox1.Items.Add('another string'); { dodaje jeszcze jeden tekst... }
ListBox1.Items.Add('still another string'); { ...i trzeci tekst }
try
Caption := ListBox1.Items[3]; { ustawia tytuł formularza na czwarty tekst w liście }
except
on EListError do
MessageDlg('List box contains fewer than four strings', mtWarning, [mbOK], 0);
end;
end;
Za pierwszym razem zostanie podniesiony wyjątek (odwołujemy się do czwartego elementu, którego jeszcze nie ma). Następne kliknięcie już nie powoduje błędu (powoduje dodanie dodatkowych trzech linii - razem jest już co najmniej 6).
Ciche wyjątki
Ciche wyjątki nie wyświetlają żadnego komunikatu o błędzie. Sami też możemy tworzyć takie wyjątki. Są użyteczne jeżeli nie chcemy obsłużyć wyjątku, a jedynie wycofać się z operacji, podobnie jak w przypadku użycia procedur Break lub Exit. Jednak w przeciwieństwie do nich potrafi przerwać nawet kilkanaście bloków programu. Ciche wyjątki dziedziczą po typie EAbort.
n Istnieje prosty sposób na stworzenie cichego wyjątku. Zamiast ręcznie konstruować obiekt dziedziczący po EAbort możemy wywołać procedurę Abort. Abort automatycznie podnosi cichy wyjątek, który przerywa wykonywane operacje bez wyświetlania komunikatu.
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
for I := 1 to 10 do {pęta powtarzająca się 10 razy }
begin
ListBox1.Items.Add(IntToStr(I)); { dodaj liczbę do listy }
if I = 7 then Abort; { porzuć po siódmym elemencie }
end;
end;
Posumowanie
Wyjątki tworzą mocny i elastyczny mechanizm dla informowania i reagowania na błędne stany aplikacji. Biblioteka Delphi i standardowe komponenty podnoszą i odpowiadają na wyjątki. Poprzez obsługę wyjątków w aplikacji, możesz mieć pewność. że nie zostaną utracone zasoby systemu, w momencie nieoczekiwanego zamknięcia aplikacji lub możemy pozwolić aplikacji lub użytkownikowi naprawić błędny stan i powtórzyć operacje. W obu przypadkach wyjątki dostarczają informacji niezbędnych dla aplikacji i mechanizmów, dzięki którym możemy odpowiednio zareagować na błędy.
Zarządzanie projektami
Składowe projektu.
Rozumienie składowych projektu, w tym pliku kodu źródłowego projektu, plików z kodem źródłowym modułu,
Co to jest projekt?
Projekt Delphi jest zbiorem wszystkich plików, które razem tworzą aplikację (lub bibliotekę.
Normalnie każdy projekt powinien być zachowany w oddzielnym katalogu. Niestety, standardowo projekt jest zachowywany w katalogu BIN. Jest to bardzo niebezpieczna sytuacja, ponieważ może prowadzić do nadpisania plików o identycznych nazwach. Należy zawsze zachować projekt w osobnym katalogu.
Pliki tworzące projekt (Składowe projektu)
Plik tworzone w trybie projektu
Rozszerzenie pliku |
Definicja |
Opis |
.DPR |
Plik projektu |
Kod pascalowy dla programu głównego projektu. Zawiera listę wszystkich formularzy i plików modułów projektu oraz zawiera kod inicjalizujący aplikację. Tworzony, gdy projekt jest po raz pierwszy zachowywany. |
.PAS |
Kod źródłowy modułu (Object Pascal) |
Dla każdego formularza jest tworzony dla każdego formularza (gdy zostanie zachowany). (W projekcie mogą być również mo-duły nie związane z żadnym formularzem). Zawiera wszystkie deklaracje i procedury, w tym procedury obsługi zdarzeń. |
.DFM |
Plik graficzny formularza |
Binarny plik zawierający właściwości formularza. Dla każdego formularza jest tworzony oddzielny plik .DFM podczas pierwszego zachowywania projektu. |
.OPT |
Plik zawierający opcje projektu |
Plik tekstowy zawierający bieżące ustawienia opcji projektu. Tworzony, gdy są zachowywane po raz pierwszy zmiany dokonane w opcjach projektu. |
.RES |
Plik zasobu kompilatora (Compiler resource file) |
Binarny plik zawierający ikony aplikacji i inne zewnętrz zasoby wykorzystywane przez projekt. |
.~DP |
Kopia zapasowa projektu. |
Tworzony podczas drugiego zachowywania projektu. Zawsze zawiera poprzednią wersję pliku projektu. |
.~PA |
Kopia zapasowa pliku modułu |
Kopia zapasowa poprzedniej wersji pliku modułu. (Poprzednia wersja pliku). |
.~DF |
Kopia zapasowa graficznego pliku formularza. |
Kopia zapasowa binarnego pliku z ustawieniami właściwości. Zawiera poprzednią wersję pliku. |
.DSK |
Ustawienia desktopu |
Plik zawiera informację o ustawieniach desktopu ustalonych dla pliku w oknie dialogowym Environment options. |
Pliki tworzone podczas kompilacji
Rozszerzenie |
Definicja |
Opis |
.EXE |
Skompilowany plik wykonywalny |
Plik wykonywalny aplikacji, zawiera również pliki .DCU. Wystarczy do rozpowszechniania aplikacji. |
.DCU |
Skompilowany moduł |
Dla każdego pliku .PAS jest tworzony taki plik. |
.DLL |
Skompilowana biblioteka dynamiczna |
|
Pliki zasobu (nie tworzone przez Delphi)
W projekcie można wykorzystać pliki tworzone przez inne aplikacji takie jak:
Pliki graficzne. Bitmapy (pliki .BMP, .WMF), które używasz w komponentach typu TImage lub wykorzystujesz w komponentach TBitBtn. Kiedy wybierzesz taki element, jest on wstawiany do pliku formularza (.DFM). Po skompilowaniu może być włączony do piku wykonywalnego .EXE.
Pliki ikon. Ikony (pliki .ICO), które określasz we właściwości Icon formularza lub w oknie dialogowym Project Options również mogą pochodzić z dowolnych źródeł. Są one wstawiane do projektu, w podobny sposób jak pliki graficzne. Pliki .BMP i .ICO mogą być również utworzone w Delphi Image Editor lub pobrane z Delphi Image Library .
Pliki pomocy. Pliki pomocy (.HLP), które określasz w oknie dialogowym Project Options, również mogą pochodzić z dowolnego źródła. Do projektu są wstawiana jest jedynie nazwa i ścieżka dostępu do pliku pomocy, ale nie sam plik.
Zrozumienie plików w projekcie
Plik kodu źródłowego projektu
Plik .DPR jest plikiem zawierającym program główny projektu, wykorzystywany przy kompilowaniu innych modułów. Delphi uaktualnia ten plik podczas tworzenia projektu. Delphi tWOrzy domyślnie następujący kod źródłowy:
program Project1;
uses
Forms,
Unit1 in 'UNIT1.PAS' {Form1};
{$R *.RES}
begin
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Unit1 reprezentuje identyfikator modułu, gdzie `UNIT1.PAS' odpowiada aktualnej DOS-owej nazwie pliku modułu.
Sekcja in informuje kompilator, gdzie można znaleźć plik modułu. {Form1} odpowiada identyfikatorowi formularza związanego z tym modułem (nie ma tej części, jeśli plik modułu nie jest związany z formularzem). Jest taki sam jak właściwość Name formularza. Po zmianie nazwy formularza za pomocą Inspektora obiektów nazwa w pliku .DPR jest uaktualniana.
Dyrektywa kompilatora $R określa, że plik z rozszerzeniem .RES (pliki zasobu) i o takiej samej nazwie jak projekt jest włączany do projektu.
Metoda Application.CreateForm ładuje (tworzy) formularz określony w jej argumencie.
Instrukcja Application.Run uruchamia aplikację.
Za każdym razem, gdy dodajesz nowy formularz do projektu, Delphi dodaje go do sekcji uses pliku źródłowego projektu.
Ważne Ponieważ Delphi sam zarządza plikiem .DPR , zazwyczaj nie ma potrzeby modyfikowania go ręcznie i nie jest to rekomendowane.
Pliki z kodem źródłowym modułów (.PAS)
Moduły są głównymi składnikami aplikacji Delphi. Poznajemy je po rozszerzeniu .PAS. Zawierają kod źródłowy aplikacji zapisany w języku Object Pascal . Z każdym formularzem jest związany moduł zawierający deklaracje obiektów zawartych w formularzu oraz procedury obsługi zdarzeń. Moduły mogą być również niezależne. Moduły możemy tworzyć od początku jako cześć projektu lub dołączyć do projektu gotowy moduł. Po dodaniu modułu do projektu, Delphi umieszcza jego deklarację w sekcji uses pliku projektu .DPR.
Moduły powiązane z formularzami
Jest to najczęstszy typ modułu. Jest tworzony za każdym razem, gdy jest otwierany nowy formularz. Dla nowego domyślnego formularza dodanego do nowego projektu, Delphi tworzy następujący kod dla modułu Unit1.
unit Unit1;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs;
type
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
end.
Deklaracja uses. Nowy moduł zawiera już listę potrzebnych modułów. Po dodaniu nowego komponentu lista jest ewentualnie uzupełniana.
Deklaracja klasy formularza Deklaracja type (lub deklaracja klasy) wprowadza formularz jako klasę (class). Wszystkie elementy tworzące aplikację, takie jak przyciski, etykiety, czcionki itd. są obiektami. Obiekty ukrywają Windows, Delphi oferuje kontakt z obiektami zamiast bezpośrednio z Windows.
Deklaracja var . Deklaracja var określa formularz jako zmienną typu TForm1. Ma więc wszystkie cechy zadeklarowane w typie TForm.
Dyrektywa kompilatora. Dyrektywa kompilatora $R łączy typ TForm z plikiem binarnym .DFM. Powoduje włączenie podczas kompilacji pliku (plików) .DFM do końcowego pliku wykonywalnego.
Ważne Nie usuwaj dyrektywy $R *.DFM z pliku modułu.
Pliki modułu nie związane z formularzem
Jeśli stworzyliśmy procedury lub funkcje, które mogą być wykorzystane w aplikacjach, najlepiej jest umieścić je w oddzielnym module, nie związanym z żadnym formularzem.
Pliki modułów dla komponentów
Jeśli chcemy utworzyć komponent, musimy go umieścić w oddzielnym pliku (module). Taki oddzielny moduł jest tworzony, gdy wybierzemy polecenie File|New Component.
Skompilowany moduł (.DCU)
Kiedy projekt jest kompilowany, Delphi każdy moduł kompiluje i zapisuje w pliku o tej samej nazwie jak moduł i o rozszerzeniu .DCU. Plik ten jest zarządzany przez kompilator i służy do przyśpieszenia procesu kompilacji projektu.
Pliki graficzne formularza(.DFM)
Dla każdego formularza jest tworzony plik zawierający informację o jego wyglądzie. Modyfikujemy ten plik zmieniając wygląd formularza w trybie projektu (zmieniając właściwości formularza i jego komponentów). Informacje zawarte w tym pliku są wykorzystywane podczas uruchomienia projektu.
Plik ten możemy zapisać w trybie tekstowym (w kodzie ASCII).
Dostosowywanie opcji projektu
Dostosowywanie opcji projektu.
Zmiana formularza głównego aplikacji
Delphi oferuje możliwość dostosowania opcji zintegrowanego środowiska (IDE). Mogą one dotyczyć wszystkich projektów lub tylko bieżącego projektu.
Opcje środowiska
Ustawienia opcji środowiska (Environment Options) dotyczą wszystkich projektów Delphi.
n Aby otworzyć opcje środowiska, wybierz Tools|Options.
Strona Preferences
Opcje Autosave
Ustawienia tej opcji określają, co ujrzysz na ekranie po uruchomieniu Delphi.
Jeżeli jest włączona opcja Desktop, Delphi ładuje projekt, który był ostatnio otwarty i wyświetla otwarte wtedy formularze.
Jeżeli jest włączona opcja Editor files, Delphi zachowuje wszystkie zmodyfikowane moduły, otwarte w edytorze kodu, za każdym razem, gdy są wybierane polecenia z menu Run oraz przy wyjściu z Delphi.
Opcje Form desinger
Display grid określa, czy siatka projektowa jest wyświetlana.
Snap to grid określa, czy rozmiary komponentów są określone przez siatkę, tzn. czy są one przyciągane do najbliższego oczka siatki
W pola Grid Size X i Grid Size Y wpisujemy rozmiary siatki projektowej.
Opcje Debugging
Break on exception włączamy, gdy program generuje wyjątki. Włączenie tej opcji pozwala wykryć ich źródło i w rezultacie odpowiednio obsłużyć wyjątek (tzn. dopisać w programie kod obsługi błędu).
Opcje projektu
Ustawienia dokonane w oknie dialogowym Project Options odnoszą się tylko do bieżącego projektu. Jeśli zmieniasz jakieś ustawienia domyślnie, tworzony jest plik z rozszerzeniem .OPT zawierający te zmiany. Plik jest umieszczony w tym samym katalogu, co cały projekt.
n Aby wyświetlić okno dialogowe wybierz Project|Options.
Przycisk wyboru Default
W oknie dialogowym na każdej stronie znajduje się pole wyboru Default. Pozwala on na zmianę domyślnej konfiguracji opcji projektu. Zaznaczenie tego pola wyboru, a następnie zmiana opcji projektu, powoduje zapisanie tych zmian w pliku DEFPROJ.OPT . Nowo otworzony projekt będzie miał opcje domyślnie zgodne z wartościami zapisanymi w tym pliku.
n Aby odtworzyć oryginalne domyślne ustawienia, usuń lub zmień nazwę dla pliku DEFPROJ.OPT.
Opcje ze strony Forms
Opcje te pozwalają określić wybrany formularz jako formularz główny oraz ustalić kolejność ładowania (tworzenia) formularzy po uruchomieniu aplikacji.
Main form - określanie formularza głównego
Jest to lista, z której możemy wybrać formularz główny. Jest to formularz, który jest widoczny jako pierwszy po uruchomieniu aplikacji. Zamknięcie tego formularza przez użytkownika jest równoznaczne z zakończeniem pracy aplikacji. Formularz główny to formularz, który jako pierwszy występuje na liście tworzenia plików w pliku projektu .DPR. Dlatego jest to najczęściej pierwszy utworzony formularz.
Zmiana formularza głównego może się przydać, gdy np. chcemy przetestować formularz bez uruchamiania całej aplikacji.
Strona Application
Title
Tekst wpisany tutaj pojawia się obok ikony programu, gdy program jest zminimalizowany. Jeśli ta właściwość jest nieokreślona, zminimalizowana aplikacja opisana jest nazwą jej pliku .EXE.
Help file
Jeżeli do aplikacji jest stworzony plik z pomocą (Windows Help .HLP), można połączyć aplikację z tym plikiem, wpisując nazwę pliku do pola. Plik wybrać korzystając z przycisku Browse. Po uruchomieniu plik jest ładowany do WINHELP.EXE, który umożliwia załadowanie pliku z pomocą i dostęp do niego.
Uwaga! Zwróć uwagę, że plik z pomocą w gotowej aplikacji może być zainstalowany na innym dysku, niż to przewidujesz. Nie określaj więc na „sztywno” ścieżki dostępu do pliku z pomocą w polu Help file np. unikaj podawania napędu.
Icon
Delphi przewiduje domyślną ikonę, która jest wyświetlana, gdy aplikacja jest zminimalizowana lub obok nazwy aplikacji w menu Start. Można tę ikoną zmienić wybierając przycisk Load Icon, a następnie odpowiedni plik .ICO. Można poszukać w katalogu IMAGES\ICONS. Wybrana ikona jest podczas kompilacji umieszczana w pliku .EXE.
Opcje Directory /Conditional
Jeśli chcesz, aby skompilowana była umieszczona w innym katalogu niż projekt, wpisz ścieżkę do tego katalogu w polu tekstowym Output Directory .
Pole tekstowe Search Path określa lokalizację (lokalizacje) bibliotek, które nie są umieszczone w katalogu
Menedżer projektu.
Podstawowe zastosowanie Menedżera projektu (dodawanie i usuwanie modułów)
Menedżer projektu i jego elementy.
Elementy projektu mogą być umieszczone w różnych katalogach. Zarządzanie plikami projektu ułatwia Menadżer projektów.
Za pomocą Menadżera projektów można otwierać, dodawać, zachowywać i przesuwać pliki projektu.
Wyświetlenie Menadżera projektów
Projekt powinien być otwarty.
n Aby otworzyć okno Menadżera projektów wybierz View|Project Manager.
Elementy okna Menadżera projektu
Pasek narzędzi Menadżera projektu
Zawiera sześć przycisków:
Przycisk |
Polecenie |
Polecenie Delphi |
Funkcja |
Komentarz |
Add |
Dodaj plik |
File|Add to Project |
Dodaje pliki do projektu. Kolumna Path podaje położenie plików. |
Podczas dodawania pliku do projektu, plik nie jest kopiowany do katalogu projektu, jedynie informacja o jego aktualnym położeniu jest rejestrowana w sekcji uses pliku projektu .DPR. |
Remove |
Usuwa plik |
File|Remove from Project |
Usuwa zaznaczone pliki z bieżącego projektu. |
Pliki nie są fizycznie usuwane, nie należą już tylko do projektu. Odpowiednie zmiany są dokonywane w pliku .DPR. Uwaga Nie kasuj pliku (na przykład przy użyciu Eksploratora Windows) dopóki ten plik nie zostanie usunięty ze wszystkich projektów, do których należał. |
View Unit |
Wyświetla moduł |
View|Units (Ctrl + F12) |
Otwiera (jeśli trzeba) i wyświetla zawartość modułu w Edytorze kodu. |
Użycie polecenia View|Unit powoduje wyświetlenie okna dialogowego, w którym trzeba wybrać moduł do wyświetlenia. |
View Form |
Wyświetla formularz |
View|Forms (Shift + F12) |
Wyświetla ostatnio zaznaczony formularz w trybie projektu. Przycisk jest dostępny tylko. gdy jest zaznaczony plik modułu skojarzony z formularzem. |
Użycie polecenia View|Forms powoduje wyświetlenie okna dialogowego, w którym trzeba wybrać formularz do wyświetlenia. |
Options |
Opcje |
Options|Project |
Wyświetla okno dialogowe Project Options . |
|
Update |
Uaktualnij |
|
Synchronizuje okno Menadżera projektów z listą modułów tworzących projekt, zapisaną w pliku .DPR. |
Przycisk normalnie niedostępny. Jest wyświetlany tylko w przypadku ręcznej modyfikacji pliku .DPR (jest to nie zalecane). |
Pasek stanu Menadżera projektów
W tym obszarze, położony tradycyjnie w dole okna, jest wyświetlona informacja o lokalizacji pliku projektu .DPR. łączna liczba formularzy i modułów zarejestrowana w pliku .DPR.
Lista plików projektu
Ten obszar zawiera informacje o plikach wchodzących w skład projektu. Zostały one pobrane z pliku .DPR.
Kolumna Path
Jeśli jakieś pliki wchodzące w skład projektu znajdują się w innym niż cały projekt katalogu, to ścieżka do nich jest podana w kolumnie Path. Pusta kolumna oznacza, że plik jest w bieżącym katalogu.
Nawigacja pomiędzy składnikami projektu
W czasie pracy nad projektem często trzeba przechodzić pomiędzy modułami, formularzami, oknem Menadżera projektu itd.
Przeglądanie formularzy i modułów
Pomiędzy formularzami i ich modułami możemy łatwo się przełączać korzystając z poleceń z menu View , za pomocą klawiszy skrótu lub Menadżera projektów.
Uwaga Aby zamknąć stronę z kodem modułu w Edytorze kodu wybierz z menu podręcznego Edytora polecenie Close Page.
Przełączanie się między projektem formularza a jego modułem
n Aby przełączać się pomiędzy oglądaniem bieżącego formularza a jego kodem źródłowym, wybierz jedną z metod:
Wciśnij F12.
Kliknij przycisk Toggle Form/Unit.
W Menadżerze projektów dwukrotnie kliknij w kolumnie Unit, aby oglądać kod źródłowy formularza lub dwukrotnie kliknij w kolumnie Form , aby oglądać formularz w trybie projektu.
Przełączanie pomiędzy oknami
Lista okien jest przydatna, gdy mamy dużo otwartych okien.
n Aby wyświetlić Listę okien (Window List) i przejść do wybranego okna:
1 Wciśnij Alt+0 (zero) lub wybierz View|Window List a następnie wybierz okno, do którego chcesz przejść.
Budowanie formularzy i menu
Wykorzystanie w jednym formularzu innych formularzy.
Sprawianie, że formularze są widoczne w innych formularzach
Umożliwienie wykorzystania dwóch formularzy nawzajem przez siebie
Zanim rozpoczniesz projektowanie i budowanie formularza, zastanów się czy może on być użyteczny w innych aplikacjach. Najprostszy sposób ponownego wykorzystania istniejącego formularza to dodanie go do nowego projektu.
Sprawianie, że formularze są widoczne w innych formularzach
Jeśli chcemy wywołać procedurę, która znajduje się na innym formularzu lub np. sprawdzić zawartość pola tekstowego na tym formularzu, musimy zadeklarować w sekcji uses użycie modułu, w którym znajduje się ten formularz (tzn. musimy podać nazwę pliku .PAS ).
Umożliwienie wykorzystania dwóch formularzy nawzajem przez siebie
Jeżeli chcemy, aby dwa formularze nawzajem z siebie korzystały musimy pamiętać o kilku rzeczach:
Umieść sekcje uses z deklaracją użycia tych modułów w sekcji implementation obu formularzy.
Jeśli w części interface muszą być zadeklarowane moduły, to przynajmniej w jednym module deklaracja modułów wzajemnie zależnych musi być w części implementation.
Wykorzystanie szablonów formularzy.
Wykorzystanie szablonów formularzy
Zachowywanie formularza w postaci szablonu
Szablony są najprostszym sposobem na wielokrotne wykorzystanie formularza.
Dodawanie szablonów formularza do projektu
n Aby dodać szablon formularza do projektu:
1 Kiedy masz otwarty projekt wybierz File|New....
2 Na stronie Forms (lub innej) podświetl szablon formularza, który chcesz dodać i kliknij OK. Delphi doda kopię szablonu formularza do projektu wraz z towarzyszącym mu modułem. Możesz teraz dokonywać zmian. które nie będą miały wpływu na oryginalny szablon formularza.
Zachowanie formularza w postaci szablonu
n Aby zachować formularz w postaci szablonu:
1 Kliknij prawym klawiszem muszki na formularzu, aby wyświetlić menu podręczne.
2 Z menu podręcznego wybierz Add To Repository .
3 W polu Title wprowadź nazwę szablonu formularza. W polu Description wpisz krótki opis szablonu formularza.
4 Na liście Page wybierz stronę w repozytorium, na której ma się znaleźć nowy szablon formularza.
5 Wybierz Browse i zaznacz bitmapę, która ma reprezentować szablon.
Tworzenie okien dialogowych.
Wyświetlanie formularza w trybie modalnym i niemodalnym
Zamykanie formularza.
Procedury i funkcje do wyświetlania okien dialogowych
Tworzenie własnych okien dialogowych.
Jednym z najczęstszych sposobów komunikacji z użytkownikiem są okna dialogowe. W Delphi możemy korzystać z gotowych komponentów - okien dialogowych lub wykorzystać dostępne procedury i funkcje.
Procedury i funkcje do wyświetlania okien dialogowych
Moduł Dialogs zawiera kilka prostych procedur i funkcji, które wyświetlają okna dialogowe, na podstawie podanych parametrów. Ponieważ wyświetlają komunikaty w wersji angielskiej (tekst na przyciskach) więc lepiej jest skorzystać z funkcji Windows API.
Wyświetlanie okien komunikatów
Okna komunikatu służą do wyświetlania różnorodnych komunikatów. Użytkownik musi na nie odpowiedzieć. Dopóki tego nie zrobi, aplikacja jest nieaktywna.
Okna komunikatów są zwykle używane w następujących celach:
Wyświetlanie ostrzeżeń.
Wyświetlanie komunikatów o błędzie.
Wyświetlanie prośby o potwierdzenie np. wyjścia z aplikacji.
Procedura ShowMessage
Procedura ShowMessage jest najprostszym sposobem na wyświetlenie krótkiej informacji.
Składnia procedury jest następująca:
ShowMessage(const Msg: string);
Wyświetla okno z komunikatem, podanym jako Msg i z przyciskiem OK.
ä Aby wypróbować wyświetlanie okna komunikatu za pomocą procedury ShowMessage wykonaj te kroki:
1 Utwórz nowy pusty projekt i umieść na nim przycisk.
2 Utwórz dla tego przycisku procedurę obsługi zdarzenia OnClick o treści:
ShowMessage('Delphi delivers!');
Uruchom program.
Metoda MessageBox()
Metoda MessageBox wyświetla okno komunikatu, które zawiera tekst podany jako parametr oraz, opcjonalnie, różnorodne nagłówki i przyciski. Jest to wywołanie wbudowanej funkcji Windows API, z tym, że nie trzeba podawać uchwytu okna.
Składnia funkcji jest następująca:
function MessageBox(Text, Caption: PChar; Flags: Word): Integer;
Znaczenie parametrów jest następujące:
Parametr |
Znaczenie |
Text |
Tekst wyświetlany w oknie dialogowym |
Caption |
Tytuł na pasku tytułu w oknie dialogowym. |
Flags |
Typ przycisku (przycisków) w oknie dialogowym. |
Stałe, które możesz podać jako parametry można znaleźć w pomocy. Przykładowe to:
Stała Flags |
Znaczenie |
MB_AbortRetryIgnore |
Wyświetla zestaw przycisków: Przerwij, Ponów próbę, Zignoruj |
MB_OK |
Wyświetlany jest tylko przycisk OK |
MB_OkCancel |
Wyświetla zestaw dwóch przycisków: OK i Anuluj |
MB_YesNo |
Wyświetla zestaw dwóch przycisków: Tak i Nie |
MB_YesNoCancel |
Wyświetla zestaw przycisków: Tak, Nie i Anuluj |
MB_IconExclamation |
Wyświetlana jest ikona wykrzyknika |
MB_IconInformation |
Wyświetlana jest ikona z pochyloną literą i |
MB_IconQuestion |
Wyświetlana jest ikona ze znakiem zapytania |
MB_IconStop |
Wyświetlana jest ikona ze znakiem stopu |
MB_DefButton1 |
Pierwszy przycisk jest przyciskiem domyślnym |
MB_DefButton2 |
Drugi przycisk jest przyciskiem domyślnym. |
MB_DefButton3 |
Trzeci przycisk jest przyciskiem domyślnym. |
MB_DefButton4 |
Czwarty przycisk jest przyciskiem domyślnym. |
Flagi można łączyć za pomocą symbolu + np.
MB_YesNo + MB_IconInformation + MB_DefButton1
Metodę wywołujemy np. dla aplikacji :
Application.MessageBox(`Czy chcesz kontytuować tę operację, `Potwierdzenie',
MB_YesNoAnuluj + MB_IconQuestion);
Metoda zwraca kod, który symbolizuje wciśnięty przycisk:
Kod zwracany |
Jego znaczenie |
IDAbort |
Został wciśnięty przycisk Przerwij |
IDCancel |
Został wciśnięty przycisk Anuluj |
IDIgnore |
Został wciśnięty przycisk Zignoruj |
IDNo |
Został wciśnięty przycisk Nie |
IDOK |
Został wciśnięty przycisk OK |
IDRetry |
Został wciśnięty przycisk Ponów próbę |
IDYes |
Został wciśnięty przycisk Tak |
ä Tak możesz wypróbować działanie funkcji MessageBox.
1 Rozpocznij nowy, pusty projekt.
2 Dodaj przycisk do formularza, i utwórz następującą procedurę obsługi zdarzeń:
procedure TForm1.Button1Click(Sender: TObject);
var
Button: Integer;
begin
Button := Application.MessageBox('Witamy w świecie Delphi!', 'Message Box', mb_OKCancel +
mb_DefButton1);
if Button = IDOK then
Label1.Caption := 'Wybrałeś OK';
if Button = IDCANCEL then
Label1.Caption := 'Wybrałeś Anuluj';
end;
3 Uruchom program.
Tworzenie prostego formularza do wprowadzania danych
Do tworzenia prostych okien dialogowych można też wykorzystać istniejące szablony okien, które są dostępne po wybraniu polecenia File|New... na stronie Dialogs. Można też stworzyć własne szablony okien dialogowych i umieścić je na tej stronie.
Password Dialogs (ukrywanie wprowadzonych znaków)
Jest to szablon znajdujący się na stronie Dialogs. Jeśli chcemy wprowadzić do programu hasło, najlepiej użyć właściwości PasswordChar pola tekstowego Edit, aby zamiast wprowadzanych liter wyświetlać specjalne znaki, takie jak (*) lub (#).
ä Aby zobaczyć to w praktyce, wypróbuj:
1 Rozpocznij nowy, pusty projekt
2 Wybierz File|New...
3 Ze strony Dialogs wybierz szablon Password Dialogs.
ä Zaznacz komponent Edit na Password Template. Właściwość PasswordChar jest ustawiona na *.
ä Aby zobaczyć działanie Password entry Form Template wypróbuj:
1 Dodaj przycisk do formularza Form1, i zapisz następującą procedurę obsługi zdarzenia OnClick.:
procedure TForm1.Button1Click(Sender: TObject);
begin
PasswordDlg.ShowModal;
end;
2 Dodaj Unit2 do sekcji uses modułu Unit1, i uruchom aplikację.
3 Wybierz Button1 aby wyświetlić okno dialogowe Password. Wpisz dowolny tekst. W oknie pojawiają się jedynie gwiazdki.
Tworzenie własnych okien dialogowych
Tworzenie oknie dialogowych modalnych i niemodalnych
Modalne okno dialogowe to takie, które użytkownik musi zamknąć, zanim rozpocznie dalszą pracę z aplikację. Większość okien dialogowych jest modalna. Możesz też tworzyć niemodalne okna dialogowe, na przykład wyświetlające dodatkowe informacje, do których użytkownik może się odwołać w czasie pracy z aplikacją.
Uwaga Jeśli chcesz stworzyć niemodalne okno dialogowe, które zawsze znajduje się na wierzchu, ustaw właściwość formularza FormStyle na fsStayOnTop .
Formularze możemy otwierać za pomocą dwóch metod:
Show, otwiera formularz w trybie niemodalnym
ShowModal, otwierającą formularz w trybie modalnym.
Wyświetlanie niemodalnego okna dialogowego
ä Uruchom okno dialogowe About w trybie niemodalnym,
1 Zacznij nowy pusty projekt i dodaj przycisk do formularza.
2 Utwórz następującą procedurę obsługi zdarzeń:
procedure TMainForm.Button1Click(Sender: TObject);
begin
AboutBox.Show;
end;
3 Dodaj w module Unit1 do sekcji uses deklarację użycia modułu Unit2.
4 Dodaj okno About do projektu, przez wybór polecenia File|New Form i wybór odpowiedniego szablonu.
5 Uruchom aplikację i kliknij na Button1.Pojawi się okno About. Kliknij na formularz Form1. Okno schowa się w tyle, aktywny będzie formularz.
Wyświetlanie okna dialogowego w trybie modalnym
ä Aby uruchomić okno About w trybie modalnym:
1 Zmień kod procedury obsługi zdarzenia OnClick dla Form1.Button1 w następujący sposób:
procedure TMainForm.Button1Click(Sender: TObject);
begin
AboutBox.ShowModal;
end;
2 Teraz uruchom program i kliknij na Button1 ,aby wyświetlić okno About.
3 Spróbuj kliknąć na formularz Form1.Zauważ, że nie możesz przejść do formularza, zanim nie zamkniesz okna About.
Ustawianie właściwości dla okna dialogowego
Okno dialogowe nie potrzebuje pewnych elementów charakterystycznych dla formularzy takich jak na przykład przycisk Minimalizacji i Maksymalizacji. Ustawiając właściwość BorderStyle na bsDialog zmieniamy kilka ustawień:
Usuwamy przycisk Minimalizacji i Maksymalizacji.
Brak przycisku kontrolnego.
Nie ma możliwości zmiany rozmiaru formularza.
Inne zmiany stylu formularza:
Właściwość |
Ustawienia |
Efekt |
BorderIcons |
||
BiSystemMenu |
False |
Usuwa menu kontrolne |
biMinimize |
False |
Usuwa przycisk Minimalizacji |
biMaximize |
False |
Usuwa przycisk Maksymalizacji |
biHelp |
False |
Usuwa przycisk pomocy |
BorderStyle |
||
|
bsSizeable |
Pozwala użytkownikowi na zmianę rozmiarów formularza. |
|
bsSingle |
Tworzy pojedynczy brzeg, nie można zmieniać rozmiarów formularza |
|
bsNone |
Brak brzegu formularza, brak możliwości zmian rozmiaru formularza |
Uwaga Te zmiany będą widoczne dopiero po uruchomieniu aplikacji.
Ustawianie nagłówka dla okna dialogowego
Nagłówek okna dialogowego powinien informować o przeznaczeniu okna. Można to uzyskać przez ustawienie właściwości Caption.
Przyciski poleceń
Każde okno dialogowe powinno mieć co najmniej jeden przycisk, przede wszystkim “OK” lub “Zamknij”. Przydatny jest też przycisk „Anuluj”. Można też używać zestawu „Tak” , „Nie” i „Anuluj”.
W kodzie programu kontrolowany jest rodzaj wciśniętego przycisku. W zależności jego typu następuje odpowiednia reakcja. Poprzez ustawianie właściwości przycisków można trzeba utworzyć wywołać odpowiednie procedury obsługi zdarzeń przycisków w sytuacji, gdy użytkownik wciśnie Enter lub Esc. Bez pisania dodatkowego kodu, można sprawić, że formularz będzie zamknięty na naciśnięciu odpowiedniego przycisku.
Przycisk reagujący na Esc
Jeśli przycisk ma ustawioną właściwość Cancel na True , wciśnięcie powoduje wykonanie procedury obsługi zdarzenia OnClick tego przycisku.
n Aby przycisk reagował na wciśnięcie Esc ustaw właściwość Cancel tego przycisku na True.
Przycisk reagujący na Enter
Wciśnięcie klawisza Enter powoduje wykonanie procedury obsługi zdarzenia OnClick przycisku, który jest zaznaczony (ma fokus). Ustawiając właściwość Default danego przycisku na True powodujemy, że właśnie ten przycisk jest aktywny na początku działania formularza (okna dialogowego
Uwaga Chociaż inne elementy mogą uzyskać fokus, to tylko dla przycisku wciśnięcie Enter powoduje wykonanie procedury obsługi zdarzenia domyślnego (czyli OnClick).
n Aby sprawić, że przycisk będzie domyślny, ustaw jego właściwość Default na True.
n Aby przenieść fokus do przycisku w czasie działania aplikacji wywołaj metodę SetFocus (metoda przycisku).
Zamknięcie okna dialogowego, kiedy użytkownik wciśnie przycisk
Aby sprawić, że okno dialogowe zamyka się po kliknięciu na przycisk, nie musimy pisać żadnej procedury obsługi zdarzeń. Wystarczy tylko nadać właściwości ModalResult niezerową wartość.
Dla przycisku Anuluj ustawiamy tę właściwość na mrCancel, a dla przycisku OK mrOK . W obu przypadkach po kliknięciu na przycisk, okno dialogowe zamknie się. ModalResult zwróci do funkcji ShowModal niezerową wartość, dzięki której będzie można odróżnić, który przycisk został wciśnięty.
ä Aby automatycznie zamknąć okno dialogowe po kliknięciu na przycisk Anuluj lub po wciśnięciu Esc ustaw właściwość ModalResult przycisku na mrCancel.
n Aby automatycznie zamknąć okno dialogowe, gdy użytkownik kliknie na przycisk lub wciśnie Enter , kiedy przycisk ma fokus, ustaw jego właściwość ModalResult na mrOK .
Tworzenie standardowych przycisków
Można szybko stworzyć standardowe przyciski poprzez dodanie komponentu BitBtn i ustawienie jego właściwości Kind . Zmiana tej właściwości powoduje jednoczesną zmianę właściwości ModalResult , z wyjątkiem rodzajów bkCustom , bkHelp i bkClose . Dla tych przypadków ModalResult przyjmuje wartość mrNone, a okno nie jest automatycznie zamykane po wybraniu takiego przycisku. Standardowe rodzaje przycisków zawierają nie tylko tekst, ale też i symbol graficzny.
Predefiniowane typy przycisków BitBtn
Wartość właściwości Kind |
Efekt |
Ustawienia innych właściwości |
Komentarz |
BkAbort |
Tworzy przycisk Cancel z tekstem Abort. |
Caption := `Abort' ModalResult := mrAbort |
Obok tekstu pojawia się czerwony X. |
bkAll |
Tworzy przycisk OK z tekstem All. |
Caption := `&All' ModalResult := 8 |
Obok tekstu pojawia się zielony podwójny check mark. |
bkCancel |
|
Caption := `Cancel' Cancel := True ModalResult := mrCancel |
Obok tekstu pojawia się czerwony X. |
bkClose |
Tworzy przycisk Close z tekstem Close. Zamyka okno. |
Caption := `&Close' |
Obok tekstu pojawiają się drzwi wyjściowe. |
bkCustom |
Żaden |
Nie dotyczy |
Użyj tego ustawienia, aby stworzyć własny przycisk z wybranym obrazkiem (Glyph - bitmapa). |
bkHelp |
Tworzy przycisk z tekstem Help. |
Caption := `&Help' |
Obok tekstu pojawia się niebieski znak zapytania. Użyj procedury obsługi zdarzeń do wywołania pliku pomocy. (Jeśli okno dialogowe ma kontekst pomocy, Delphi zrobi to automatycznie). |
bkIgnore |
Tworzy przycisk służący do ignorowania zmian i kontynuowania akcji. |
Caption := `&Ignore' ModalResult := mrIgnore |
Użyj do kontynuowania akcji po wystąpieniu błędu. |
bkNo |
Tworzy przycisk Cancel z tekstem No |
Caption := `&No' Cancel := True ModalResult := mrNo |
Obok tekstu pojawia się czerwone przekreślone koło. |
bkOK |
Tworzy przycisk OK z tekstem OK |
Caption := `OK' Default := True ModalResult := mrOK |
Obok tekstu pojawia się zielony check mark . |
BkRetry |
Tworzy przycisk do ponawiania akcji. |
Caption := `&Retry' ModalResult := mrRetry |
Obok tekstu pojawiają się dwie cykliczne zielone strzałki. |
BkYes |
Tworzy przycisk OK z tekstem Yes. |
Caption := `&Yes' Default := True ModalResult := mrYes |
Obok tekstu pojawia się zielony check mark . |
ä Aby utworzyć kod otwierający okno dialogowe:
1 Dwukrotnie kliknij na przycisk Button1 (w MainForm) aby utworzyć procedurę obsługi domyślnego zdarzenia.
2 W bloku begin..end wpisz wywołanie metody ShowModal otwierającej formularz About jako okno dialogowe (tzn. aby użytkownik mógł wykonywać jakiekolwiek czynności musi najpierw zamknąć okno dialogowe).
AboutBox.ShowModal;
3 Dodaj do sekcji uses modułu MainForm deklarację wykorzystania modułu About.
4 Skompiluj i uruchom aplikację.
5 Kliknij na przycisk Button1 aby otworzyć okno About.
6 Kliknij na przycisk OK., aby zamknąć okno dialogowe. Przycisk OK. działa tak, ponieważ w projekcie jego właściwość Kind była ustawiona na bkOK, a styl obramowania na bsDialog.
Ustalenie kolejności przejścia przy klawiszu Tab.
Ustalanie kolejności przejścia przy klawiszu tab
Kolejność reagowania na klawisz Tab polega na kolejności w jakiej będziemy przechodzić od komponentu do komponentu, kiedy wciskamy klawisz Tab. Domyślnie kolejność ta jest ustawiana domyślnie zgodnie z kolejnością dodawania komponentów do formularza. Można tę kolejność zmienić. Aby komponent uzyskał fokus po wciśnięciu klawisza Tab, jego właściwość TabStop powinna być ustawiona na True.
n Aby użyć okno dialogowe Edit Tab Order:
1 Zaznacz formularz lub komponent zbiorczy, dla których chcemy ustawić kolejność klawisza Tab.
2 Wybierz Edit|Tab Order (lub kliknij na przycisk Tab Order). W oknie dialogowym Edit Tab Order pojawi się lista komponentów, w aktualnej kolejności klawisza Tab.
3 Na liście Controls zaznacz komponent, którego kolejność chcesz zmienić i kliknij odpowiedni przycisk strzałki(Up lub Down), albo przeciągnij komponent na właściwe miejsce.
4 Po uporządkowaniu kolejności komponentów , wybierz OK.
Przy użyciu okna dialogowego Edit Tab Order zmieniamy właściwość TabOrder komponentów. Można tę właściwość zmienić też ręcznie.
n Aby ręcznie zmienić właściwość TabOrder komponentów:
1 Zmień właściwość TabOrder komponentu zgodnie z pozycją, którą powinien mieć komponent w liście kolejności klawisza Tab
Uwaga:
Pierwszy komponent na liście kolejności klawisza Tab ma wartość TabOrder równą 0.
Każda wartość powinna być unikatowa.
Wartość TabOrder powinna być mniejsza od liczby komponentów. Tylko ostatni komponent może mięć większą wartość.
Komponenty niewidoczne lub wyłączone nie otrzymują fokusu po wciśnięciu klawisza Tab , nawet jeśli mają poprawną wartość TabOrder .
Testowanie kolejności klawisza Tab
Efekt ustawień kolejności klawisza Tab możemy obserwować po uruchomieniu aplikacji.
n Aby przetestować kolejność klawisza Tab:
1 Uruchom aplikację i obserwuj , w jakiej kolejności komponenty uzyskują fokus, podczas wciskania klawisza Tab.
Usunięcie komponentu z listy kolejności klawisza Tab
Czasami nie chcemy, aby podczas wciskania klawisza Tab, komponent uzyskiwał fokus (na przykład nie chcemy, aby komponent Panel uzyskał fokus).
n Aby usunąć komponent z listy kolejności klawisza Tab:
1 Ustaw właściwość komponentu TabStop na False.
Wyłączanie komponentu.
Wyłączanie komponentu
Można wyłączyć komponent, tak, aby użytkownik nie mógł do niego przejść (nawet, gdy właściwość TabStop jest ustawiona True). Na przykład można wyłączyć przycisk OK i włączyć go dopiero, gdy użytkownik poda nazwę pliku. Wyłączony element jest wyświetlany na szaro.
Można również sprawić, aby komponent był niewidoczny i wyświetlić go ponownie, gdy np. użytkownik wciśnie jakiś przycisk.
n Aby wyłączyć komponent, ustaw jego właściwość Enabled na False .
n Aby komponent uczynić niewidocznym, ustaw jego właściwość Visible na False .
Ustawianie fokusu.
Ustawianie fokusu.
Tylko jeden komponent na formularzu może być aktywny w danym momencie aktywny, czyli mieć fokus
Ustawianie fokusu w czasie projektu
n Aby wybrać komponent, który jako pierwszy będzie aktywny po otwarciu formularza, ustaw właściwość ActiveControl. W tym celu wybierz z rozwijanej listy nazwę tego komponentu.
Jeśli żaden komponent nie zostanie wybrany aktywnym, Delphi ustawi jako aktywny komponent, który jest jako pierwszy na liście kolejności klawisza Tab (z wyjątkiem wyłączonych, niewidocznych lub ustawieniem TabStop na False).
Nadawanie fokusu w kodzie programu
Taką potrzeba może zaistnieć, gdy chcemy na przykład zaoferować użytkownikowi możliwość przechodzenia od elementu do elementu za pomocą strzałek kursora. Do nadawania fokusu służy metoda SetFocus.
n Aby ustawić fokus dla komponentu, wywołaj dla niego metodę SetFocus :
<nazwa_komponentu>.SetFocus;
ä Wypróbuj.
1 Dodaj do nowego formularza komponenty: Edit, Button i Memo. Ustaw ich właściwości zgodnie z tabelą:
Komponent |
Właściwość |
Ustawienie |
Form1 |
ActiveControl |
Edit1 |
Edit1 |
Text |
<pusty> |
Button1 |
Default |
True |
Button1 |
Caption |
OK. |
2 Utwórz następującą procedurę obsługi zdarzenia OnClick przycisku Button1:
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Lines.Add(Edit1.Text);
Edit1.Clear;
end;
3 Uruchom program. Na początku aktywnym elementem jest Edit1.
4 Wpisz dowolny tekst do pola tekstowego Edit1 i wciśnij Enter. Ponieważ przycisk Button1 jest domyślnym przyciskiem, wciśnięcie klawisza Enter aktywuje zdarzenie OnClick.
Tworzenie menu formularzy.
Tworzenie menu formularza
Łączenie zdarzeń menu z kodem programu
Modyfikacja menu
Edytowanie poleceń menu bez użycia Projektanta menu
Używanie szablonów menu i zachowywanie menu w postaci szablonu
Menu są wygodnym sposobem wybierania poleceń przez użytkownika. W Delphi menu tworzy się w łatwy sposób dzięki komponentowi menu oraz Projektantowi Menu (Menu Designer).
Otwieranie Projektanta menu
Aby uruchomić Projektanta menu musisz najpierw dodać do formularza komponent MainMenu lub PopupMenu
Komponent MainMenu tworzy standardowe menu na górze formularza, PopupMenu tworzy menu podręczne, które się pojawia, gdy klikamy prawym klawiszem myszki.
n Aby otworzyć Projektanta menu dwukrotnie kliknij komponent menu.
Pojawi się Projektant menu z pierwszym, pustym poleceniem menu.
Tworzenie menu
Musisz dodać komponent menu dla każdego menu, które chcesz umieścić w aplikacji. Możesz budować menu od podstaw lub skorzystać ze szablonu memu.
Nadawanie nazw poleceniom menu
Musisz wpisać nazwy kolejnych poleceń. Najlepiej jest wpisać wartość do właściwości Caption, Delphi automatycznie wpisze wartość do właściwości Name.
Uwaga Jeśli wartość właściwości zawiera znaki niedozwolone dla identyfikatorów (na przykład spacje) wartość Name jest tak modyfikowana, aby była poprawną nazwą identyfikatora.
Delphi dodaje wszystkie nazwy poleceń menu do deklaracji klasy formularza.
Dodawanie, wstawianie i usuwanie poleceń menu
Zakładamy, że okno Projektanta menu jest otwarte.
n Aby dodać polecenie menu w trybie projektu:
1 Zaznacz pozycję, ma której chcesz utworzyć polecenie. Na początku tworzenia menu jest zaznaczona pierwsza pozycja.
2 Wpisz nazwę polecenia (na przykład do właściwości Caption) i wciśnij Enter.
Pojawia się zaznaczone miejsce na następne polecenie..
4 W podobny sposób możesz dodać kolejne polecenia. Użyj strzałek kursora do poruszania się pomiędzy poszczególnymi poleceniami (lub myszki).
n Aby wstawić do listy poleceń nowe puste miejsce umieść kursor pod miejscem, gdzie ma być wstawione plecenie (lub z prawej strony) i wciśnij klawisz Ins.
n Aby usunąć element menu lub polecenie menu zaznacz je i kliknij Del.
Uwaga Nie możesz skasować pustego miejsca, które się pojawia pod lub z prawej strony ostatnio wpisanego polecenia. Te puste miejsca nie są widoczne po uruchomieniu aplikacji.
Dodawanie separatorów
Długą listę pleceń możesz pogrupować za pomocą poziomej linii.
n Aby utworzyć separator (poziomą linię) wpisz we właściwości Caption polecenia menu myślnik (-).
Określanie klawiszy szybkiego dostępu i skrótów klawiszowych
Klawisze szybkiego dostępu umożliwiają wywołanie polecenia menu przez wciśnięcie klawisza Alt i wyróżnionej litery. Wyróżnione litery są oznaczone w menu poprzez podkreślenie. Skróty klawiszowe umożliwiają wykonanie polecenia po wpisaniu określonej kombinacji klawiszy.
n Aby określić klawisz szybkiego dostępu, dodaj przed nim znak &. Na przykład, aby określić dla polecenia Zapisz klawisz szybkiego dostępu Z, wpisz &Zapisz.
n Aby określić klawisz skrótu, wpisz odpowiednią kombinację klawiszy we właściwości ShortCut polecenia menu. Możesz też wybrać kombinację klawiszy z rozwijanej listy.
Skrót pojawi się obok nazwy polecenia.
Uwaga! Delphi nie sprawdza, czy klawisze skrótu się powtarzają.
Tworzenie podmenu (nested (sub)menus)
Do poleceń menu możemy dodać podmenu. Polecenie. które rozwija się w podmenu, jest oznaczane przez strzałkę obok polecenia. Taka organizacja poleceń jest szczególnie korzystna w przypadku bardzo rozbudowanego systemu menu. Można dodać dowolną ilość poziomów podmenu, chociaż w praktyce nie używa się więcej niż dwa lub trzy poziomy.
n Aby utworzyć podmenu:
1 Zaznacz polecenie menu, obok którego chcesz utworzyć podmenu
2 Wciśnij Ctrl→ aby utworzyć pierwsze miejsce na polecenie podmenu lub wybierz Create Submenu z menu podręcznego.
3 Wpisz nazwę pierwszego polecenia podmenu lub przeciągnij istniejące polecenie menu.
4 Wciśnij Enter lub , aby utworzyć miejsce na następne polecenie.
5 Kiedy wpiszesz wszystkie polecenia wciśnij Esc, aby wrócić na poprzedni poziom menu.
Tworzenie podmenu poprzez przeciąganie istniejącego menu
Można utworzyć podmenu poprzez proste przeciągnięcie istniejącego menu (np. z szablonu lub z paska menu). Podczas przeciągania zachowywana jest cała struktura przeciąganego menu.
Przesuwanie poleceń menu
Podczas projektu możemy przesuwać polecenia menu w inne miejsce na liście poleceń menu. Jedyne ograniczenie to takie, iż nie możemy przesunąć polecenie menu z paska menu do jednego z jego własnych poleceń, ani przeciągnąć menu do jego własnego podmenu.
n Aby przesunąć polecenie menu wzdłuż paska menu przeciągnij myszką w nowe położenie.
n Aby przesunąć polecenie menu do listy poleceń menu:
1 Przeciągnij polecenie menu wzdłuż paska menu, aż do polecenia, do którego listy chcesz go dołączyć. Lista poleceń powinna się rozwinąć.
2 Przeciągnij polecenie i upuść na listę w wybranym miejscu.
Oglądanie menu
Menu jest widoczne na górze formularza. Polecenia menu podręcznego można oglądać tylko po uruchomieniu aplikacji lub w Projektancie menu.
Polecenia z menu podręcznego Projektanta menu
Menu podręczne Projektanta menu oferuje szybki dostęp do najczęściej używanych poleceń.
n Aby wyświetlić menu podręczne kliknij prawym klawiszem myszki na okno Projektanta menu.
Polecenia w menu podręcznym
Polecenie menu |
Akcja |
Insert |
Wstawia miejsce na nowe polecenie nad lub z lewej strony zaznaczonego polecenia. |
Delete |
Usuwa zaznaczone polecenie (wraz z podmenu, o ile takie istnieje) |
Create Submenu |
Tworzy podmenu i wyświetla miejsce na pierwsze polecenie menu. Dodaje strzałkę z prawej strony polecenia. |
Select Menu |
Otwiera listę menu w bieżącym formularzu. Dwukrotne kliknięcie obok wybranego menu otwiera okno projektowe z tym menu. |
Save As Template |
Otwiera okno dialogowe Save Template , gdzie możesz zachować menu do przyszłego użytku.. |
Insert From Template |
Otwiera okno dialogowe Insert Template, gdzie możesz zaznaczyć szablon, który chcesz wstawić do menu. |
Delete Templates |
Otwiera okno dialogowe Delete Templates, gdzie możesz usunąć wybrany szablon. |
Insert From Resource |
Otwiera okno dialogowe Insert Menu from Resource , w którym można wybrać plik .MNU do otwarcia w bieżącym formularzu. |
Przełączanie pomiędzy menu w trybie projektu
Jeśli utworzyłeś kilka menu w formularzu, możesz łatwo przełączać się między nimi za pomocą menu podręcznego Projektanta menu lub Inspektora obiektów.
n Aby przełączać się między menu na formularzu:
1 Kliknij prawym klawiszem myszki na Projektancie menu, aby otworzyć menu podręczne i wybierz polecenie Select Menu.
2 Wybierz z listy wszystkich menu na formularzu, menu które chcesz oglądać.
n Aby przełączać się między menu na formularzu przy użyciu Inspektora obiektów:
1 Zaznacz formularza i z Listy komponentów, widocznej na górze Inspektora obiektów wybierz menu, które chcesz edytować.
2 Dwukrotnie kliknij obok właściwości Items aby otworzyć okno Projektanta menu.
Używanie szablonów menu
Delphi oferuje szereg szablonów menu, które zawierają zestaw najczęściej używanych menu. Można je wykorzystać jako punkt startowy docelowego menu. Szablony menu nie zawierają procedur obsługi zdarzeń. Szablony są przechowywane w katalogu \DELPHI\BIN w plikach o rozszerzeniu .DMT. Swoje własne menu możesz również zachować jako szablony, tak aby później wykorzystać je jeszcze raz.
n Aby dodać szablon menu do aplikacji:
1 Otwórz menu podręczne Projektanta menu i wybierz polecenie Insert From Template. (Jeśli nie posiadasz szablonów menu polecenie jest niedostępne).
2 Wybierz szablon , który Cię interesuje. Po kliknięciu na OK (lub wciśnięciu klawisza Enter) szablon menu zostanie wstawiony nad kursorem (jeśli zaznaczone jest polecenie menu na liście poleceń) lub z lewej strony kursora (jeśli zaznaczone jest polecenie na pasku menu).
n Aby usunąć szablon menu
1 Otwórz menu podręczne Projektanta menu i wybierz polecenie Delete Templates. (Jeśli nie posiadasz szablonów menu polecenie jest niedostępne).
2 Na liście szablonów zaznacz ten, który chcesz usunąć i wciśnij Del.
Zachowywanie menu w postaci szablonu
n Aby zachować menu w postaci szablonu:
1 W oknie Projektanta menu umieść (lub utwórz) menu , które chcesz zachować.
2 Otwórz menu podręczne Projektanta menu i wybierz polecenie Save As Template .
3 W polu Template Description wpisz krótki opis menu i kliknij na OK.
Uwaga Opis, który wpisałeś pojawia się tylko w oknach dialogowych Save Template, Insert Template i Delete Templates i nie ma żadnego wpływu na właściwości Name i Caption.
Kiedy zachowujesz menu jako szablon, Delphi nie zachowuje jego właściwości Name, ponieważ każdy element powinien mieć unikatową nazwę. Po dodaniu szablonu, Delphi tworzy ich nazwy.
Nie są również zachowywane procedury obsługi zdarzeń, ponieważ nie ma pewności, czy będą one prawidłowo działać w nowej aplikacji.
Łączenie zdarzeń menu z kodem programu
Same zaprojektowanie menu to jeszcze nie wszystko. Żeby menu mogło być użyteczne, każe polecenie menu musi mieć określoną procedurę obsługi zdarzenia OnClick. Można również modyfikować menu za pomocą kodu programu (przykład w rozdziale 10).
Zdarzenia komponentu menu
Komponent menu nie ma żadnych zdarzeń (zdarzenia mają jedynie polecenia menu). Zdarzenie OnClick polecenia menu na pasku menu jest często wykorzystywane do zmiany stanu poleceń na liście menu, zależnie od stanu programu.
n Aby utworzyć procedurę obsługi zdarzenia dla polecenia menu:
1 Dwukrotnie kliknij na polecenie w oknie Projektanta menu lub kliknij na wybrane polecenie menu widoczne na formularzu.
Powiązanie polecenia menu z istniejącą procedurą obsługi zdarzeń
n Aby połączyć polecenie menu z istniejącą procedurą obsługi zdarzeń:
1 W oknie Projektanta menu wybierz polecenie menu.
2 Sprawdź, czy polecenie ma nazwę (wypełniona właściwość Name).
3 Wybierz na liście procedur przy zdarzeniu OnClick właściwą procedurę.
Wygaszanie poleceń menu.
Włączanie i wyłączanie poleceń menu (wygaszanie)
Czasem istnieje potrzeba dodania polecenia menu w kodzie programu (na przykład zmieniamy polecenia menu w trakcie działania aplikacji). Można wtedy albo wykorzystać metodę Add lub Insert , albo można zmieniać listę poleceń menu ukrywając lub pokazując polecenia poprzez zmianę ich właściwości Visible . Można również uczynić dane polecenie niedostępnym poprzez zmianę właściwości Enabled.
Menu podręczne.
Tworzenie menu podręcznego
Określanie menu podręcznego dla formularza
Menu podręczne to znaczne ułatwienie dla właściciela. Wystarczy kliknąć prawym klawiszem myszki, aby uzyskać dostęp do najczęściej wykonywanych poleceń.
n Aby utworzyć menu podręczne dodaj do formularza komponent PopupMenu.
Obsługa zdarzenia OnPopup komponentu PopupMenu
Zdarzenie to zachodzi w momencie rozwijania menu podręcznego. Wykorzystuje się je głównie do ustalenia, które polecenia menu powinny być dostępne. Przykład - jeśli w edytorze tekstu żaden tekst nie jest zaznaczony, to po rozwinięciu menu podręcznego polecenie Kopiuj powinno być niedostępne.
Określanie menu podręcznego dla komponentu
Jeśli teraz uruchomisz aplikację i spróbujesz kliknąć prawy przyciskiem myszki np. na formularzu - nic się nie stanie. Wbrew pozorom nie otworzy się menu podręczne. Stało się tak, bo nie „nauczyliśmy” komponent , które menu podręczne powinno być otwierane po kliknięciu prawym przyciskiem myszki. Służy do tego właściwość komponentu PopupMenu. Wpisujemy tu (lub lepiej - wybieramy z listy) nazwę komponentu menu podręcznego, które ma się rozwinąć po kliknięciu na ten komponent.
Najczęściej określa się tylko menu podręczne dla formularza. Wówczas nazwę komponentu menu podręcznego wpisujemy obok właściwości PopupMenu formularza.
Tworzenie paska narzędzi
Dodanie do formularza paska narzędzi
Dodanie przycisków do paska narzędzi
Obsługa kliknięcia przycisku.
Dołączenie do przycisków grafiki
Ustawienie początkowego stanu przycisków
tworzenie grup przycisków
przyciski działające na zasadzie przełączników
Dodanie do formularza paska narzędzi
Pasek narzędzi jest panelem, zwykle umieszczonym na górze formularza, poniżej paska menu, na którym są specjalne przyciski i inne elementy kontrolne. Pasek narzędzi ułatwia obsługę aplikacji.
n Aby dodać do formularza pasek narzędzi:
1 Do formularza dodaj komponent Panel.
2 Ustaw właściwość panelu Align na alTop. Wówczas panel zachowuje swoją wysokość, a szerokość jest rozciągana na całą szerokość formularza, nawet gdy okno formularza zmienia swoje rozmiary.
3 Dodaj przyciski (speed buttons) lub inne elementy kontrolne do paska narzędzi.
Do formularza można dodać dowolną ilość pasków narzędzi. Jeśli są one wyrównane do góry, to będą umieszczane jedne pod drugim na górze formularza.
Dodanie przycisków do paska narzędzi
W Delphi jest specjalny komponent speed buttons, przystosowanych do umieszczania ich na paskach narzędzi. Zwykle nie mają one nagłówków, tylko niewielki element graficzny, zwany glyph, który reprezentuje funkcję przycisku.
Przyciski (speed buttons) mają kilka możliwych trybów pracy. Mogą:
Zachowywać się jak zwykłe przyciski (wciskają się przy kliknięciu)
Jedno kliknięcie je włącza (przycisk jest wciśnięty), drugie wyłącza.
Mogą być elementem grupy opcji. Włączenie jednego przycisku z grupy powoduje wyłączenie innych.
n Aby umieścić przyciski na pasku narzędzi, dodaj komponent przycisku do panelu. Teraz panel będzie „właścicielem” przycisków, więc schowanie lub przesunięcie panelu powoduje schowanie lub przesunięcie przycisków.
Dołączenie do przycisków grafiki (glyph)
Grafika na przycisku określa funkcję przycisku. Można przypisać przyciskowi jeden obraz, wówczas grafika będzie odpowiednio zmieniana, aby wyróżnić różne stany przycisków: wciśnięty, nie wciśnięty, zaznaczony, wyłączony. Można również przyporządkować dla tych różnych stanów różne obrazy.
Zwykle przypisujemy grafikę (glyphs) dla przycisku w trybie projektu, choć można to również zrobić w kodzie programu.
n Aby przyporządkować grafikę (glyph) do przycisku w trybie projektu:
1 Zaznacz przycisk i w Inspektorze obiektów dwukrotnie kliknij obok właściwości Glyph.
Zostanie otworzony Edytor obrazu.
2 Kliknij na przycisk Load i odszukaj odpowiedni plik graficzny.
Tworzenie grup przycisków
Seria przycisków (grupa) służy do reprezentowania możliwości wyboru jednej z opcji. Zawsze może być wciśnięty najwyżej jeden przycisk.
n Aby połączyć przyciski w grupę opcji, przyporządkuj im tą samą wartość właściwości GroupIndex. Najłatwiej można to zrobić poprzez zaznaczenie wszystkich przycisków, które będą tworzyć grupę, i wpisać unikalną wartość do właściwości GroupIndex.
Grupy opcji są wykorzystywane gdy oferujemy do wyboru w danym momencie tylko jedną z wartości np. narzędzie do rysowania w programie graficznym.
Przyciski działające na zasadzie przełączników
Można też utworzyć przyciski, które działają jak przełączniki. Przy pierwszym kliknięciu są włączone (wciśnięte), przy drugim kliknięciu podnoszą się (wyłączone). W ten sposób można np. kliknąć wybrany (włączony) przycisk z grupy, tak, aby żaden z przycisków nie był wciśnięty.
n Aby przycisk (grupa przycisków) zachowywał się jak przełącznik
1 Ustaw jego właściwość GroupIndex na wartość różną od 0. Przyciski posiadające ten sam GroupIndex tworzą grupę przycisków.
2 Ustaw jego właściwość AllowAllUp na True. Takie ustawienie dla grupy przycisków powoduje, że żaden przycisk w grupie nie będzie wybrany lub będzie wybrany dokładnie jeden. Dla pojedynczego przycisku uzyskamy efekt przełącznika - przycisk będzie wciśnięty lub nie.
Ustawienie początkowego stanu przycisków
n Aby przycisk wyglądał na wciśnięty, ustaw jego właściwość Down na True. Aby to było możliwe wartość GroupIndex musi być różna od 0. Dla grupy przycisków, których wartość AllowAllUp jest ustawiona na True, jeden z przycisków musi mieć ustawioną wartość Down na True.
n Aby przycisk był wyłączony(nidostępny), ustaw jego właściwość Enabled na False.
Obsługa kliknięcia przycisku
Przyciski (speed-button) rozróżniają dwa zdarzenia: OnClick i OnDblClick.
n Aby odpowiedzieć na kliknięcie na przycisk, napisz procedurę obsługi zdarzenia OnClick.
Komponenty. Grafika. Teksty.
Grafika w Delphi.
Są trzy sposoby tworzenia grafiki w Delphi: utworzenie go za pomocą komponentów graficznych w trybie projektu, wstawienie gotowego obrazu oraz tworzenie grafiki za pomocą kodu.
Komponenty graficzne.
Komponent Shape
Komponent Shape
Komponent Shape wyświetla na formularzy kształty takie jak prostokąt czy okrąg.
Rodzaj wyświetlanego kształtu określamy poprzez ustawienie właściwości Shape. Można tu wybrać wartości takie jak:
stEllipse (elipsa)
stRectangle (prostokąt),
stRoundRect (prostokąt z zaokrąglonymi rogami),
stRoundSquare (kwadrat z zaokrąglonymi rogami),
stSquare (kwadrat),
stCircle (okrąg).
Zmiana koloru komponentu
Zmianę koloru można uzyskać zmieniając właściwość Color. Jest ona dostępna po rozwinięciu właściwości Brush (należy dwukrotnie kliknąć na znak + z lewej strony). Jeśli chcemy wybrać dowolny kolor, a nie tylko dostępny na liście, należy dwukrotnie kliknąć z prawej strony właściwości Color. Otworzy się wówczas edytor koloru, który pozwolić wybrać dowolny kolor.
Color jest właściwością w obiekcie Brush, dlatego aby zmienić kolor komponentu w kodzie programu, należy podać najpierw nazwę komponentu, potem obiekt Brush, a na końcu właściwość Color, np.:
Shape1.Brush.Color:=clBlue;
Komponent Image.
Komponent Image, umieszczanie na nim rysunku
Komponent Image i jego właściwości
Komponent Paint Box
Komponent Image służy do wyświetlania bitmap, metaplików i ikon. Sam komponent jest niewidoczny. Nie tylko pozwala na wyświetlanie rysunków, ale również na ich tworzenie w kodzie programu.
Wstawianie rysunku
n Aby umieścić obrazek na formularzu:
1 Dodaj komponent Image i dwukrotnie na nim kliknij.
2 W oknie dialogowym Picture Editor kliknij przycisk Load..
3 W oknie dialogowym Load Picture zaznacz opcję bitmapa (.BMP), ikona (.ICO), lub Windows
Metafile (.WMF).
4 Wybierz obraz, który chcesz wstawić i kliknij OK. lub powtórz poprzednie kroki by wybrać inny obraz.
Zmiana rozmiaru obrazu
Obrazy wstawiane do komponentu są często zbyt małe lub zbyt duże w stosunku do komponentu. Można dopasować komponent do obrazu lub oraz do komponentu jedną z następujących metod:
Użyj Image editor, aby zmienić rozmiary obrazka przed jego umieszczeniem w formularzu.
Dopasuj rozmiar grafiki do rozmiaru komponentu ustawiając właściwość Stretch komponentu Image na True. Właściwość Stretch nie ma wpływu na rozmiar ikon (.ICO).
Zmień wielkość komponentu, aby dopasować go do grafiki ustawiając właściwość AutoSize na True zanim zostanie wstawiona grafika.
Aby wyśrodkować rysunek w komponencie, ustaw właściwość Center na True. Ustawienie tej właściwości na False powoduje, że grafika jest wyrównana do górnego lewego rogu komponentu.
Przesunięcie komponentu na wierzch lub pod spód
n Aby przesunąć komponent na wierzch lub pod spód wybierz Edit|Bring to Front lub Edit|Send to Back .
Wstawianie rysunku w kodzie programu
Jeśli zachodzi potrzeba wstawienia rysunku w kodzie programu, np. aby zmienić wyświetlany rysunek w odpowiedzi na działanie użytkownika, trzeba wykorzystać metodę LoadFromFile. Jest to metoda obiektu Picture, który wchodzi w skład komponentu TImage.
Image1.Picture.LoadFromFile(`Rysunki/obrazek1.bmp');
Tworzenie grafiki za pomocą kodu.
Pojęcie kanwy
Zmiana koloru pióra i pędzla
rysowanie linii prostych
Zdarzenie OnPaint
Sprawdzanie koloru piksela, zmiana koloru
Zmiana właściwości pióra i pędzla
Rysowanie figur geometrycznych na kanwie
Grafikę tworzymy w Delphi , rysując na kanwie obiektu (canvas), a nie bezpośrednio na danym obiekcie. Kanwa jest właściwością obiektu, jest również obiektem, ze swoimi właściwościami. Cztery najważniejsze to: pióro (pen) do rysowania linii, pędzel (brush) do wypełniania kształtów, czcionka (font) dla tworzenia tekstu i tablica pikseli do reprezentowania obrazów.
Kanwy są dostępne tylko za pomocą kodu programu.
Tworzenie grafiki w kodzie programu jest oparte na Windows Graphics Device Interface (GDI), dzięki Delphi jest jednak dużo prostsze niż tworzenie kodu bezpośrednio w Windows.
Różnica między rysowaniem a malowaniem
Rysowanie jest tworzeniem pojedynczego, graficznego elementu, takiego jak linia czy okrąg, w kodzie programu. W Delphi każemy obiektowi wyrysować określony obiekt graficzny w określonym miejscu kanwy, poprzez wywołanie odpowiedniej metody kanwy.
Malowanie jest tworzeniem wnętrza obiektu. Najczęściej Windows decyduje, że obiekt na ekranie powinien być odtworzony i generuje zdarzenie OnPaint. Zdarza się to, na przykład, gdy jest pokazywane dotąd schowane okno.
Zwykle malowanie pociąga za sobą rysowanie. W odpowiedzi na zdarzenie OnPaint. obiekt rysuje jaką grafikę. Na przykład pole tekstowe maluje się (paints itself) poprzez wyrysowanie prostokąta i wyrysowanie tekstu wewnątrz prostokąta. Komponent Shape maluje się za pomocą wyrysowania prostej grafiki.
Przykłady zawarte w tym rozdziale demonstrują, jak rysować różnorodną grafikę w odpowiedzi na zdarzenie OnPaint.
Wykorzystanie tablicy pikseli
Każda kanwa ma właściwość Pixels, która zwiera tablicę kolorowych punktów (pikseli) tworzących obraz na kanwie. Rzadko występuje potrzeba bezpośredniego dostępu do tej tablicy. Robimy to, gdy chcemy sprawdzić lub ustawić kolor określonego punktu. Pixels jest powierzchnią kanwy, na której można rysować, a pióro i pędzel są wygodnymi sposobami manipulowania grupami pikseli.
Manipulowanie pikselami
Można traktować piksele na kanwie jako dwuwymiarową tablicę, której każdy element przechowuje określony kolor.
Sprawdzanie koloru piksela
n Aby sprawdzić kolor określonego piksela, wykorzystaj właściwość kanwy Pixels i podaj współrzędne piksela. Lewy górny róg kanwy ma współrzędne 0, 0.
äPrzykład: następująca procedura obsługi kliknięcia na pole wyboru zmienia kolor tekstu w polu wyboru na kolor punktu na formularzu o współrzędnych (10, 10):
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
CheckBox1.Font.Color := Canvas.Pixels[10, 10];
end;
Ustawianie koloru piksela
n Aby ustawić kolor piksela przyporządkuj wartość koloru do właściwości kanwy Pixels, podając jego współrzędne.
Przykład: następująca procedura obsługuje zdarzenie kliknięcia na przycisk poprzez zmianę losowego punktu na formularzu na kolor czerwony.
procedure TForm1.Button1Click(Sender: TObject);
begin
Canvas.Pixels[Random(ClientWidth), Random(ClientHeight)] := clRed;
end;
Wykorzystanie pióra
Właściwość Pen kontroluje sposób tworzenia linii, w tym rysowanie krzywych i różnych kształtów.
Pióra ma swoje cztery właściwości, które można zmienić: Color, Width, Style i Mode.
Wartość tych właściwości określa sposób, w jaki jest rysowana linia. Domyślnie kolor linii jest czarny, jej szerokość ma 1 piksel, linia jest ciągła i jest rysowana w trybie zwanym copy (nakładanie) stara zawartość kanwy jest zastępowana nową.
Można te właściwości zmienić, określając kolor (Color), szerokość (Width - podajemy liczbę pikseli), styl (Style - linia ciągła, przerywana, kropkowana itd.), tryb rysowania (Mode).
Ustawianie pióra
Kanwa przechowuje bieżące położenie pióra - miejsce od którego będzie rysowana następna linia - we właściwości PenPos. Położenie pióra dotyczy tylko linii, nie dotyczy kształtów i tekstu.
n Aby zmienić położenie pióra, wywołaj metodę kanwy MoveTo.
ä Na przykład, aby przesunąć piór do lewego górnego rogu kanwy, wywołaj następującą instrukcję:
Canvas.MoveTo(0, 0);
Uwaga Metoda LineTo rysuje linię i przesuwa pióro na koniec rysowanej linii.
Zmiana właściwości pióra
Ustawić kolor możemy za pomocą stałych (np. clRed), np.
Canvas.Pen.Color:=clRed;
Dowolny kolor uzyskamy dzięki funkcji RGB. Ma ona trzy parametry, które przyjmują wartości od 0 do 255. Podają one stopień nasycenia koloru. Pierwszy parametr odpowiada za kolor czerwony, drugi za zielony, a trzeci za niebieski. RGB(0,0,0) to kolor czarny, a RGB(255,255,255) to kolor biały.
Canvas.Pen.Color:=RGB(255,0,0); // ustawia czerwony kolor
Canvas.Pen.Mode:=pmCopy; //standardowy tryb rysowania
Canvas.Pen.Style:=psDot; //linia kropkowana
Canvas.Pen.Width:=2; //linia o grubości dwóch pikseli
Wykorzystanie pędzla
Właściwość kanwy Brush kontroluje sposób wypełniania obszarów, w tym wnętrza kształtów. Pędzel ma trzy właściwości, które można zmieniać: Color, Style i Bitmap. Domyślnie pędzel jest biały, wypełnia obszar w sposób ciągły (jednolity) i nie ma bitmapy. Można ustawić kolor pędzla (Color), sposób łączenia koloru pędzla z kolorem kanwy (Style) oraz bitmapę reprezentującą wzór, którym będą wypełniane obszary na kanwie (Bitmap - 8 na 8 pikseli, przykład w pomocy).
Canvas.Brush.Color:=RGB(0,200,0); // ustawia zielony kolor
Canvas.Brush.Style:=bsCross; //wzór w kratkę
Zdarzenie OnPaint
Zdarzenie OnPaint zachodzi, gdy Windows decyduje, że formularz musi być przemalowany, np. gdy okno formularza jest zakryte przez inne okno, a następnie odkryte. Obsłuż zdarzenie OnPaint, jeśli tworzysz tło formularza lub gdy chcesz odnawiać obraz.
Jeśli instrukcje rysujące na kanwie znajdują się w procedurze obsługi zdarzenia OnPaint, to mamy pewność, że po zasłonięciu grafiki, np. przez inne okno, a następnie odsłonięciu, grafika zostanie prawidłowo odtworzona.
Rysowanie linii prostych i łamanych
Kanwa może rysować dwa rodzaje linii: linie proste i łamane. Są one rysowane za pomocą pióra.
Rysowanie linii prostych
n Aby narysować prostą linię na kanwie, użyj metody LineTo. Metoda ta rysuje linię od bieżącego położenia pióra do punktu określonego przez parametry. Pióro jest przesuwane na koniec linii. Linia jest rysowana za pomocą pióra.
ä Przykład: metoda rysująca przekątne linie na formularzu, za każdym razem, gdy formularz jest malowany:
procedure TForm1.FormPaint(Sender: TObject);
begin
with Canvas do
begin
MoveTo(0, 0);
LineTo(ClientWidth, ClientHeight);
MoveTo(0, ClientHeight);
LineTo(ClientWidth, 0);
end;
end;
Rysowanie łamanych
Kanwa potrafi również rysować łamane, które są zbiorem dowolnej liczby połączonych odcinków (prostych).
n Aby narysować linię łamaną na kanwie, użyj metody kanwy PolyLine. Parametrem tej metody jest tablica punktów. Odpowiada wywołaniu metody MoveTo dla pierwszego punktu i następnie metody LineTo dla każdego kolejnego punktu.
ä Przykład: metoda rysująca na formularzu romb:
procedure TForm1.FormPaint(Sender: TObject);
begin
with Canvas do
PolyLine([Point(0, 0), Point(50, 0), Point(75, 50), Point(25, 50), Point(0, 0)]);
end;
W tym przykładzie jest wykorzystana zaawansowana możliwość Delphi: tworzenie parametru “on
the fly.” (nieograniczonej tabeli). Możesz przekazać dowolną tablicę punktów, ale najprostszym sposobem jest umieszczenie elementów tablicy w kwadratowych nawiasach i przekazanie całości jako parametr.
Rysowanie kształtów
Kanwy mają metody do rysowanie czterech rodzajów kształtów. Ich brzegi są rysowane piórem, a wnętrz są wypełniane (malowane) pędzlem.
Rysowanie prostokątów i elips
n Aby narysować na kanwie prostokąt lub elipsę, wywołaj metodę Rectangle lub Ellipse, przekazując jako parametry współrzędne prostokąta lub prostokąta opisanego na elipsie.
äPrzykład: metoda rysująca prostokąt, wypełniający górną lewą ćwiartkę formularza, a następnie rysuje w tym samym obszarze elipsę:
procedure TForm1.FormPaint(Sender: TObject);
begin
Canvas.Rectangle(0, 0, ClientWidth div 2, ClientHeight div 2);
Canvas.Ellipse(0, 0, ClientWidth div 2, ClientHeight div 2);
end;
Rysowanie zaokrąglonych prostokątów
Do rysowania prostokątów o zaokrąglonych kątach używamy metody kanwy RoundRect. Jej pierwsze cztery parametry opisują prostokąt opisany na zaokrąglonym prostokącie. Ostatnie dwa określają, jak mają być zaokrąglone kąty.
ä Przykład: poniższa metoda rysuje prostokąt wypełniający górną lewą ćwiartkę formularza. Zaokrąglone kąty są wycinkiem koła o promieniu 10 pikseli:
procedure TForm1.FormPaint(Sender: TObject);
begin
Canvas.RoundRect(0, 0, ClientWidth div 2, ClientHeight div 2, 10, 10);
end;
Rysowanie wielokątów
n Aby narysować na kanwie wielokąt o dowolnej liczbie boków, wywołaj metodę kanwy Polygon. Jej parametrem jest tablica punktów. Te punkty są kolejno łączone liniami, dodatkowo pierwszy punkt jest łączony z ostatnim. Następnie wnętrze wielokąta jest wypełniane pędzlem (zgodnie z jego aktualnymi ustawieniami).
ä Przykład: poniższa metoda rysuje trójkąt prostokątny w dolnej, lewej połowie formularza:
procedure TForm1.FormPaint(Sender: TObject);
begin
Canvas.Polygon([Point(0, 0), Point(0, ClientHeight), Point(ClientWidth, ClientHeight)]);
end;
Rysowanie innych elementów graficznych
Dodatkowo kanwa umożliwia rysowanie takich elementów jak: wycinek koła, wypełniony wycinek. Dodatkowo można wypełniać obszary i prostokąty oraz kopiować obrazy z innych kanw. O szczegółach można przeczytać w pomocy (komponent TCanvas).
Komponenty posiadające kanwę
Nie tylko formularz posiada kanwę. Posiada ją również komponent TImage oraz komponent TPaintBox
Jeśli chcemy mieć pewność, że rysowana grafika nie wykroczy poza określony obszar, to zamiast na formularzu rysujmy na kanwie komponentu TPaintBox.
PaintBox.Canvas.LineTo(100,100); // rysuje linię na kanwie komponentu TPaintBox.
Praca z plikami graficznymi.
Ładowanie do komponentu Image zawartości pliku graficznego
Zachowywanie w pliku zawartości komponentu Image
Drukowanie zawartości komponentu Image
Ładowanie do komponentu Image zawartości pliku graficznego
Jeśli zachodzi potrzeba wstawienia rysunku w kodzie programu, np. aby zmienić wyświetlany rysunek w odpowiedzi na działanie użytkownika, trzeba wykorzystać metodę LoadFromFile. Jest to metoda obiektu Picture, który wchodzi w skład komponentu TImage.
Image1.Picture.LoadFromFile(`Rysunki/obrazek1.bmp');
Zachowywanie grafiki w pliku
n Aby zachować zawartość komponentu Image w pliku, wywołaj metodę SaveToFile, która jest metodą obiektu Picture, należącego do tego komponentu.
Metoda SaveToFile wymaga nazwy pliku, w którym ma być zachowana grafika.
Image.Picture.SaveToFile(`własna.bmp')
Drukowanie grafiki
Drukowanie obrazów graficznych jest w Delphi bardzo prostym zadaniem. Trzeba tylko zadeklarować w module formularza użycie modułu Printers. W tym module jest zadeklarowany obiekt Printer, który zawiera kanwę, reprezentującą drukowany obszar.
n Aby wydrukować obraz graficzny, przekopiuj go na kanwę obiektu Printer. Możesz używać tej kanwy tak samo jak innych kanw. W szczególności, możesz kopiować zawartość obiektów takich jak bitmapy bezpośrednio na drukarkę.
ä W tym przykładzie, jako reakcję na zdarzenie kliknięcia na polecenie Print, będziemy drukować zawartość komponentu Image:
procedure TForm1.Print1Click(Sender: TObject);
begin
with Printer do
begin
BeginDoc; { rozpocznij drukowanie }
Canvas.Draw(0, 0, Image.Picture.Graphic); { rysuj grafikę w lewym górnym rogu strony }
EndDoc; { zakończ drukowanie}
end;
end;
Opis wybranych komponentów
Używanie komponentu MaskEdit
Powiększanie powierzchni formularza za pomocą komponentu Page Control
Umieszczanie w aplikacji paska stanu
Poprawa wyglądu formularza poprzez zastosowanie komponentu Bevel
Tworzenie obszaru, który można przewijać za pomocą pasków przewijania (ScrollBox)
Zastosowanie komponentu Timer
Komponenty na stronie Windows 95
Wizualny |
Nazwa komponentu |
Zastosowanie |
|
TabControl |
Tworzy zakładki, dzięki którym formularz ma wygląd formularza ze stronami, między którymi możemy przełączać się za pomocą tych zakładek. Często używany z komponentem PageControl |
|
PageControl |
Tworzy stos stron (multiple pages). Często używany z komponentem TabControl. |
|
TreeView |
Komponent, który pozwala na wyświetlanie listy obiektów w postaci drzewa, którego poszczególne elementy można rozwijać lub zwijać. |
|
ListView |
Komponent, który wyświetla elementy w postaci listy, może je wyświetlać na różne sposoby (np. duże ikony, małe ikony, lista).
|
|
ImageList |
Tworzy kolekcję obrazów (bitmap) tego samego rozmiaru, do których możemy odwołać się poprzez ich indeks. Używamy go do efektywnego zarządzania dużą ilością bitmap. Może też zawierać bitmapę z maską, która służy do wyświetlania w transparentnym stylu (ikony). |
|
HeaderControl |
Jest podzielonym na sekcje komponentem, który wyświetla tekst. Rozmiary każdej części można zmieniać za pomocą myszki. |
|
RichEdit |
Pole podobne do memo, ma wbudowane szereg możliwości np. przeciąganie i upuszczanie tekstu za pomocą myszki. |
|
StatusBar |
Służy do utworzenia paska statusu.
|
|
TrackBar |
Pasek, który wskazuje na wartość jakiej zmiennej i umożliwia jej zmianę za pomocą suwaka. |
|
ProgressBar |
Pasek, który używamy na wskazanie postępu jakiejś czynności np. instalowania. |
Tak |
UpDown |
Strzałki, które ułatwiają zmianę jakieś wartości (zwiększanie lub zmniejszanie o 1). |
|
HotKey |
Komponent, który umożliwia dodanie klawisza szybkiego dostępu do dowolnego innego komponentu. |
MaskEdit
Jest to komponent Edit rozbudowany o możliwość kontroli wprowadzanych przez użytkownika tekstów (maska wprowadzania). Maskę wprowadzamy obok właściwości MaskEdit. Można skorzystać z pomocy Edytora maski wprowadzania (dwukrotnie kliknąć obok właściwości MaskEdit). Do tworzenia maski wykorzystujemy specjalne symbole:
Znak |
Znaczenie |
> |
Tekst po tym znaku jest zamieniany na duże litery |
< |
Tekst po tym znaku jest zamieniany na małe litery |
<> |
Tekst po tym znaku nie jest zamieniany ani na duże, ani na małe litery |
\ |
Następny znak po tym pojawi się w masce. Używamy \ gdy chcemy w masce umieścić np. - |
L |
Wymagana litera |
l |
Litera, ale wprowadzanie nie jest wymagane. |
A |
Litera lub cyfra, wprowadzenie wymagane. |
a |
Litera lub cyfra, wprowadzenie nie jest wymagane. |
C |
Dowolny znak, wprowadzenie wymagane |
c |
Dowolny znak, ale wprowadzenie nie jest wymagane. |
0 |
Cyfra, wprowadzenie wymagane |
9 |
Cyfra, wprowadzenie nie jest wymagane |
# |
Cyfra, znak + lub - , wprowadzenie nie jest wymagane. |
: |
Znak używany do oddzielania godzin od minut, minut od sekund . Znak ten jest wyświetlany w masce w takiej postaci jak jest to określane w ustawieniach międzynarodowych na danym komputerze. |
/ |
Znak używany do oddzielania lat od miesięcy, miesięcy od dni w dacie. Znak ten jest wyświetlany w masce w takiej postaci jak jest to określane w ustawieniach międzynarodowych na danym komputerze. |
ä Przykładowe maski
00/00/99 // Data
>LL 0000000 //mumer dowodu osobistego
PageControl
Komponent ten jest wykorzystywany najczęściej do wyświetlania wielostronicowego okna dialogowe. Użytkownik wybiera odpowiednią stronę klikając na zakładkę.
Aby utworzyć nową stronę w komponencie TPageControl w trybie projektu, kliknij prawym klawiszem myszki na tym komponencie (otworzy się menu podręczne) i wybierz New Page. Każda storna jest komponentem TTabSheet.. Aby przejść do określonej strony, wystarczy na nią kliknąć. W kodzie programu możemy to zrobić poprzez ustawienie właściwości ActivePage.
Właściwość PageIndex komponentu TabSheet zawiera indeks strony w komponencie PageControl.
Domyślnie PageControl wyświetla tylko jeden rząd zakładek. Ustawiając właściwość MultiLine sprawimy, ze w razie potrzeby zakładki będą wyświetlane w kilku rzędach.
StatusBar
Pasek stanu. Jest umieszczony na dole okna i służy do wyświetlania informacji o aplikacji. Może wyświetlać pojedynczą informację w jednym panelu lub klika informacji w kilku panelach.
Właściwość Panels zawiera zbiór paneli (typu TStatusPanels) z których każdy ma oddzielne właściwości Text, Width, Style, Bevel i Alignment (wyrównanie tekstu - do lewej, prawej lub wyśrodkowanie) . W trybie projektu ustawiamy te właściwości w edytorze paneli paska stanu. Otwieramy go dwukrotnie klikając obok właściwości Panels. Liczba paneli w pasku stanu jest zawarta we właściwości Count . Aby uzyskać dostęp w kodzie programu do właściwości poszczególnych paneli, należy użyć właściwość Items właściwości Panels.
Panels.Items[1].Text := `Poszukiwanie...';
Bevel
Pozwala na umieszczenie na formularzu linii, prostokątów lub ramek. O kształcie wyświetlanego komponentu decyduje właściwość Shape. Właściwość Style określa czy komponent jest wypukły czy wklęsły.
ScrollBox
Komponent ten tworzy obszar, który można przewijać (dodane są dwa paski przewijania). Umieszczamy na nim inne komponenty. Tworzy to obszar, mniejszy od formularza, który można przewijać. Jest to przydatne, gdy mamy na formularzu pasek narzędzi (zwykle wyrównany do góry) i pasek stanu (wyrównany do dołu). Podczas przewijania formularza zostaną one schowane. Będziemy mieli pewność, że tak nie będzie, gdy pozostałe komponenty umieścimy na komponencie TScrollBox, który zostanie rozciągnięty na cały dostępny obszar (właściwość Align ustawiona na alClient).
Zachowanie pasków przewijania możemy określić poprzez zmianę ich właściwości (zmieniamy właściwości HorzScrollBar - pasek poziomy i VertScrollBar - pasek pionowy).
Jeśli chemy,aby obszar się przewinął ukazując określony element, powinnyśmy użyć metody ScrollInView. Jako jej parametr podajemy komponent, który ma zostać pokazany.
ä Umieść na formularzu panel. Ustaw jego wyrównanie (Align) na alTop. Teraz dodaj do formularza ScrollBox. Rozciągnij go na cały dostępny obszar (Align ustaw na alClient). Umieść na nim dwa przyciski w dwóch końcach, tak, aby nie były widoczne oba na raz. Utwórz teraz dla nich procedury obsługi zdarzenia. Ich zadanie będzie przewinięcie obszaru tak, aby pokazał się drugi element.
procedure TForm1.Button1Click(Sender: TObject);
begin
ScrollBox1.ScrollInView(Button2); // zostanie pokazany przycisk Button2
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ScrollBox1.ScrollInView(Button1); // zostanie pokazany przycisk Button1
end;
Timer
Komponent ten wywołuje zdarzenie OnTimer za każdym razem, gdy minie czas określony przez właściwość Interval. Czas określamy podając ilość milisekund. Domyślnie we właściwości Interval jest wpisana wartość 1000 (jedna sekunda).
ä Utwórz projekt, w którym po formularzu będzie się powoli przesuwało kółko. W tym celu umieść na formularzu komponent TTimer i obsłuż jego zdarzenie OnTimer:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Interval := 100;
Shape1.Shape := stCircle;
Shape1.Left := Shape1.Left + 1;
end;
Wykorzystanie typowych okien dialogowych.
Dodanie do formularza komponentu okna dialogowego
Metoda Execute komponentów okien dialogowych
Określanie wybranych właściwości komponentów okien dialogowych (np. Filter)
Praktyczne wykorzystanie komponentów okien dialogowych do otwierania plików, zachowywania plików, zmiany czcionki, wydruku
Komponenty na stronie Dialogs
Wyświetlają okna dialogowe wspólne dla środowiska Windows. Aby wyświetlić okno dialogowe należy umieścić na formularzu odpowiedni komponent, a następnie w odpowiednim miejscu w kodzie programu wywołać dla tego komponentu metodę Execute.
Każde okno dialogowe jest otwierane poprzez wywołanie jego metody Execute. Metoda Execute zwraca wartość logiczną: jeśli użytkownik wybierze OK , akceptując zmiany dokonane w oknie dialogowym, zwraca True; jeśli użytkownik wybierze Cancel, metoda zwraca wartość False.
Wizualny |
Nazwa komponentu |
Zastosowanie |
|
OpenDialog |
Okno służące do otwierania pliku.
|
|
SaveDialog |
Okno dialogowe do zachowywania pliku.
|
|
FontDialog |
Okno do zmiany atrybutów czcionki.
|
|
ColorDialog |
Okno służące do zmiany koloru (z możliwością zdefiniowania własnego dowolnego koloru). |
|
PrintDialog |
Otwiera okno służące do drukowania zawartości pliku.
|
|
PrinterSetupDialog |
Okno dialogowe służące do zmiany ustawień drukarki (np. jakość wydruku) |
|
FindDialog |
Tworzy okno służące do wyszukiwania podanego tekstu
|
|
ReplaceDialog |
Tworzy okno Zamień, w którym podajemy szukany tekst i tekst, na który ma być zmieniony odnaleziony tekst. |
Opcje typowych okien dialogowych
W Delphi każde okno dialogowe (za wyjątkiem okna Printer Setup) zawierają właściwość Options. Dostępne opcję są dostępne jako zagnieżdżone właściwości pod tą właściwością.
Określenie typu plików (filtrów)
Występuje w oknach dialogowych OpenDialog i SaveDialog.
Pole tekstowe Pliki typu (List Files Of Type) wyświetla listę dostępnych rodzajów (typów plików). W polu listy są wyświetlane tylko pliki o wybranym rodzaju (typie), znajdujące się w wybranym katalogu. Wybór typu pliku odbywa się na podstawie jego rozszerzenia. te rozszerzenia plików zwane są filtrami. Aby stworzyć taką listę filtrów (czyli dostępnych rozszerzeń), ustawiamy właściwość Filters.
n Aby określić filtry:
1 W Inspektorze obiektów, dwukrotnie kliknij obok właściwości Filter (lub kliknij na przycisk ...).
2 Określ nazwę filtru (na przykład “Text”) i związane z nim rozszerzenie (na przykład “*.TXT”).
Uwaga Kolejność wprowadzanych filtrów jest zgodna z kolejnością w jakiej się ukażą na liście Pliki typu (List Files Of Type).
Wykorzystanie komponentu OpenDialog
Komponent ten umożliwia wykorzystanie w aplikacji okna dialogowego Otwórz plik. Samo dodanie komponentu nie powoduje wyświetlenie okna dialogowego. W tym celu trzeba wywołać metodę Execute.
Jeśli użytkownik w oknie dialogowym wybierze przycisk OK, to wybrany przez niego plik (dokładniej - jego nazwa) jest przechowywany we właściwości FileName komponentu OpenDialog.
Można określić rodzaj wyświetlanych w oknie plików poprzez ustawienie właściwości Filter. Domyślny rodzaj filtru określamy poprzez użycie właściwości FilterIndex. Jeśli chcemy, aby rozszerzenie było automatycznie dopisywane do nazwy pliku znajdującej się w polu Nazwa pliku , należy te rozszerzenie wpisać do właściwości DefaultExt .
ä Następująca procedurę obsługi kliknięcia dla polecenia Plik|Otwórz ładuje do komponentu Image plik wybrany przez użytkownika w oknie dialogowym Otwórz Plik.
procedure TForm1.Otworz1Click(Sender: TObject);
begin
if OpenDialog1.Execute then // Otwiera okno dialogowe, jeśli użytkownik wybrał OK, Execute zwraca True
begin
NazwaPliku := OpenDialog1.FileName; //zachowuje nazwę pliku w polu obiektu formularza
Image.Picture.LoadFromFile(NazwaPliku); //ładue do Image wybrany plik
end;
end;
Wykorzystanie komponentu SaveDialog
Właściwości komponentu SaveDialog są identyczne jak komponentu OpenDialog. Jeden jest używany do zapisywania plików, drugi do otwierania plików.
ä Następująca procedurę obsługi kliknięcia dla polecenia Plik|Zachowaj zachowuje obraz z komponentu Image w pliku wybranym przez użytkownika w oknie dialogowym Zachowaj Plik.
procedure TForm1.Zachowaj1Click(Sender: TObject);
begin
if SaveDialog1.Execute then
begin { pobierz z okna dialogowego nazwę pliku }
CurrentFile := SaveDialog1.FileName; { zachowaj w polu wybraną przez właściciela nazwę pliku }
Image.Picture.SaveToFile(CurrentFile) { zachowaj obraz pod wybraną przez użytkownika nazwą}
end;
end;
Komponent okna dialogowego Czcionka
Komponent TFontDialog pozwala na dodanie do aplikacji okna dialogowego, w którym będzie możliwa zmiana czcionki. Jeśli użytkownik kliknie na OK, to wybrana przez niego czcionka i jej atrybuty zostanie przechowana we właściowości Font.
ä Następująca procedura obsługi zmienia czcionkę (Font) w komponencie Memo na czcionkę wybraną w oknie dilogowym Czcionka:
procedure TEditForm.Czcionka1Click(Sender: TObject);
begin
FontDialog1.Font := Memo1.Font;
if FontDialog1.Execute then
Memo1.Font := FontDialog1.Font;
end;
Wykorzystanie okien dialogowych drukarki
Komponent PrintDialog służy do wyświetlenia okna dialogowego Drukuj. Kliknięcie na przycisk Właściwości spowoduje wyświetlenie okna dialogowego ustawień drukarki (nie trzeba dodawać komponentu PrionSetup).
Ustawienia w tym oknie dialogowym , podobnie jak i w innych, są zapisywane i czytane z pliku WIN.INI (za pomocą funkcji Windows) - na tym polega tajemnica tego, że w angielskim Delphi pojawia się okno dialogowe po Polsku.
Właściwości komponentu okna dialogowego Print
Właściwości tego komponentu odpowiadają poszczególnym obszarom okna dialogowego Print. Zwykle nie ma potrzeby zmiany domyślnych wartości tych właściwości w trybie projektu. Warto jednak przyjrzeć się kilku opcjom.
MinPage / MaxPage
Te ustawienia określają górny lub dolny limit numeru strony, który użytkownik może określić w pole tekstowym Strony od: i Do:. Te ustawienia nie mają wpływu na wyświetlane wartości w oknie dialogowym. Jeśli jednak użytkownik wybierze wartość spoza zakresu, to kliknięciu na OK zostanie wyświetlony komunikat o błędzie.
Options | poPageNums
Wartość True włącza opcje Strony od: i Do: , więc użytkownik może określić zakres strony do wydruku. Na przykład można ją ustawić na True, gdy dokument ma więcej niż dwie strony.
Options | poPrintToFile
Wartość True dodaje do okna dialogowego pole wyboru Drukuj do pliku. (Należy wtedy utworzyć kod, który umożliwi drukowanie do pliku)
Options | poSelection
Wartość True włącza przycisk opcji Zaznaczony fragment, jego wybór powoduje drukowanie zaznaczonego tekstu. Można ją ustawiać w zależności od tego, czy w tekście jest zaznaczony tekst.
PrintRange
Ustawienia tej właściwości określają domyślną wartość w obszarze Zakres wydruku. Na przykład ustawienie PrintRange = prPageNums powoduje, że jest wybrana opcja Strony, zamiast domyślnej (ustawienie AllPages). Wybranie opcji, która nie jest domyślna, powoduje konieczność ustawienia odpowiedniej opcji grupy Options na wartość True. Na przykład, jeśli ustawisz PrintRange na prSelection , to trzeba też ustawić Options|Selection na True.
Dźwięk i multimedia.
Komponent MediaPlayer
odtwarzanie plików dźwiękowych za pomocą funkcji PlaySound
Komponent MediaPlayer i sterowanie jego funkcjami z kodu programu
Funkcja PlaySound
Funkcja PlaySound odtwarza pliki w formacie .WAV.
PlaySound(`C:\Windows\MEDIA\The Microsoft Sound.WAV', 0, SND_SYNC);
Pierwszy parametr funkcji to ścieżka do pliku, który ma być odtworzony.
Drugi ma znaczenie, gdy odtwarzany plik ładujemy do pamięci, jeśli jest odtwarzany z pliku, to wpisujemy 0.
Trzeci określa opcje związane z odtwarzaniem pliku, np.:
SND_SYNC dźwięk jest odtwarzany synchroniczne - aplikacja jest zatrzymana do momentu odtworzenia pliku
SND_ASYNC dźwięk jest odtwarzany asynchronicznie - dźwięk jest odtwarzany równolegle z działającym programem
SND_LOOP dźwięk jest powtarzany ciągle aż do ponownego wywołania funkcji PlaySound
Jeśli chcemy wybrać kilka opcji. łączymy je za pomocą operatora or.
PlaySound(`C:\Windows\MEDIA\The Microsoft Sound.WAV', 0, SND_ASYNC or SND_LOOP);
Aby przerwać odtwarzanie dźwięku, wywołaj PlaySound z pierwszym parametrem ustawionym na NULL, a trzecim na AND_ASYNC.
Komponent MediaPlayer
Prezentowany jest jako pasek przycisków znany z magnetofonu lub magnetowidu umożliwiających kompleksowe zarządzanie multimediami. Pozwala na odtworzenie plików w formacie .WAV, .MID, .AVI.
Przycisk Open pozwala wczytać plik multimedialny. Play, Pause, Stop działają jak w klasycznym magnetowidzie. Next i Previous sterują przełączaniem ścieżek (na przykład utworów na płycie kompaktowej). Jeśli dla danego urządzenia nie istnieje pojęcie ścieżki (tak jak w naszym przypadku), metody te odpowiednio "przewijają" plik na koniec lub początek. Step i Back umożliwiają poruszanie się po multimedium klatka po klatce (frame) a StartRecording rozpoczyna nagrywanie. Niezależnie od tego, MediaPlayer dysponuje szeregiem metod nawiązujących do poszczególnych przycisków, których efekt działania jest taki sam. Może być zatem sterowany z poziomu programu. Dodatkowa metoda Save powoduje zapisanie aktualnie otwartego pliku pod nazwą podaną we właściwości FileName.
Umieszczenie w programie instrukcji przywołujących metody Play i Close bezpośrednio po sobie zaowocuje natychmiastowym przerwaniem odtwarzania. Przeciwdziała temu właściwość Wait ustawiona na wartość True:
MediaPlayer.Wait := True;
MediaPlayer.Open;
MediaPlayer.Play;
MediaPlayer.Close;
Inna właściwość, która może okazać się pomocna, to AutoOpen. Gdy jest ustawiona na True, każda zmiana FileName komponentu powoduje automatyczne wywołanie metody Open, czyli otworzenie pliku. Jeszcze inna właściwość-- Capabilities pozwala sprawdzić, co może w danej chwili sterownik. Możemy zatem "zapytać", czy jest możliwa operacja "eject", czy aktualnie otwarty plik można odegrać, czy można nagrywać i tym podobne.
Istnieją także właściwości Error i ErrorMessage, odpowiedzialne za informowanie programu, a tym samym, pośrednio, użytkownika naszej aplikacji o błędach zaistniałych podczas funkcjonowania komponentu multimedialnego.
Wyświetlenie komponentu MediaPlayer
Z komponentu Media Player możemy korzystać na dwa sposoby. Pierwszy pozwala użytkownikowi na manipulowanie przyciskami "Play'', "Stop", "Record" czy .,Rewind''. Drugi sposób polega na tym, że komponentu nie wyświetlamy (cecha Visible = False) i sterujemy nim z poziomu programu, używając odpowiednich metod.
ä Utwórzmy prostą aplikację, która pozwoli użytkownikowi wybrać dowolny plik typu WAV, MIDI czy .AVI i odtworzyć go za pomocą panelu Media Player. Potrzebujemy trzech obiektów: TMainMenu, TOpenDialog i oczywiście TMediaPlayer. Wszystkie wstawiamy do formularza. Do menu (TMainMenu) dodajemy polecenie Plik|Otwórz. Procedura obsługi kliknięcia na tym poleceniu jest następująca:
procedure TForm2.Open1Click(Sender: T0bject);
begin
if OpenDialog1.Execute then
begin
{ ustalamy nazwę pliku }
MediaPlayer1.FileName . OpenDialog1.FileName;
{ otwieramy plik }
MediaPlayer1.open;
end;
end;
W ten sposób stworzyliśmy działającą aplikację do odtwarzania plików muitimedialnych.
Możemy zmienić sposób działania komponentu Media Player przez odpowiednie ustawienie jego wybranych właściwości. Na przykład, gdy odtwarzamy plik AVI, otwiera się w tym celu osobne okienko. Możemy to zmienić poprzez zmianę właściwości Display. Decyduje ona o miejscu, w którym film video ma być wyświetlany. Własność Display może zawierać dowolny wizualny komponent wywodzący się z klasy TWinComponent. Istnieje również właściwość DisplayRect. która określa obszar okienka, w którym wyświetlany będzie obraz.
Własność DisplayRect może być nieco myląca. Ponieważ przypisujemy jej wartość typu TRect, może wydawać się, że chodzi o współrzędne lewego górnego i prawego dolnego wierzchołka obszaru wyświetlania. W rzeczywistości jest inaczej, trzeci i czwarty parametr to szerokość i wysokość tego obszaru. Tak więc zapis:
MediaPlayer1.Display := Form1;
MediaPlayer1.DisplayRect := Rect(10,10,200,200);
oznacza, że dla obiektu Media Player przeznaczamy wycinek formularza wyznaczony przez punkty o współrzędnych 10, 10 oraz 210, 210 (a nie 10, 10, 200, 200).
Metody komponentu Media Player
Czasami będziemy chcieli skorzystać w naszych aplikacjach z możliwości, jakie niosą multimedia, ale bez udostępniania użytkownikowi funkcji komponentu Media Player. Ustawiamy wtedy jego cechę Visible na False, a obsługę realizujemy z wnętrza programu za pomocą odpowiednich metod. Metody te odpowiadają wszystkim czynnościom, które można wykonać za pomocą panelu. Jest też wiele funkcji z poziomu użytkownika niedostępnych. Jedną z poznanych już, niedostępnych dla użytkownika, jest metoda Open.
ä Utwórzmy aplikację, która będzie wyświetlała filmy informacyjne o wybranych trzech ptakach. Dodaj do formularza trzy przyciski opcji (najlepiej umieścić je na komponencie GroupBox). Podpisz je: „Kukułka”, „Wróbel”, „Bocian”. Umieść panel (o nazwie Ekran), na którym będą wyświetlane filmy. Dodaj przycisk Info, podpisany :”Wyświetl film”. Kliknięcie na nim spowoduje wyświetlenie filmu:
procedure TForm1.InfoClick(Sender: TObject);
begin
if RadioButtonl.Checked then
MediaPlayerl.FileName := 'Kukułka.AVI':
if RadioButton2.Checked then
MediaPlayerl.FileName := 'Wróbel.AVI';
if RadioButton3.Checked then
MediaPlayerl.FileName := 'Bocian.AVI';
MediaPlayerl.Open;
MediaPlayer1.DisplayRect := Rect(0 0, Ekran.Width,Ekran.Height);
MediaPlayer1.Play;
end;
Przy tworzeniu formularza przypisujemy panel do właściwości Display komponentu MediaPlayer. W ten sposób zapewnimy, że filmy będą odtwarzane na panelu.
procedure TForm1.FormCreate(Sender: TObject);
begin
MediaPlayer1.Display := Ekran;
end;
Prawie cały program koncentruje się wokół procedury obsługi zdarzenia OnClick przycisku Info. Kiedy użytkownik go użyje, aplikacja sprawdza, które pole opcji jest aktualnie włączone. Na podstawie tego otwierany jest odpowiedni plik typu AVI. Po otwarciu (metoda Open) plik jest od razu odtwarzany, używamy do tego metody Play.
Przeciąganie elementów za pomocą myszki.
Zdarzenia myszki :wciśnięcie, zwolnienie klawisza oraz przesunięcie myszki
Przeciąganie elementów za pomocą myszki
Co to jest zdarzenie myszki?
W Delphi zostały zdefiniowane trzy zdarzenia myszki: OnMouseDown, OnMouseMove i OnMouseUp. Kiedy aplikacja wykryje zdarzenie myszki, wykonywana jest procedura obsługi odpowiedniego zdarzenia, przy czym do tej procedury jest przekazywane pięć parametrów. Można je wykorzystać przy tworzeniu obsługi tego zdarzenia. Te parametry to:
Parametr |
Znaczenie |
Sender |
Obiekt, który wykrył akcję myszki |
Button |
Określa, który przycisk myszki bierze udział w akcji: mbLeft, mbMiddle lub mbRight |
Shift |
Określa stan klawiszy Alt, Ctrl i Shift podczas akcji myszki |
X, Y |
Współrzędne miejsca, gdzie wystąpiło zdarzenie myszki |
Uwaga Do określania, który klawisz myszki został wciśnięty, Delphi używa tych samych kryteriów co Windows. Jeśli więc zostaną zamieniane klawisze myszki (myszka dla leworęcznych), to wciśnięcie prawego klawisza myszki zostanie rozpoznane jako wciśnięcie lewego klawisza myszki (mbLeft).
Odpowiedź na wciśnięcie klawisza myszki
Jeśli użytkownik wciśnięcie myszkę, to zostanie wywołane zdarzenie OnMouseDown dla obiektu, nad którym znajduje się wskaźnik myszki. Na przykład, jeśli wskaźnik myszki wskazuje na formularz, to przy wciśnięciu klawisza myszki zostanie wywołane zdarzenie OnMouseDown dla formularza.
n Aby obsłużyć akcję wciśnięcia klawisza myszki, przyporządkuj procedurę obsługi zdarzenia dla zdarzenia OnMouseDown. Delphi wygeneruje następującą domyślną procedurę obsługi zdarzenia:
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
end;
ä Aby przećwiczyć obsługę myszki, wypróbuj wypisywania tekstu w miejscu kliknięcia myszką. W procedurze zostanie min. wykorzystana metoda TextOut , która wypisuje teksty na kanwie:
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
Canvas.TextOut(X, Y, `Tutaj!'); { wypisuje tekst w punkcie o współrzędnych (X, Y) }
end;
Uruchom aplikację. Po kliknięciu myszką na formularz, pojawia się w miejscu kliknięcia tekst Here.
Jeszcze nie możemy rysować linii. Wciśnięcie klawisza myszki podaje tylko punkt początkowy rysowanej linii. Do narysowania linii potrzebny jest jeszcze punkt końcowy.
ä Zmień procedurę obsługi zdarzenia wciśnięcia klawisza myszki, tak, aby pióro zostało ustawione w miejscu wciśnięcia klawisza myszki:
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
Canvas.MoveTo(X, Y); { ustawia pióro na nowej pozycji }
end;
Teraz wystarczy ustalić punkt końcowy linii. W tym celu trzeba obsłużyć zdarzenie zwolnienia klawisza myszki.
Odpowiedź na zwolnienie klawisza myszki
Zwolnieni klawisza myszki wywołuje zdarzenie OnMouseUp, które dotyczy obiektu, nad którym klawisz myszki został wciśnięty, a więc nie musi dotyczyć obiektu, nad którym myszka została zwolniona. Dzięki temu można np. narysować linię, której koniec jest poza formularzem.
n Aby obsłużyć akcję zwolnienia klawisza myszki, zdefiniuj procedurę obsługo zdarzenia OnMouseUp.
ä Narysuj linię do miejsca na formularzu, gdzie został zwolniony klawisz myszki. Prosta procedura, która to realizuje, może wyglądać tak:
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
Canvas.LineTo(X, Y); { narysuj linię od położenia pióra do punktu (X, Y) }
end;
Po uruchomieniu aplikacji, można rysować linie poprzez kliknięcie, przeciągnięcie i zwolnienie klawisza myszki. Niestety, dopóki klawisz nie zostanie zwolniony, nie widać rysowanej linii. Można rozwiązać ten problem za pomocą tymczasowych linii rysowanych podczas ruchu myszki.
Odpowiedź na ruch myszki
Zdarzenie OnMouseMove występuje cyklicznie podczas ruchu myszki. Zdarzenie to jest zdarzeniem obiektu, który wskazywała myszka, gdy został wciśnięty jej klawisz.
n Aby odpowiedzieć na przesuwanie się myszki, zdefiniuj procedurę obsługi zdarzenia OnMouseMove.
ä W tej aplikacji zdarzenie ruchu myszki zostanie wykorzystane do rysowania tymczasowych kształtów. Oto prosta procedura obsługi zdarzenia formularza OnMouseMove, która rysuje linie od położenia pióra do miejsca, gdzie wystąpiło zdarzenie OnMouseMove:
procedure TForm1.FormMouseMove(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
Canvas.LineTo(X, Y); { rysuje linię do bieżącego położenia myszki }
end;
Po uruchomieniu aplikacji zauważysz, że ruch myszki powoduje rysowanie linii, nawet jeśli nie został jeszcze wciśnięty klawisz myszki. Musimy dodać kod, który wykona obsługę zdarzenia ruchu myszki (narysuje tymczasową linię) tylko wtedy, gdy klawisz myszki jest wciśnięty.
W tym celu do obiektu formularza zostanie dodane nowe pole, Rysowanie (Boolean), która ma przyjmuje wartość True, gdy klawisz myszki zostanie wciśnięty oraz False , gdy zostanie zwolniony.
Początek rysowanej linii zostanie zapamiętany w polu Start , ostatnie położenie myszki w polu Koniec. Oba ostatnie pola są typu Tpoint.
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
Rysowanie := True;
Canvas.MoveTo(X, Y);
Start := Point(X, Y);
Koniec := Point(X, Y); { zapamiętuje ostatnie położenie myszki }
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
Canvas.MoveTo(Start.X, Start.Y); { przesuwa pióro do punktu początkowego }
Canvas.LineTo(X, Y);
Rysownie := False;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Rysowanie then
begin
Canvas.Pen.Mode := pmNotXor; { wykorzystuje tryb XOR do rysowania/usuwania linii }
Canvas.MoveTo(Start.X, Start.Y); { przesuwa pióro do punktu startowego }
Canvas.LineTo(Koniec.X, Koniec.Y); { usuń starą linię }
Canvas.MoveTo(Start.X, Start.Y); { ponownie przesuwa pióro do punktu startowego }
Canvas.LineTo(X, Y); { rysuje nową linię }
end;
MovePt := Point(X, Y); { zapamiętuje położenie myszki}
Canvas.Pen.Mode := pmCopy;
end;
Przeciąganie i upuszczanie
Przeciąganie i upuszczanie elementów na formularzu może być wygodnym sposobem na manipulowanie obiektami na formularzu. Można pozwolić użytkownikowi na przeciąganie komponentów lub przeciąganie elementów z jednej listy na inną listę (w innym komponencie).
Dla przeciąganie i upuszczania ważne są cztery operacje:
1 Rozpoczęcie operacji przeciągania
2 Zaakceptowanie przeciąganych elementów
3 Upuszczanie elementów
4 Zakończenie operacji przeciągania
Rozpoczęcie operacji przeciągania
Każdy komponent ma właściwość zwaną DragMode, która kontroluje zachowanie komponentu, w momencie, gdy użytkownik rozpocznie operację przeciągania. Jeśli DragMode jest ustawione na dmAutomatic, przeciąganie rozpocznie się automatycznie w momencie, gdy użytkownik wciśnie klawisz myszki nad komponentem. Częstszym ustawieniem jest dmManual (domyślne), które powoduje rozpoczęcie przeciągania poprzez obsługę zdarzenie wciśnięcia klawisza myszki.
n Aby rozpocząć ręcznie przeciąganie, wywołaj metodę BeginDrag. Metoda ta ma jeden parametr logiczny, zwany Immediate. Jeśli przekażesz True, przeciąganie rozpocznie się natychmiast, da to podobny efekt jak ustawienie DragMode na dmAutomatic. Jeśli przekażesz False, przeciąganie nie rozpocznie się, dopóki użytkownik nie przesunie myszki na krótki dystans. Wywołanie BeginDrag(False) pozwala kontrolce (Komponentowi) zaakceptowanie kliknięcia myszki bez rozpoczęcia operacji przeciągania.
Można także ustawić warunki, które muszą być spełnione, aby rozpoczęło się przesuwanie np. sprawdzenie jaki przycisk wcisnął użytkownik czy testowanie parametrów zdarzenia wciśnięcia klawisza myszki.
ä Następujący kod obsługuje zdarzenie wciśnięcie klawisza myszki w polu listy poprzez rozpoczęcie przeciąganie tylko jeśli jest wciśnięty lewy klawisz myszki:
procedure Tform1.ListBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then { przeciąga tylko jeśli jest wciśnięty lewy klawisz myszki }
with Sender as TListBox do { traktuj Sender jako typ TListBox }
begin
if ItemAtPos(Point(X, Y), True) >= 0 then { czy jest tam element? }
BeginDrag(False); { jeśli tak, rozpocznij przesuwanie }
end;
end;
Po uruchomieniu programu okazuje się, że łatwo jest przeciągnąć elementy, ale nie można ich nigdzie upuścić. Aby było to możliwe, muszą być kontrolki (komponenty), które zaakceptują upuszczany element.
Akceptowanie przeciąganych elementów
Kiedy użytkownik przeciąga jakiś element nad kontrolkę (komponent), to otrzymuje ona zdarzenie OnDragOver. Musi zostać określone, czy zaakceptuje ona upuszczenie tego elementu. Delphi zmienia wygląd kursora, tak aby było jasne, czy kontrolka akceptuje przeciągany element czy nie.
n Aby zaakceptować element przeciągany nad kontrolkę, utwórz odpowiednią procedurę obsługi zdarzenia OnDragOver. Zdarzenie to ma jeden parametr przekazywany przez zmienną, zwany Accept, który procedura powinna ustawić na True, jeśli zaakceptuje element.
Ustawienie Accept na True oznacza, że jeśli użytkownik zwolni klawisz myszki w tym miejscu, upuszczając przeciągany element, aplikacja wyśle zdarzenie upuszczenia elementu do tej samej kontrolki. Jeśli wartością Accept jest False, aplikacja nie pozwoli na upuszczenie elementu nad tą kontrolką. Tym samym kontrolka nigdy dnie będzie obsługiwać zdarzenia upuszczania elementu, którego nie potrafi obsłużyć.
Zdarzenie drag-over zawiera szereg parametrów, w tym źródło przeciąganego elementu i bieżące położenie kursora myszki. Procedura obsługi tego zdarzenia może wykorzystać te parametry do określenia, czy akceptuje przeciągany element czy nie. Najczęściej decyzja o akceptacji zapada na podstawie typu sendera, ale może też akceptować tylko elementy pochodzące z określonej instancji komponentu.
ä W tym przykładzie, pole listy akceptuje przeciągane elementy tylko wtedy, jeśli pochodzą one z pola listy:
procedure TForm.ListBox2DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState;
var Accept: Boolean);
begin
if Source is TListBox then
Accept := True;
end;
Upuszczanie elementów
Jeśli kontrolka określi, że zaakceptuje przeciągany element, powinna także określić sposób, w jaki obsłuży sytuację upuszczenia tego elementu. Jeśli użytkownik widzi, że element można upuścić w danym miejscu to oczywiście oczekuje, że to upuszczenie spowoduje jakąś reakcję.
n Aby obsłużyć upuszczenie elementów, utwórz odpowiednią procedurę obsługi zdarzenia OnDragDrop kontrolki, która akceptuje upuszczenie elementu.
Podobnie jak zdarzenie przeciągania (drag-over), zdarzenie upuszczana określa źródło przeciąganego elementu i współrzędne położenia kursora myszki. Te parametry dostarczają procedurze obsługi upuszczenia niezbędnych informacji dotyczących źródła przeciąganego elementu i decydują o sposobie jego obsłużenia.
ä Na przykład, pole listy2 akceptuje elementy przeciągane od pola listy i może przenieść do niej przeciągany element.
procedure TForm1.ListBox2DragDrop(Sender, Source: TObject; X, Y: Integer);
var
i : integer;
punkt : TPoint;
napis : String;
begin
{ zmienia współrzędne x,y na zmienną typu TPoint }
punkt.x:=x;
punkt.y:=y;
i := 0;
While i <= (Source as TListBox).Items.Count-1 do //przegląda całą listę (Items.Count-1) podaje ilość elementów
begin
{ szuka zaznaczonego elementu, to ten, który będzie przesunięty }
if (Source as TlistBox).selected[i] then
begin
With Sender as TListBox do
begin
napis := (Source as TListBox).items[i];
(Source as TListBox).items.Delete(i); {usuwa napis, który będzie przeciągany }
items.Insert( ItemAtPos (punkt,true), napis); { wstawia napis na właściwą pozycję w drugiej liście}
end;
end;
inc(i);
end;
end;
Powyższa procedura usuwa przeciągany element z pierwszej listy i wstawia do drugiej listy.
Zakończenie operacji przeciąganie
Kiedy operacja przeciągania zostanie zakończona, albo poprzez upuszczenie przeciąganego elementu lub poprzez zwolnienie klawisza myszki nad kontrolką, która go nie zaakceptowała, Delphi wysyła zdarzenie zakończenia przeciągania z powrotem do kontrolki, którą użytkownik przeciągał.
n Aby umożliwić kontrolce odpowiedź na zakończenie przeciągania elementu, który z niej pochodzi, dołącz do zdarzenia OnEndDrag tej kontrolki odpowiednią procedurę obsługi zdarzenia.
Najważniejszym parametrem zdarzenia OnEndDrag jest parametr Target, który określa, który parametr, o ile taki był, zaakceptował upuszczenie elementu. Jeśli Target ma wartość nil, to żadna kontrolka (komponent) nie zaakceptowała upuszczenia elementu. W przeciwnym przypadku Target określa kontrolkę, która go zaakceptowała. Zdarzenie OnEndDrag również zawiera współrzędne (x, y) miejsca, gdzie nastąpiło upuszczenie.
Listy tekstów i ich zastosowanie.
Pojęcie list tekstów i ich zastosowanie
Dostęp do wybranego tekstu na liście
Dodanie tekstu do listy
Ładowanie i zachowywanie list tekstów
Liczenie tekstów na liście
odszukiwanie pozycji tekstu na liście
przesuwanie tekstów na liście
usuwanie tekstów z listy
kopiowanie całej listy tekstów
przeglądanie tekstów na liście
tworzenie nowych list tekstów
Dodawanie obiektów do listy tekstów
Pola listy i pola kombi
Używanie grup opcji (RadioGroup)
Listy tekstów mają bardzo szerokie zastosowanie: elementy na listach i listach rozwijanych, linie tekstów w komponencie memo, linie i kolumny w komponencie siatki tekstów (string grid), elementy grupy opcji (RadioGroup). Do obsługi tych list Delphi oferuje obiekt, zwany listą tekstów (string list), dzięki czemu możliwa jest wymiana pomiędzy różnymi typami list np. można umieścić teksty z pola memo na liście rozwijanej.
Zazwyczaj korzystamy z list tekstów podczas pracy z Inspektorem obiektów. Właściwości będące listą tekstów są typu TStrings (ten typ pojawia się w kolumnie Value). Po dwukrotnym kliknięciu pojawi się Edytor list tekstów (String List editor), gdzie można edytować, dodawać lub usuwać linie.
Można także pracować z listami tekstów w kodzie programu.
Manipulowanie tekstami na liście
Często piszemy w Delphi kod operujący tekstami na istniejącej liście. Dzieje się tak najczęściej wtedy, gdy jeden z komponentów ma właściwość typu TStrings (lista tekstów) i istnieje potrzeba jej zmiany lub wydobycia z niej tekstów.
Liczenie tekstów na liście
n Aby policzyć ile jest tekstów na liście, wykorzystaj właściwość Count . Jest to właściwość tylko do odczytu i podaje liczbę tekstów na liście. Ponieważ teksty są numerowane od 0, więc właściwość Count podaje wartość o 1 większą od numeru ostatniego tekstu na liście.
ä Na przykład, aplikacje może odczytać liczbę dostępnych czcionek poprzez odczytanie właściwości Count na liście dostępnych czcionek bieżącego ekranu:
FontCount := Screen.Fonts.Count;
Dostęp do wybranego tekstu
Każda lista tekstów ma indeksowaną właściwość Strings, którą możesz traktować jak tablicę tekstów. Na przykład pierwszy tekst na liście to Strings[0]. Ponieważ ta właściwość jest właściwością domyślną, można ominąć identyfikator Strings i traktować samą listę jako tablicę tekstów.
n Aby uzyskać dostęp do wybranego tekstu na liście tekstów, podajemy jego numer (indeks) na liście. Elementy na liście są numerowane od 0.
Jeśli wystąpi próba odwołania się do napisu spoza listy (o błędnym indeksie) zostanie podniesiony wyjątek.
ä Poniższe instrukcje wykonują to samo: zmieniają wartość pierwszej linii w polu memo:
Memo1.Lines.Strings[0] := 'To jest pierwsza linia.';
Memo1.Lines[0] := 'To jest pierwsza linia';
Odszukiwanie pozycji tekstu na liście
Mając podany tekst, możemy sprawdzić, na jakiej pozycji znajduje się on na liście (lub czy w ogóle tam występuje).
n Aby zlokalizować tekst na liście, możesz użyć metody IndexOf . IndexOf ma jako parametr tekst, którego pozycję chcemy odszukać i zwraca indeks tego tekstu na liście lub -1 , gdy tekst nie występuje na liście.
Metoda IndexOf działa tylko dla pełnych tekstów, tzn. nie pozwala na sprawdzenie, czy dowolny tekst na liście zawiera ciąg znaków podanych jako parametr tej metody.
ä Przykład: metoda IndexOf sprawdza czy podany plik znajduje się na liście plików w polu listy plików
if FileListBox1.Items.IndexOf('AUTOEXEC.BAT') > -1 then { Jesteś w katalogu głównym };
Dodawanie tekstu do listy
Istnieją dwa sposoby na dodanie tekstu do listy. Można go dodać na końcu lub w środku listy.
n Aby dodać tekstu na końcu listy, wywołaj metodę Add i przekaż jako jej parametr dodawany tekst.
n Aby wstawić tekst w środku listy, wywołaj metodę Insert, przekazując jej dwa parametru, indeks miejsca, gdzie chcesz wstawić tekst i wstawiany tekst.
ä Aby wstawić tekst `Trzy' na trzeciej pozycji w liście, wywołaj metodę Insert :
ListBox1.Items.Insert(2,'Trzy')
Jeśli lista zawiera nie zawiera co najmniej dwóch elementów zostanie podniesiony wyjątek przekroczenia zakresu indeksu (index-out-of- range)
Przesuwanie tekstów na liście
Przesuwanie tekstów może być przydatne w sytuacji, gdy chcemy np. posortować listę. Jeśli tekst zawiera powiązany z nim obiekt, zostanie on również przesunięty.
n Aby przesunąć teksty na liście, wywołaj metodę Move , przekazując jej dwa parametry: bieżący indeks elementu oraz numer pozycji na którą chcemy przesunąć element.
ä Na przykład, aby przesunąć trzeci tekst na liście na piątą pozycję, wywołaj Move:
ListBox.Items.Mowve(2,4);
Usuwanie tekstów z listy
n Aby usunąć tekst z listy, wywołaj metodę (obiektu - listy tekstów) Delete przekazując jej indeks tekstu, który chcesz usunąć z listy. Jeśli nie znasz indeksu usuwanego tekstu, użyj najpierw metody IndexOf .
n Aby usunąć wszystkie teksty z listy , użyj metody Clear.
ä Przykład pokazujący użycie metody IndexOf do zlokalizowanie tekstu na liście a następnie usuwający go za pomocą metody Delete:
with ListBox1.Items do
begin
if IndexOf('czekolada') > -1 then
Delete(IndexOf('czekolada'));
end;
Kopiowanie całej listy tekstów
n Aby skopiować całą listę tekstów z jednej listy tekstów do drugiej, wystarczy przypisać listę źródłową do listy docelowej.
Kopiowanie tekstów z jednej listy do innej wymazuje testy oryginalnie znajdujące na liście docelowej. Jeśli chcesz dowiązać jedną listę na końcu drugiej, użyj metody AddStrings przekazując jej jako parametr listę, która ma być dodana.
ä Przykład: kopiowanie listy z pola kombi do listy outline:
Outline1.Lines := ComboBox1.Items;
ä Przykład: lista zostanie dodana na końcu listy outline:
Outline1.AddStrings(ComboBox1.Items);
Przeglądanie tekstów na liście( iteracja)
Przydatne jest, gdy np. poszukujemy tekstu na liście, który zawiera określony ciąg znaków (podciąg).
n Aby przeglądać po kolei teksty na liście możesz wykorzystać pętlę for .
Jeśli chcemy przejrzeć wszystkie teksty na liście, zmienna sterująca pętli powinna się zmieniać od 0 do liczby elementów na liście zmniejszonej o 1 (Count - 1).
äNa przykład, poniższa pętla przegląda teksty w polu listy i zamienia je na teksty pisane dużymi literami:
procedure TForm1.Button1Click(Sender: TObject);
var
Index: Integer;
begin
for Index := 0 to ListBox1.Items.Count - 1 do
ListBox1.Items[Index] := UpperCase(ListBox1.Items[Index]);
end;
Ładowanie i zachowywanie list tekstów
Możesz łatwo przechowywać dowolne listy tekstów w pliku tekstowym. Obiekty list tekstów zawiera metody, które ułatwiają zapisywanie list w pliku i ładowania tekstów z pliku do listy.
n Aby załadować listę tekstów z pliku, wywołaj metodę LoadFromFile i przekaż jej jako parametr nazwę pliku tekstowego, z którego mają być załadowane teksty. LoadFromFile czyta każdą linię tekstu z pliku tekstowego jako oddzielny element na liście.
n Aby przechować listę tekstów w pliku tekstowym, wywołaj metodę SaveToFile i przekaż jej nazwę pliku, w którym mają być zachowane teksty. Jeśli plik nie istnieje, zostanie on utworzony. Jeśli istnieje, to jego stara zawartość zostanie usunięta i zastąpiona nową.
äPrzykład: kopia pliku AUTOEXEC.BAT zostanie załadowana z katalogu głównego dysku C do pola memo i tworzy jego kopię w pliku AUTOEXEC.BAK:
procedure TForm1.FormCreate(Sender: TObject);
var
FileName: string; { przechowuje nazwę pliku}
begin
FileName := 'C:\AUTOEXEC.BAT'; { ustawia nazwę pliku }
with Memo1 do
begin
LoadFromFile(FileName); { ładuje z pliku }
SaveToFile(ChangeFileExt(FileName, 'BAK')); { przechowuje w pliku o rozszerzeniu .BAK }
end;
end;
Komponenty wykorzystujące listy tekstów
TListBox
Pole listy. Służy do wyświetlania listy tekstów, z których użytkownik może wybrać jedną lub wiele.
Właściwość Items zawiera listę wyświetlanych tekstów (właściwość jest typu TString).
Jeśli na liście został zaznaczony element, właściwość Selected przyjmie wartość True. Aby określić, który element został zaznaczony, wykorzystaj właściwość ItemIndex. Jeśli właściwość MultiSelect ma wartość True, to użytkownik może zaznaczyć więcej niż jeden element. Ilość zaznaczonych elementów jest przechowywana we właściwości SelCount.
Możemy wyświetlać elementy na liście w porządku alfabetycznym, ustawiając właściwość Sorted na True.
TcomboBox
Pole kombi. Ma podobne właściwości jak pole listy. Dodatkowo ma pole tekstowe, w którym użytkownik może wpisać nowy element. Ma również właściwość Text, w którym jest przechowywany tekst wpisany przez użytkownika.
Lista elementów jest przechowywana we właściowści Items.
ItemIndex przechowuje indeks wybranego elementu.
Aby usunąć tekst z pola edycji użyj metody Clear.
Możemy wyświetlić elementy listy w porządku alfabetycznym poprzez ustawienie właściwości Sorted na True.
TRadioGroup
Grupa opcji. Komponent ten grupuje przyciski opcji. W danej chwili może być zaznaczony co najwyżej jeden element. Nowy przycisk opcji jest dodawany o ile zostanie wpisany nowy element do listy tekstów zawartych we właściwości Items. Każdy element listy Items pojawia się jako kolejny przycisk opcji. Wartość właściwości ItemIndex wskazuje, który przycisk został wciśnięty (zawiera indeks tego elementu).
Przyciski opcji można wyświetlać w jednej lub kilku kolumnach (wpisz wtedy ilość kolumn do właściwości Columns).
Komponent Memo i RichEdit
Komponent RichEdit
Formatowanie tekstu i drukowanie zawartości komponentu RichEdit
Memo jako przykład listy tekstów
Ustawianie wyrównania tekstu
Wykorzystanie schowka
Manipulowanie tekstem w komponencie memo
Komponent Memo służy do wyświetlania i wprowadzania tekstu, podobnie jak pole tekstowe (TEdit). Jednak w przeciwieństwie do niego można wprowadzać kilka linii tekstu. Wprowadzany tekst jest przechowywany we właściwości Text, jednak jeśli chcemy manipulować poszczególnymi liniami tekstu, powinniśmy użyć właściwości Lines (TStrings). Korzystamy wtedy z metod dla list tekstów.
Memo1.Lines.Add('Dodano nową linię' );
Jeśli chcemy, aby użytkownik nie mógł zmienić wyświetlanego tekstu, ustawiamy właściwość ReadOnly na True.
Ustawianie wyrównania tekstu i zawijania tekstu
W naszym edytorze tekstów użytkownik może wyrównywać tekst i decydować o tym, czy tekst będzie zawijany po dojściu do krawędzi. Umożliwiają to polecenia z menu Character . Włączona opcja jest oznaczona przez specjalny znaczek z lewej strony opcji.
Alignment i WordWrap są właściwościami komponentu Memo. Podobnie jak wszystkie właściwości, możemy je ustawiać w kodzie programu za pomocą prostej instrukcji przypisania.
Dodanie dynamicznych pasków przewijania
Właściwość ScrollBars dla komponentu Memo została już ustawiona. Na początku okno ma oba pasku przewijania. Jeśli użytkownik wybierze opcję zwijania tekstu, to potrzebny będzie tylko jeden, pionowy pasek przewijania.
ä Procedura obsługi zdarzenia OnClick dla polecenia Znak|Zawijaj tekst zamienia wartość właściwości WordWarp na przeciwną (True na False, False na True). Jeśli jest wybrana opcja zawijania tekstu, jest ustawiany jeden pasek przewijania, w przeciwnym przypadku oba.
procedure TForm1.ZawijajTekst1Click(Sender: TObject);
begin
with Memo1 do
begin
WordWrap := not WordWrap;
if WordWrap then
ScrollBars := ssVertical
else
ScrollBars := ssBoth;
ZawijajTekst1.Checked := WordWrap;
end;
end;
Wykorzystanie schowka na teksty
Obiekt Clipboard utworzony w Delphi obsługuje schowek Windows i oferuje metody do dokonywania podstawowych operacji takich jak wycinanie, kopiowanie i wklejanie tekstów (i innych formatów). Obiekt Clipboard jest zadeklarowany w module CLIPBRD.PAS, więc aby móc wykorzystać metody z tego obiektu, trzeba zadeklarować użycie tego modułu.
Zaznaczanie tekstu
Możliwość zaznaczania tekstów należy do standardowych cech komponentu Memo, RichEdit i Edit. Właściwość SelText, dostępna tylko w kodzie programu, zawiera tekst zaznaczony w komponencie. Metoda SelectAll zaznacza cały tekst w komponencie memo lub w innym komponencie. Metody SelLength i SelStart zwracają długość tekstu i startową pozycję zaznaczonego tekstu w komponencie.
Można wykorzystać metodę SelLength do sprawdzenia, czy Memo zawiera jakikolwiek zaznaczony tekst i do określenia stanu poleceń z menu Edit (dostępny, niedostępny).
ä Poniższa procedura zaznacza cały tekst w komponencie:
procedure TForm1.ZaznaczWszystko(Sender: TObject);
begin
Memo1.SelectAll;
end;
Wycinanie, kopiowanie i wklejanie tekstu
Metoda CopyToClipboard kopiuje zaznaczony w komponencie Memo lub Edit tekst do schowka. Metoda CutToClipboard wycina zaznaczony tekst i umieszcza go w schowku. Metoda PasteFromClipboard wkleja tekst znajdujący się obecnie w schowku w miejscu aktualnego położenia punktu wstawiania.
ä Poniższa procedura kopiuje tekst do schowka:
procedure TForm1.Kopiuj(Sender: TObject);
begin
Memo1.CopyToClipboard;
end;
Usuwanie tekstu bez przenoszenia go do schowka
Komponent memo zawiera też metodę ClearSelection, które usuwa zaznaczony w komponencie memo tekst, bez przenoszenia go do schowka.
ä Poniższa procedura usuwa tekst bez wklejania go do schwola:
procedure TForm1.Skasuj(Sender: TObject);
begin
Memo1.ClearSelection;
end;
TRichEdit
W komponencie memo cały tekst musiał mieć taką samą czcionkę. Nie można było wyróżnić fragmentu tekstu poprzez np. pogrubienie i zwiększenie czcionki.
Taką możliwość daje komponent TRichEdit zawarty na stronie Win95. Zawiera on w większości metody i właściwości komponentu memo i pozwala na wyświetlanie tekstu w formacie .RTF.
Zwartość komponentu jest zawarta we właściwości Lines, podobnie jak w przypadku memo.
Formatowanie tekstu
w trybie projektu
Korzystamy wtedy z właściwości Font oraz z właściwości PlainText. Ta ostatnia decyduje, czy tekst zawarty w komponencie jest traktowany jako czysty tekst czy też tekst w formacie .RTF. Ustawmy PlainText na:
true jeśli chcemy załadować tekst z pliku tekstowego (.TXT) lub zapisać zawartość RichEdit w takim pliku
false jeśli chcemy załadować tekst z pliku .RTF lub zapisać zawartość RichEdit w takim pliku.
Wyświetlany tekst można przygotować np. w Wordzie i zapisać w formacie .RTF. Następnie można w procedurze obsługi np. zdarzenia OnCreate formularza umieścić kod ładujący ten plik do komponentu RichEdit.
ä Poniższy kod ładuje do komponentu RichEdit zawartość pliku `Informacje.rtf':
RichEdit1.Lines.LoadFromFile(`informacje.rtf');
w kodzie programu
Format tekstu można zmieniać korzystając z właściwości DefAttributes i SelAttributes. Ustawienia akapitu zawiera właściwość Paragraph.
Właściwość SelAttributes zawiera opis atrybutów zaznaczonego tekstu (jest ona typu TTextAttributes).
Właściwość DefAttributes zawiera opis domyślnych atrybutów tekstów. Dotyczy nowo wprowadzanego tekstu (o ile żaden tekst nie jest zaznaczony) i takich, które nie były formatowane w specjalny sposób.
Jeśli wprowadzamy tekst w miejsce zaznaczonego tekstu, to nowo wprowadzony tekst przyjmuje formatowanie zastępowanego.
Właściwości DefAttributes i SelAttributes są typu TTextAttributes. Jest on analogiczne go właściwości TFont.
Właściwość Paragraph zawiera informacje dotyczące ustawień akapitu: wyrównanie, wcięcie, wyliczanie, tabulatory. Wykorzystując tą właściwość można zmienić formatowanie zaznaczonych akapitów
Drukowanie zawartości RichEdit
Komponent ten posiada specjalną metodę służącą do drukowania jego zawartości: Print. Wystarczy ją wywołać:
RichEdit1.Print;
Wydruk zawartości listy tekstów.
Wydruk pliku tekstowego
Wydruk zawartości listy tekstów (na przykładzie komponentu Memo).
Drukowanie
Moduł Delphi - Printers zawiera procedury do obsługi procesu drukowania. Został w nim zadeklarowany obiekt, TPrinter, który tworzy interface pomiędzy drukowanym plikiem a drukarką. Procedura AssignPrn łączy plik tekstowy z drukarką wybraną w oknie dialogowym Print Setup.
Wykorzystanie obiektu printer
Metody i właściwości obiektu Printer pozwalają na kontrolowanie sposobu, w jaki są drukowane dokumenty. te metody i właściwości współpracują z oknami dialogowymi Print i Printer Setup.
Kanwa (Canvas)
Kanwa reprezentuje powierzchnię aktualnie drukowanego dokumentu. Zawartość pliku tekstowego przypisujemy do właściwości Canvas obiektu printer. Obiekt przekazuje następnie zawartość właściwości Canvas do drukarki.
Czcionki
Jeśli nie zostanie to określone inaczej, drukarka używa domyślnej (systemowej) czcionki, określonej przez sterownik drukarki dla drukowania plików tekstowych. Aby zmienić czcionkę drukarki wystarczy przypisać wartość właściwości Font komponentu Memo1 do właściwości Font obiektu Canvas obiektu drukarki. Na przykład:
Printer.Canvas.Font := Memo1.Font;
Przesyłanie pliku tekstowego do drukarki
Zanim rozpoczniemy drukowanie, musimy przyporządkować zmienną plikową do drukarki. poprzez wywołanie procedury AssignPrn. Od tego momentu instrukcje Write i WriteLn zapisują tekst na kanwie obiektu printer, wykorzystując czcionkę i pozycję kursora właściwości Canvas.
AssignPrn(zmienna_plikowa);
Rewrite(zmienna_plikowa);
Zmienna_plikowa jest typu System.Text (typ zdefiniowany w module System).
Wywołanie metody Rewrite (z modułu System) otwiera plik do zapisu (tu drukarkę).
Wypisanie tekstu
Po przygotowaniu drukarki, możemy wypisać tekst z memo na drukarkę. Można to zrobić korzystając z pętli for. Najpierw deklarujemy zmienną sterującą Line:
var
Line: Integer;
Teraz tworzymy instrukcję for wypisującą zawartość (właściwość Lines) komponentu Memo1:
for Line := 0 to Memo1.Lines.Count-1 do
Writeln(Printer1, Memo1.Lines[Line]);
Numery linii są liczone od 0, więc ostatni numer linii to liczba linii (count) minus 1.
Po wypisaniu tekstu zamykamy plik procedurą CloseFile:
CloseFile(zmienna_plikowa).
Drukowanie zawartości Memo
ä Następująca procedurę obsługi kliknięcia dla polecenia Plik|Drukuj drukuje zawartość pola memo:
procedure TEditForm.Drukuj1Click(Sender: TObject);
var
Linia: Integer; {zmienna liczącą linie tekstu}
druk: System.Text; {deklaracja zmiennej plikowej tekstowej, typ zdefiniowany w module System}
begin
if PrintDialog1.Execute then
begin
AssignPrn(druk); {skojarzenie zmiennej PrintText z drukarką}
Rewrite(druk); {utworzenie i otworzenie pliku do zapisu }
Printer.Canvas.Font := Memo1.Font; {przypisanie bieżącej czcionki z Memo
do czcionki kanwy obiektu Printer}
for Lina := 0 to Memo1.Lines.Count - 1 do
Writeln(druk, Memo1.Lines[Line]); {wypisanie zawartości Memo na drukarkę}
CloseFile(druk);
end;
end;
Obsługa plików zdefiniowanych.
Korzystanie z plików zdefiniowanych
Pliki zdefiniowane są to pliki, które zawierają elementy tego samego typu, najczęściej jest to typ rekordowy.
ä Deklaracja typu rekordowego :
type TDane = record
Imie:String[20];
Nazwisko:String[40];
end;
Jeśli będziemy korzystać z pliku zdefiniowanego o elementach typu rekordowego, to w jego deklaracji żadne pole nie powinno być typu String (można zadeklarować jako String[80] - ograniczając liczbę znaków lub ShortString - ograniczony do 255 znaków). Każdy element pliku, niezależnie od długości wprowadzonego łańcucha będzie miał tę samą stałą długość, warto więc w definicji typu rekordowego ograniczać zadeklarowaną długość napisu.
Deklaracja typu plikowego
Następnie musimy zadeklarować zmienną typu plikowego. Podajemy w definicji typ elementów pliku
zmienna_pllikowa : file of Typ_elementów_pliku
ä Deklaracja zmiennej plikowej typu rekordowego TDane:
var
PlikDanych: file of TDane;
funkcje i procedury do obsługi plików zdefiniowanych
AssignFile (zmienna_plikowa, nazwa_pliku);
Procedura służy do skojarzenia zmiennej plikowej (F) z określonym plikiem:
ä Następujący kod kojarzy zmienną PlikDanych z plikiem `dane.dat', znajdującym się w katalogu Adresy:
AssignFile(PlikDanych, `Adresy/dane.dat');
Reset ( zmienna_plikowa);
Procedura otwiera istniejący już plik na podstawie skojarzonej wcześniej z nim zmiennej. Plik jest otwierany do odczytu.
Rewrite (zmienna_plikowa);
Procedura tworzy i otwiera nowy plik na podstawie stowarzyszonej wcześniej z nim zmiennej.
Seek (zmienna_plikowa, numer_pozycji_pliku);
Procedura ustawia otwarty plik identyfikowany przez zmienną zmienna_plikowa w pozycji określonej
parametrem numer_pozycji_pliku. Elementy pliku są numerowane od zera.
ä Poniższa instrukcja ustawia wskaźnik pliku na pierwszym rekordzie:
Seek(PlikDanych, 0);
FileSize(zmienna_plikowa);
Funkcja podaje rozmiar pliku, dla plików zdefiniowanych jest to ilość elementów pliku.
ä Poniższa procedura ustawia wskaźnik pliku za ostatnim rekordem:
Seek( PlikDanych, FileSize(PlikDanych) );
Read (zmienna_plikowa, zmienne)
Procedura odczytuje rekordy (elementy) z pliku identyfikowanego przez zmienną (zmienną_plikową).
ä Poniższa procedura odczytuje wartość zmiennej Dane typu TDane z pliku:
Read( PlikDanych, Dane );
Write (zmienna_plikowa, zmienne)
Procedura zapisuje rekordy (elementy) do pliku skojarzonego ze zmienną (zmienną_plikową).
ä Poniższa procedura zapisuje wartość zmiennej Dane typu TDane do pliku:
Write( PlikDanych, Dane );
Eof (zmienna_plikowa);
Funkcja zwraca wartość True, jeśli plik F znajduje się w pozycji końcowej (End Of File).
ä Poniższa pętla wykonuje się do momentu osiągnięcia końca pliku:
while not Eof(PlikDanych) do
begin
..... {instrukcje te są wykonywane, aż zostanie osiągnięty koniec pliku}
end;
CloseFile (zmienna_plikowa);
Procedura zamyka plik skojarzony ze zmienną zmienna_plikowa, zapisując do niego wcześniej wszystkie nie zapisane jeszcze zmiany.
Przykład operacji na plikach zdefiniowanych
Przykład ten to bardzo prosta baza danych, która przechowuje tylko nazwy firm i numery telefonów. Jeśli taki program miałby być wykorzystany w praktyce, trzeba go rozbudować.
ä Rozpocznij nowy projekt. Do formularza dodaj dwa pola tekstowe i dwie etykiety, które te pola będą opisywać. Pierwsze pole niech się nazywa NazwaEdit , a etykieta powinna wyświetlać tekst `Nazwa firmy”, drugie pole tekstowe niech się nazywa TelefonEdit, a etykieta `Telefon'.
Dodaj też pięć przycisków: Poprzedni (nazwa - poprzedni), Następny (nastepny), Zapisz (zapisz), Nowy(nowy), Zamknij (zamknij);
Deklaracje typów i zmiennych
ä Przed deklaracją typu formularza dodaj deklarację typu rekodowego:
type
TDane= record
nazwa:String[40];
telefon:String[14];
end;
ä W części private formularza zadeklaruj następujące pola i metody:
PlikDanych : TDane; {zmienna plikowa}
dane : TDane {przechowujemy tu aktualnie odczytany rekord}
Pozycja : {numer rekordu, nad którym jest aktualnie wskaźnik pliku}
procedure PobierzRekord;
procedure ZachowajRekord;
procedure PokazRekord;
procedure WyczyscDane;
Otwieranie pliku i wyświetlenie pierwszego rekordu
ä Zakładamy, że dane są w pliku `Adresy.dat'. Po otwarciu aplikacji plik ten powinien być otworzony lub utworzony, jeśli nie istnieje. Ponieważ jest to czynność, którą wykonujemy na początku pracy aplikacji, więc najlepiej jest ją umieścić w procedurze obsługi zdarzenia OnCreate formularza:
procedure TForm1.FormCreate(Sender:TObject);
begin;
WyczyscDane; {czyścimy pola edycji}
Pozycja:=0; {bieżący rekord = 0}
AssignFile (PlikDanych, `adresy.dat');
if FileExist( PlikDanych) then {jeśli jest plik, otwieramy go}
begin
Reset(PlikDanych);
if not eof(PlikDanych) then
begin
Read(PlikDanych, dane);
PokazRekord(dane);
end;
end
else begin {...jeśli nie ma, tworzymy go}
WyczyscDane;
Rewrite(PlikDanych);
end;
ä W procedurze zostały wykorzystane dwie metody, które nie zostały zdefiniowane. Zdefiniujmy je:
procedure TForm1.PokazRekord; {wyświetla dane z bieżącego rekordu (pole dane) na ekranie}
begin
NazwaEdit.Text:=dane.nazwa;
TelefonEdit.Text:=dane.telefon;
end;
procedure TForm1.WyczyscDane; {czyści pola na ekranie}
begin
NazwaEdit.Text:='';
TelefonEdit.Text:='';
end;
Dodanie nowego rekordu
ä Dodanie nowego rekordu następuje w momencie kliknięcia na przycisk Nowy. Zostaną wtedy dodane dane wpisane w pola edycji na formularzu:
procedure TForm1.NowyClick(Sender:TObject); {dodaje nowy pusty rekord na końcu pliku}
begin
repeat
pozycja:=pozycja+1;
Seek(PlikDanych, pozycja);
until eof(PlikDanych);
WyczyscDane;
ZachowajRekord; {zapisuje nowy pusty rekord}
end;
ä Nowo wpisane dane są zachowywane w momencie kliknięcia na przycisk Zapisz:
procedure TForm1.ZapiszClick(Sender:TObject);
begin
ZachowajRekord;
PokazRekord;
end;
ä W procedurach tych została wykorzystana metoda, która nie jest jeszcze zdefiniowana:
procedure TForm1.ZachowajRekord; {zachowuje w pliku dane wyświetlane na ekranie}
begin
dane.nazwa:= NazwaEdit.Text;
dane.telefon:=Telefon.Edit.Text; {pobiera dane z ekranu}
Write(PlikDanych, dane); { i zapisuje je w pliku}
end;
Przejście do poprzedniego i do następnego rekordu
ä Następujące procedury są wywoływane jako odpowiedź na kliknięcie przycisku Następny i Poprzedni:
procedure TForm1.PoprzedniClick(Sender:TObject);
begin
if Pozycja-1 < 0 then {próba przejścia przed pierwszy rekord}
begin
pozycja:=0;
Seek(PlikDanych, pozycja);
ShowMessage(`Początek pliku');
end
else begin
pozycja:=pozycja-1;
Seek(PlikDanych, pozycja);
Read(PlikDanych, dane); {odczytuje rekord i przesuwa wskaźnik pliku o jedną pozycję}
Seek(plikDanych, pozycja); {wskaźnik wraca na poprzednie miejsce, określone przez zmienną pozycja}
PokazRekord;
end;
end;
procedure TForm1.NastępnyClick(Sender:TObject);
begin
Pozycja:=pozycja+1;
Seek(PlikDanych, pozycja);
if not eof(PlikDanych) then {nie osiągnięto końca pliku}
begin
Read(PlikDanych, dane); {odczytuje rekord i przesuwa wskaźnik pliku o jedną pozycję}
Seek(plikDanych, pozycja); {wskaźnik wraca na poprzednie miejsce, określone przez zmienną pozycja}
PokazRekord;
end
else begin {osiągnięto koniec pliku}
pozycja:=pozycja-1;
Seek(PlikDanych, pozycja);
ShowMessage(`Koniec pliku');
end;
end;
Zamknięcie aplikacji
ä Aplikacja jest zamykana jako odpowiedź na kliknięcie przycisku Zamknij. Ale może być zamknięta po kliknięciu na systemowy przycisk Zamknij lub np. wciśnięcie Alt-F4. Te czynności wywołują zdarzenie OnClose. Dlatego napiszemy dwie procedury, jedna jako odpowiedź na kliknięcie przycisku (zamyka formularz), druga jako odpowiedź na zamknięcie formularza (OnClick).
procedure TForm1.ZamknijClick(Sender:TObject);
begin
Close; {zamknij formularz, a tym samym i aplikację}
end;
procedure TForm1.Form1Close(Sender:TObject);
begin
ZachowajRekord;
CloseFile(PlikDanych);
end;
Formularze MDI i SDI.
Formularze MDI i SDI
Łączenie menu dla formularzy typu MDI
Otwieranie i zamykanie okna potomnego w aplikacji MDI.
Multiple Document Interface (MDI) jest formularzem, dla którego może być otwartych wiele okien potomnych i mają one jednego przodka (na przykład edytory tekstu).
Single Document Interface (SDI) jest formularzem, dla którego można otworzyć tylko jedno okno potomne.
Ustawienia właściwości FormStyle
Wartość FormStyle |
Tworzy |
Komentarz |
fsNormal |
Tworzy formularz SDI |
|
fsMDIForm |
MDI przodek lub frame form |
Ten formularz może zawierać inne formularze. |
fsMDIChild |
MDI potomek |
Ten formularz może być zawarty przez przodka Mdi w czasie uruchomienia programu |
fsStayOnTop |
Formularz SDI, który zawsze jest na wierzchu innych otwartych formularzach. |
|
Aplikacje wielodokumentowe (MDI)
Aplikacje wielodokumentowe pozwalają na jednoczesne, równoległe wyświetlanie dwóch lub więcej plików. Przykładem takich aplikacji mogą być edytory tekstowe lub arkusze kalkulacyjne.
Aplikacje MDI oferują wspólny obszar roboczy oraz ustalony sposób wyświetlania wielu dokumentów. Wspólny obszar roboczy jest nazywany rodzicem lub ramką. W Delphi jest to zawsze główny formularz aplikacji.
Wewnątrz obszaru roboczego można otwierać inne okna, które noszą nazwę potomnych. Każde okno potomne wygląda początkowo i zachowuje się tak samo. Dokumenty aplikacji lub inne dane są wyświetlane w oknach potomnych. Te dokumenty mogą mieć albo ten sam format, albo różny, dostępny w danej aplikacji.
W trybie projektu tworzymy ramkę MDI (rodzica) jako główny formularz aplikacji i tworzymy formularz okna potomnego jako szablon dla okien potomnych aplikacji. Można utworzyć kilka typów okien potomnych jako szablony. O ile typów okien potomnych może być wiele, to może być tylko jedna ramka (rodzic).
Tworzenie formularza ramki MDI
W aplikacjach MDI ramka tworzy obszar roboczy, wewnątrz którego są otwierane okna potomne.
Właściwość FormStyle określa, czy formularz jest ramką, czy oknem potomnych (lub formularzem aplikacji nie będącej typu MDI). Tę właściwość można ustawić tylko w trybie projektu.
n Aby utworzyć ramkę MDI, zaznacz główny formularz i ustaw jego właściwość FormStyle na fsMDIForm.
Uwaga Właściwość FormStyle możemy ustawić na fsMDIForm tylko dla formularza głównego aplikacji.
ä Ustaw odpowiednio właściwości formularza FormStyle, Caption i Name zgodnie z tabelką:
Właściwość |
Wartość |
Name |
Ramka |
Caption |
Aplikacja MDI |
FormStyle |
fsMDIForm |
Tworzenie formularza potomnego aplikacji MDI
Formularz potomny tworzymy w trybie projektu jako szablon dla okien, które zostaną otwarte przez właściciela po uruchomieniu aplikacji. Chociaż formularz okna potomnego jest domyślnie widoczny, należy w kodzie programu utworzyć każdy otwierany formularz (usuwamy formularz z listy automatycznie tworzonych formularzy).
W przykładowym edytorze tekstów, tworzone jest okno potomne za każdym razem, gdy użytkownik wybierze polecenie File|New. Otwierana instancja okna potomnego czyta swój stan początkowy (wygląd) z pliku .DFM.
W kolejnych krokach ustawiamy właściwości formularza potomnego i usuwamy formularz potomny z listy automatycznie tworzonych formularzy (listy Auto-Create).
Uwaga Formularzem potomnym może być dowolny formularz za wyjątkiem formularza głównego aplikacji.
n Aby utworzyć formularz potomny aplikacji MDI:
1 Otwórz nowy pusty formularz.
2 Ustaw właściwość FormStyle formularza na fsMDIChild.
3 Przejdź do listy automatycznie tworzonych formularzy (listy) (wybierz Project|Options).
4 Na liście Auto-Create zaznacz formularz potomny i przesuń go do listy Available (dostępnych formularzy).
Uwaga Przykład zawiera tylko jeden typ formularza potomnego, ale można przygotować dowolną ilość różnych typów okien potomnych. Należy pamiętać tylko o usunięciu tych formularzy z listy automatycznego tworzenia formularzy.
Jeśli aplikacja wykorzystuje tylko po jednej instancji każdego z dostępnych typów okien potomnych, to lepszym rozwiązaniem jest pozwolenie na ich automatyczne tworzenie przez Delphi (nie usuwać tych formularzy z listy).
ä Utwórz nowy formularz i ustaw jego właściwości zgodnie z tabelką. Usuń ten formularz z listy Auto-Create.
Właściwość |
Ustawienie |
Name |
Potomek |
Caption |
< blank> |
FormStyle |
fsMDIChild |
Tworzenie menu aplikacji
Pasek menu ramki (formularza rodzica) oferuje główne menu aplikacji. Jeśli formularze potomne zawierają pasek menu. każdy element menu zawarty na nim powinien być włączony do menu formularza rodzica, w momencie otrzymania fokusu przez formularz potomny.
äW przykładzie edytora tekstu, po uruchomieniu aplikacji menu zawiera tylko dwa polecenia Plik i Okno, ponieważ kontrolują one funkcje ramki. Po otworzeniu okna potomnego, menu aplikacji uzyskuje dodatkowe dwa polecenia Edycja i Znak . Istnieją one na formularzu potomnym, ponieważ dotyczą poleceń związanych z oknem potomnym. Po otworzeniu okna potomnego te polecenia są włączanie do głównego menu aplikacji.
W ten sposób główne menu aplikacji ulega zmianie w zależności od bieżącego stany aplikacji.
Uwaga Chociaż większość aplikacji MDI łączy menu ramki i formularzy potomnych, możesz także zastępować menu, zamiast je łączyć.
Tworzenie menu formularza ramki
ä Utwórz Plik i Okno menu dla ramki edytora tekstu, zgodnie z danymi z tabelki. Dla każdego elementu menu określ wartość właściwości Caption i zaakceptuj domyślną nazwę tego elementu. Zauważ, że wpisanie do właściwości nagłówka myślnika spowodowało powstanie poziomej linii oddzielającej elementy menu.
&Plik |
&Window |
&Nowy |
&Tile |
&Otwórz... |
&Kaskada |
- <myślnik> |
&Rozmieść ikony |
&Zamknij |
|
Tworzenie menu formularzy potomnych
ä Aby utworzyć menu formularza Potomek, dodaj szablon menu File, przetłumacz właściwość Caption.Utwórz elementy menu zgodnie z tabelką. Dla każdego elementu menu określ właściwość Caption i zaakceptuj automatycznie utworzoną nazwę. Dla menu Edit określ wartość właściwości ShortCut.
&Edycja ( klawisze skrótu - Shortcut) |
&Znak |
&Wytnij Ctrl+X |
Do &lewej |
&Kopiuj Ctrl+C |
Do &prawej |
W&klej Ctrl+V |
&Wyśrodkuj |
&Usuń Ctrl+D |
- <myślnik> |
- <myślnik> |
&Zawijaj słowa |
&Zaznacz wszystko |
- <myślnik> |
|
&Czcionka ... |
Łączenie menu aplikacji
Okna potomne aplikacji MDI nie zawsze mają swoje menu, ale jeśli mają , to często są one włączane do menu formularza ramki.
Przy pierwszym otwarciu aplikacji widoczne jest tylko menu formularz ramka (nie ma otwartych okien potomnych). Po otwarciu przez właściciela okna potomnego, menu z formularza potomnego zostaje włączone do menu formularza ramki. Tak dzieje się automatycznie w Delphi dla aplikacji MDI. O tym, jak zostaną połączone menu decyduje właściwość GroupIndex. Menu zostaną tak połączone, aby kolejność ich występowania na pasku menu była zgodna z wartością GroupIndex. (od lewej do prawej, menu o wartości GroupIndex 0 występuje zawsze z lewej strony menu). Jeśli właściwość GroupIndex menu potomnego jest taka sama jak jakiegoś menu ramki, to menu ramki jest zastępowane przez menu potomne.
ä Ustaw właściwość GroupIndex dla każdego elementu z paska menu, zgodnie z tabelą. Można to zrobić albo w Projektancie menu, albo ustawiając bezpośrednio tę właściwość w Inspektorze obiektów.
Formularz |
Menu |
Ustawienie GroupIndex |
FrameForm |
File |
0 |
FrameForm |
Window |
9 |
EditForm |
File |
0 |
EditForm |
Edit |
1 |
EditForm |
Character |
1 |
Ustawienie wartości GroupIndex obu menu File na 0 powoduje, że menu File z okna potomnego zastępuje menu z formularza ramki i daje pewność, że menu File znajdzie się z lewej strony menu. Przyporządkowanie właściwości GroupIndex menu Window wartości 9 zapewnia ukazanie się tego menu jako ostatniego (9 to więcej niż łączna ilość menu). Przyporządkowanie menu Edit i Character identycznych wartości GroupIndex oznacza, że zostaną one włączone do menu ramki, wartość 1 zapewnia, że znajdą się tuż za menu File.
Tworzenie okien potomnych po uruchomieniu aplikacji
n Aby utworzyć instancję okna potomnego po uruchomieniu aplikacji (w kodzie programu) wywołaj metodę Create z formularza EditForm.
Ponieważ po otworzeniu formularza potomnego jego menu Plik zastępuje menu Plik ramki, więc musimy obsłużyć polecenie Plik|Nowy oddzielnie dla obu menu.
ä Utwórz następujące procedury obsługi zdarzenia OnClick polecenia Plik|Nowy na pasku menu formularza Ramka (zmień nazwę tej procedury na NowyPotomek):
procedure TFrameForm.NowyPotomek(Sender: TObject);
var
EditForm: TEditForm; {deklaruje formularz potomny jako zmienną}
begin
EditForm := TEditForm.Create(Self); {tworzy nowe okno potomne}
end;
ä Utwórz następującą procedurę obsługi zdarzenia dla polecenia Plik|Nowy paska menu formularza Potomek:
procedure TEditForm.NowyClick(Sender: TObject);
begin
Ramka.NowyPotomek(Sender);
end;
Ponieważ wywołujemy procedurę z innego modułu, trzeba zadeklarować jego użycie w sekcji implementation.
Wywołanie metody Create dla komponentów (czyli też i dla formularza) wymaga podania jako parametru właściciela tego komponentu. Jeśli nie chcesz aby komponent miał właściciela, przekaż Self jako parametr.
ä Wypróbuj:
1 Uruchom aplikację.
Pomimo, że formularz potomny został utworzony, nie pojawił się na ekranie (został usunięty z listy automatycznego tworzenia formularzy).
2 Wybierz Plik|Nowy.
W ten sposób została wywołana procedura obsługi zdarzenia, która tworzy instancję formularza potomnego. Pojawia się okno potomne.
3 Zamknij aplikację.
Jak na razie aplikacja nie oferuje możliwości manipulowania oknami potomnymi.
Praca z otwartymi oknami potomnymi
W edytorze tekstowym, po otworzeniu okna potomnego, menu z paska formularza Potomek zostają włączone do menu formularza Ramka.
Aranżowanie i dostęp do otwartych okien potomnych
Aplikacje MDI oferują możliwość otwarcia kilkunastu okien potomnych, które znajdują się we wspólnym obszarze roboczym (okno ramka). Dlatego powinny też zawierać menu Okno, z elementami menu, które będą zawierać:
Polecenia do aranżowania otwartych okien w obszarze roboczym, np.: Tile, Kaskada, Uporządkuj ikony.
Listę otwartych dokumentów, która umożliwi użytkownikowi łatwe przełączanie się pomiędzy nimi. Bieżące okno (które ma fokus) jest wyróżnione na liście.
Kodowanie poleceń menu Okno
ä Aby po kliknięciu na polecenia Tile, Kaskada i Uporządkuj ikony nastąpiło odpowiednie ustawienie okien, utwórz następujące procedury obsługi zdarzeń. Każda procedura wymaga jedynie wywołania odpowiedniej metody:
procedure TFrameForm.Tile1Click(Sender: TObject);
begin
Tile; {wywołanie metody}
end;
procedure TFrameForm.Kaskada1Click(Sender: TObject);
begin
Cascade; {wywołanie metody}
end;
procedure TFrameForm.UporzadkujIkony1Click(Sender: TObject);
begin
ArrangeIcons; {wywołanie metody}
end;
Włączenie listy otwartych dokumentów do menu
Listę otwartych dokumentów można włączyć do dowolnego elementu menu, który pojawia się na pasku menu. Jednak może być tylko jedna taka lista na pasku menu. Lista otwartych dokumentów pojawi się pod ostatnim poleceniem menu. Aby włączyć taką listę do menu, ustaw właściwość WindowMenu formularza ramki na nazwę (właściwość Name) menu, pod którym ma się znaleźć taka lista.
n Aby włączyć listę otwartych dokumentów do menu:
1 Zaznacz formularz ramkę i ustaw właściwość WindowMenu na nazwę menu, pod którym ma się znaleźć taka lista (np. Window) (nazwę menu możesz wybrać z rozwijanej listy).
Uwaga Nazwa menu musi reprezentować nazwę elementu, który się pojawia na pasku menu, a nie polecenia z podmenu, ponieważ lista otwartych dokumentów nie może być użyta w zagnieżdżonych menu.
ä Dla edytora tekstu, ustaw właściwość WindowMenu formularza FrameForm na Window1.
Wykład z Delphi Jolanta Gryko Strona 2
Wyrównaj do lewej
Wyśrodkuj elementy (w poziomie)
Wyśrodkuj poziomo w oknie
Wyrównaj odstępy w poziomie
Wyrównaj do prawej
Wyrównaj do góry
Wyśrodkuj elementy (w pionie)
Wyśrodkuj pionowo w oknie
Wyrównaj odstępy w pionie
Wyrównaj do dołu
TForm
MyDialogBox
TForm3
TForm2
TForm1
TControl
TListBox
TCheckBox
TButton
TForm
TComponent
TObjectm
blok chroniony
zagnieżdżony blok chroniony
blok chroniony
zagnieżdżony blok chroniony
Tczew 2000