wyklad z delphi, Wiadomości wstępne


0x08 graphic
0x08 graphic
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:

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.

Ś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

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.

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

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.

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ń.

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.

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:

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:

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.

Po utworzeniu nowego formularza deklaracja potrzebnych modułów jest wykonywana automatycznie.

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

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.

0x08 graphic
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.

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

0x08 graphic
Nie

MainMenu

Menu. Tworzy pasek menu wraz z rozwijanym menu.

0x08 graphic
Nie

PopupMenu

Menu podręczne. Tworzy podręczne menu rozwijane po kliknięciu prawym klawiszem myszki na formularzu lub komponentach

0x08 graphic
Tak

Label

Etykieta. Tworzy etykietę wyświetlającą teksy. Zwykle opisuje inne komponenty na formularzu.

0x08 graphic
Tak

Edit

Pole tekstowe. Tworzy na formularzu obszar, gdzie użytkownik może wprowadzać i modyfikować pojedynczą linię tekstu.

0x08 graphic
Tak

Memo

Memo. Wyświetla obszar w którym użytkownik może wprowadzać i modyfikować wiele linii tekstu.

0x08 graphic
Tak

Button

Przycisk. Tworzy przycisk.

0x08 graphic
Tak

CheckBox

Pole wyboru. Prezentuje opcje typu Tak/ Nie, Wł/Wył, True/False itp.

0x08 graphic
Tak

RadioButton

Przycisk opcji. Zwykle używane w grupach opcji, w których można wybrać tylko jedną opcję.

0x08 graphic
Tak

ListBox

Pole listy. Wyświetla listę, z której można wybrać jeden lub kilka elementów.

0x08 graphic
Tak

ComboBox

Pole kombi. Łączy pole edycji z listą wyboru. Użytkownik może pisać tekst w pole edycji lub wybrać element z listy.

0x08 graphic
Tak

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.

0x08 graphic
Tak

GroupBox

Pole grupy. Grupuje inne komponenty na formularzu.

0x08 graphic
Tak

RadioGroup

Grupa opcji.

0x08 graphic
Tak

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

0x08 graphic
Tak

BitBtn

BitBtn. Tworzy przycisk, na którym dodatkowo można umieścić bitmapę.

0x08 graphic
Tak

SpeedButton

Przyciski z bitmapą (ale bez tekstu), umieszczone na panelu tworzą paski narzędzi.

0x08 graphic
Tak

MaskEdit

Podobny do pola tekstowego, ale dodatkowo potrafi formatować wyświetlaną informację i tworzyć maskę wprowadzania dla danych.

0x08 graphic
Tak

StringGrid

Wyświetla informacje tekstowe w postaci tabeli.

0x08 graphic
Tak

DrawGrid

Wyświetla informacje inne niż teksty w postaci tabeli.

0x08 graphic
Tak

Image

Wyświetla bitmapy, ikony lub pliki w formacie WFM.

0x08 graphic
Tak

Shape

Rysuje geometryczne kształty: elipsę, prostokąt, zaokrąglony prostokąt.

0x08 graphic
Tak

Bevel

Tworzy linie lub prostokąty, które są wypukłe lub wklęsłe (efekt 3D).

0x08 graphic
Tak

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

0x08 graphic
Nie

Timer

Komponent wywołuje zdarzenie OnTimer w określonych przedziałach czasu.

0x08 graphic
Tak

PaintBox

Oferuje prostokątny obszar, na którego kanwie (czyli na nim) możemy rysować, bez obawy wyjścia poza ten obszar.

0x08 graphic
Tak

FileListBox

Wyświetla przewijaną listę plików znajdujących się w bieżącym katalogu.

0x08 graphic
Tak

DirectoryListBox

Wyświetla listę katalogów bieżącego napędu. Zmiana katalogu na liście powoduje zmianę bieżącego katalogu.

0x08 graphic
Tak

DriveComboBox

Wyświetla rozwijaną listę dostępnych napędów. Można tu zmienić bieżący napęd.

0x08 graphic
Tak

FilterComboBox

Służy do tworzenia filtrów, ograniczających zbiór wyświetlanych plików.

0x08 graphic
Tak

MediaPlayer

Wyświetla panel kontrolny do odtwarzania i nagrywania plików AVI, MID i WAV.

0x08 graphic
Tak

OLEContainer

Tworzy obszar do łączenia i osadzania obiektów OLE

0x08 graphic
Nie

DDEClientConv

Komponent do nawiązania połączenia DDE (obszar klienta)

0x08 graphic
Nie

DDEClientItem

Komponent do nawiązania połączenia DDE (określa dane do wymiany - klienta)

0x08 graphic
Nie

DDEServerConv

Komponent do nawiązania połączenia DDE (określa serwer)

0x08 graphic
Nie

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

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:

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 :

n Aby zaznaczyć grupę obiektów:

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ę.

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.

0x08 graphic
ä 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.

ä 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:

n Aby wrócić do formularza wybierz jedną z następujących metod:

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

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.

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:

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.

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.

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 .

0x08 graphic
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

0x08 graphic
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 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.

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

Deklaracje w części prywatnej (private) powodują, że obiekty te są niedostępne w innych modułach. Użyj części prywatnej do

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

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;

0x08 graphic

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.

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.

Tworzenie obiektów niewizualnych.

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.

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 }

0x08 graphic
0x08 graphic
try

{ przydzielenie drugiego zasobu }

0x08 graphic
try

0x08 graphic
{ 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:

0x08 graphic
0x08 graphic
try

{ kod chroniony }

0x08 graphic
try

0x08 graphic
{ 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:

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.

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:

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.

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.

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

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.

Opcje Form desinger

Opcje Debugging

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

Pole tekstowe Search Path określa lokalizację (lokalizacje) bibliotek, które nie są umieszczone w katalogu

Menedżer projektu.

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:

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.

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:

Wykorzystanie szablonów formularzy.

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.

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:

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:

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ń:

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.

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:

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.

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.

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.

0x08 graphic
Tworzenie menu formularzy.

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.

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.

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

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ą:

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 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:

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 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:

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.

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

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

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;

0x08 graphic
Opis wybranych komponentów

Komponenty na stronie Windows 95

Wizualny

Nazwa komponentu

Zastosowanie

0x08 graphic
Tak

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

0x08 graphic
Tak

PageControl

Tworzy stos stron (multiple pages). Często używany z komponentem TabControl.

0x08 graphic
Tak

TreeView

Komponent, który pozwala na wyświetlanie listy obiektów w postaci drzewa, którego poszczególne elementy można rozwijać lub zwijać.

0x08 graphic
Tak

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).

0x08 graphic
Tak

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).

0x08 graphic
Tak

HeaderControl

Jest podzielonym na sekcje komponentem, który wyświetla tekst. Rozmiary każdej części można zmieniać za pomocą myszki.

0x08 graphic
Tak

RichEdit

Pole podobne do memo, ma wbudowane szereg możliwości np. przeciąganie i upuszczanie tekstu za pomocą myszki.

0x08 graphic
Tak

StatusBar

Służy do utworzenia paska statusu.

0x08 graphic
Tak

TrackBar

Pasek, który wskazuje na wartość jakiej zmiennej i umożliwia jej zmianę za pomocą suwaka.

0x08 graphic
0x08 graphic
Tak

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).

0x08 graphic
Tak

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.

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

0x08 graphic
Nie

OpenDialog

Okno służące do otwierania pliku.

0x08 graphic
Nie

SaveDialog

Okno dialogowe do zachowywania pliku.

0x08 graphic
Nie

FontDialog

Okno do zmiany atrybutów czcionki.

0x08 graphic
Nie

ColorDialog

Okno służące do zmiany koloru (z możliwością zdefiniowania własnego dowolnego koloru).

0x08 graphic
Nie

PrintDialog

Otwiera okno służące do drukowania zawartości pliku.

0x08 graphic
Nie

PrinterSetupDialog

Okno dialogowe służące do zmiany ustawień drukarki (np. jakość wydruku)

0x08 graphic
Nie

FindDialog

Tworzy okno służące do wyszukiwania podanego tekstu

0x08 graphic
Nie

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.

0x08 graphic
Dźwięk i multimedia.

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.:

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.

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.

0x08 graphic
Listy tekstów i ich zastosowanie.

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

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:

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.

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;

0x08 graphic
Obsługa 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.

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ć:

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

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

0x01 graphic

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



Wyszukiwarka

Podobne podstrony:
wykladwiadomosciwstepne, Wiadomości wstępne
wykład 1 (wiadomości wstępne)
Matlab wiadomości wstępne
02 Wiadomości wstępne
K02 Wiadomości wstępne – część 2
wiadomości wstępne (1)
K01 Wiadomości wstępne – część 1
Test z wiadomości wstępnych
ściąga polan- zajebista, Wiadomości wstępne
Angielski FCE, Wiadomosci wstepne, JES
wiadomosci wstepne sciaga(2), Dokumenty w-f, Anatomia
Roboty mobilne, Wiadomości wstępne o robotach
Algebra Roszkowska, ALGEBRA LINIOWA CZI, WIADOMOŚCI WSTĘPNE
02 Rozdział 01 Wiadomości wstępne o równaniach różniczkowych
Wiadomości wstępne
69 Motoryka przewodu pokarmowego wiadomości wstępne

więcej podobnych podstron