ABC Delphi 6

38
Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: [email protected] PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ IDZ DO IDZ DO ZAMÓW DRUKOWANY KATALOG ZAMÓW DRUKOWANY KATALOG KATALOG KSI¥¯EK KATALOG KSI¥¯EK TWÓJ KOSZYK TWÓJ KOSZYK CENNIK I INFORMACJE CENNIK I INFORMACJE ZAMÓW INFORMACJE O NOWOCIACH ZAMÓW INFORMACJE O NOWOCIACH ZAMÓW CENNIK ZAMÓW CENNI K CZYTELNIA CZYTELNIA FRAGMENTY KSI¥¯EK ONLINE FRAGMENTY KSI¥¯EK ONLINE SPIS TRECI SPIS TRECI DODAJ DO KOSZYKA DODAJ DO KOSZYKA KATALOG ONLINE KATALOG ONLINE ABC Delphi 6 Autor: Andrzej Daniluk ISBN: 83-7197-504-X Format: B5, stron: 136 Przyk³ady na ftp: 1002 kB Delphi 6 to kolejna wersja popularnego rodowiska programistycznego firmy Borland, s³u¿¹cego do szybkiego tworzenia aplikacji za pomoc¹ jêzyka ObjectPascal. W Delphi napisano ju¿ wiele profesjonalnych aplikacji, co nie oznacza, i¿ jest ono rodowiskiem wy³¹cznie dla zawodowców. Wrêcz przeciwnie, dziêki prostocie obs³ugi i zaletom wzorowanego na Pascalu jêzyka ObjectPascal, jest ono doskona³ym narzêdziem dla pocz¹tkuj¹cych programistów, tak¿e dla tych, którzy nie mieli wczeniej wiele wspólnego z programowaniem obiektowym. Dla nich w³anie przeznaczona jest ta ksi¹¿ka omawiaj¹ca: Podstawy programowania w jêzyku ObjectPascal Projektowanie zorientowane obiektowo (OOD) Zintegrowane rodowisko programistyczne ObjectPascal w wydaniu Delphi 6 Biblioteki VCL i CLX Tworzenie w³asnych komponentów Biblioteki DLL Pomoc¹ w zg³êbianiu tajników Delphi 6 jest 19 kompletnych przyk³adowych projektów, ilustruj¹cych najwa¿niejsze æwiczenia. Po przeczytaniu „ABC Delphi 6”, bêdziesz móg³ samodzielnie pisaæ aplikacje dzia³aj¹ce w rodowisku Windows. Ksi¹¿ka stanowi tak¿e doskona³y wstêp do innych, bardziej zaawansowanych pozycji, omawiaj¹cych Delphi.

description

Delphi 6 to kolejna wersja popularnego środowiska programistycznego firmy Borland, służącego do szybkiego tworzenia aplikacji za pomocą języka ObjectPascal. W Delphi napisano już wiele profesjonalnych aplikacji, co nie oznacza, iż jest ono środowiskiem wyłącznie dla zawodowców. Wręcz przeciwnie, dzięki prostocie obsługi i zaletom wzorowanego na Pascalu języka ObjectPascal, jest ono doskonałym narzędziem dla początkujących programistów, także dla tych, którzy nie mieli wcześniej wiele wspólnego z programowaniem obiektowym. Dla nich właśnie przeznaczona jest ta książka omawiająca: * Podstawy programowania w języku ObjectPascal * Projektowanie zorientowane obiektowo (OOD) * Zintegrowane środowisko programistyczne * ObjectPascal w wydaniu Delphi 6 * Biblioteki VCL i CLX * Tworzenie własnych komponentów * Biblioteki DLLPomocą w zgłębianiu tajników Delphi 6 jest 19 kompletnych przykładowych projektów, ilustrujących najważniejsze ćwiczenia. Po przeczytaniu "ABC Delphi 6", będziesz mógł samodzielnie pisać aplikacje działające w środowisku Windows. Książka stanowi także doskonały wstęp do innych, bardziej zaawansowanych pozycji, omawiających Delphi.

Transcript of ABC Delphi 6

Page 1: ABC Delphi 6

Wydawnictwo Helion

ul. Chopina 6

44-100 Gliwice

tel. (32)230-98-63

e-mail: [email protected]

PRZYK£ADOWY ROZDZIA£PRZYK£ADOWY ROZDZIA£

IDZ DOIDZ DO

ZAMÓW DRUKOWANY KATALOGZAMÓW DRUKOWANY KATALOG

KATALOG KSI¥¯EKKATALOG KSI¥¯EK

TWÓJ KOSZYKTWÓJ KOSZYK

CENNIK I INFORMACJECENNIK I INFORMACJE

ZAMÓW INFORMACJEO NOWO�CIACH

ZAMÓW INFORMACJEO NOWO�CIACH

ZAMÓW CENNIKZAMÓW CENNIK

CZYTELNIACZYTELNIA

FRAGMENTY KSI¥¯EK ONLINEFRAGMENTY KSI¥¯EK ONLINE

SPIS TRE�CISPIS TRE�CI

DODAJ DO KOSZYKADODAJ DO KOSZYKA

KATALOG ONLINEKATALOG ONLINE

ABC Delphi 6

Autor: Andrzej Daniluk

ISBN: 83-7197-504-X

Format: B5, stron: 136

Przyk³ady na ftp: 1002 kB

Delphi 6 to kolejna wersja popularnego �rodowiska programistycznego firmy Borland,

s³u¿¹cego do szybkiego tworzenia aplikacji za pomoc¹ jêzyka ObjectPascal. W Delphi

napisano ju¿ wiele profesjonalnych aplikacji, co nie oznacza, i¿ jest ono �rodowiskiem

wy³¹cznie dla zawodowców. Wrêcz przeciwnie, dziêki prostocie obs³ugi i zaletom

wzorowanego na Pascalu jêzyka ObjectPascal, jest ono doskona³ym narzêdziem dla

pocz¹tkuj¹cych programistów, tak¿e dla tych, którzy nie mieli wcze�niej wiele

wspólnego z programowaniem obiektowym.

Dla nich w³a�nie przeznaczona jest ta ksi¹¿ka omawiaj¹ca:

• Podstawy programowania w jêzyku ObjectPascal

• Projektowanie zorientowane obiektowo (OOD)

• Zintegrowane �rodowisko programistyczne

• ObjectPascal w wydaniu Delphi 6

• Biblioteki VCL i CLX

• Tworzenie w³asnych komponentów

• Biblioteki DLL

Pomoc¹ w zg³êbianiu tajników Delphi 6 jest 19 kompletnych przyk³adowych projektów,

ilustruj¹cych najwa¿niejsze æwiczenia. Po przeczytaniu „ABC Delphi 6”, bêdziesz móg³

samodzielnie pisaæ aplikacje dzia³aj¹ce w �rodowisku Windows. Ksi¹¿ka stanowi tak¿e

doskona³y wstêp do innych, bardziej zaawansowanych pozycji, omawiaj¹cych Delphi.

Page 2: ABC Delphi 6

Spis treści

Wstęp ............................................................................................... 5

Rozdział 1. Elementarz Object Pascala................................................................. 7Moduły ................................................................................................................................7

Program główny ..................................................................................................................8

Stałe...................................................................................................................................10

Zmienne.............................................................................................................................11

Typy całkowite..................................................................................................................12

Typy rzeczywiste...............................................................................................................12

Typ Currency.....................................................................................................................13

Typy logiczne....................................................................................................................13

Typy znakowe ...................................................................................................................13

Typy łańcuchowe ..............................................................................................................14

Literały łańcuchowe ..........................................................................................................14

Tablice...............................................................................................................................15

Rekordy .............................................................................................................................16

Typ okrojony .....................................................................................................................18

Typ mnogościowy.............................................................................................................18

Typ wyliczeniowy.............................................................................................................19

Typ Variant .......................................................................................................................19

Operatory...........................................................................................................................20

Wskazania i adresy............................................................................................................21

Instrukcje sterujące przebiegiem programu ......................................................................22

Instrukcja warunkowa If...Then ..................................................................................22

Instrukcja warunkowa Case...Of.................................................................................23

Instrukcja iteracyjna Repeat...Until ............................................................................24

Instrukcja iteracyjna While...Do .................................................................................25

Instrukcja iteracyjna For...To...Do..............................................................................26

Procedura przerwania programu Break ......................................................................26

Procedura przerwania programu Exit .........................................................................27

Procedura wyjścia z programu Halt ............................................................................27

Procedura zatrzymania programu RunError ...............................................................27

Procedura kontynuacji programu Continue ................................................................28

Procedury ..........................................................................................................................28

Parametry formalne.....................................................................................................29

Funkcje ..............................................................................................................................31

Moduły na poważnie .........................................................................................................32

Podsumowanie ..................................................................................................................34

Page 3: ABC Delphi 6

4 ABC Delphi 6

Rozdział 2. Projektowanie obiektowe OOD ......................................................... 35Klasa ...........................................................................................................................35

Obiekt..........................................................................................................................35

Metody ........................................................................................................................36

Widoczność obiektów.................................................................................................36

Współdziałanie obiektów............................................................................................36

Implementacja obiektu................................................................................................36

Dziedziczenie..............................................................................................................36

Podsumowanie ..................................................................................................................36

Rozdział 3. Środowisko programisty — IDE ........................................................ 37Biblioteka VCL .................................................................................................................39

Karta Standard ............................................................................................................40

Karta Additional..........................................................................................................41

Karta Win32................................................................................................................43

Karta System...............................................................................................................45

Karta Dialogs ..............................................................................................................46

Biblioteka CLX .................................................................................................................47

Karta Additional..........................................................................................................48

Karta Dialogs ..............................................................................................................48

Podsumowanie ..................................................................................................................48

Rozdział 4. Object Pascal w wydaniu Delphi ....................................................... 49Formularz ..........................................................................................................................49

Zdarzenia...........................................................................................................................51

Wykorzystujemy własne funkcje i procedury...................................................................56

Metody przeciążane...........................................................................................................58

Wyjątki ..............................................................................................................................60

Operacje na plikach...........................................................................................................65

Strukturalna obsługa wyjątków.........................................................................................71

Tablice otwarte..................................................................................................................72

Tablice dynamiczne...........................................................................................................73

Typ OleVariant..................................................................................................................74

Rekordy w Delphi .............................................................................................................76

Podsumowanie ..................................................................................................................83

Rozdział 5. Biblioteka VCL................................................................................. 85Komponenty TActionList, TImageList, TOpenDialog, TSaveDialog i TMainMenu ......85

Komponenty TActionManager i TActionMainMenuBar .................................................91

Komponenty TFrame, TSpinEdit i TStaticText................................................................96

Hierarchia własności obiektów. Właściciele i rodzice....................................................100

Konstruktor i Destruktor ...........................................................................................102

Podsumowanie ................................................................................................................103

Rozdział 6. Biblioteka CLX............................................................................... 105Komponenty TTimer i TLCDNumber ............................................................................105

Podsumowanie ................................................................................................................109

Rozdział 7. Tworzymy własne komponenty ....................................................... 111Podsumowanie ................................................................................................................117

Rozdział 8. Biblioteki DLL ................................................................................ 119Podsumowanie ................................................................................................................126

Skorowidz...................................................................................... 127

Page 4: ABC Delphi 6

Rozdział 4.

Object Pascalw wydaniu Delphi

Rozdział ten poświęcony jest omówieniu praktycznych sposobów wykorzystania po-znanych wcześniej elementów języka Object Pascal w graficznym środowisku Delphi 6.Zapoznamy się tutaj m. in. z pojęciem formularza, wyjątku czy procedury obsługi zda-rzenia. Poznamy również metody wykorzystania w aplikacji własnych funkcji i proce-dur. Zastosowanie omówionych elementów Delphi zostanie zilustrowane odpowied-nimi ćwiczeniami.

Formularz

Formularz jest pierwszym obiektem, z którym spotykamy się, rozpoczynając pisanieaplikacji. Po dwukrotnym kliknięciu w obszarze formularza dostajemy się do oknaedycji kodu modułu Unit1.pas, który pokazany jest na rysunku 4.1.

Object Pascal oferuje nam słowo kluczowe �����, pozwalające na tworzenie obiektów.Przykładowa definicja klasy formularza wygląda następująco:

������������� ��������������� ������������������������� ����������������� �������� ���������!������� ������ ���� ��� ���������!������

Zdefiniowana klasa dziedziczy własności bazowej klasy formularza TForm, natomiastsam formularz, traktowany jako zmienna obiektowa, deklarowany jest jako:

��������������

Page 5: ABC Delphi 6

50 ABC Delphi 6

Rysunek 4.1.

Okno edycji kodu

głównego modułu

aplikacji

Z zapisu tego odczytamy, iż formularz jest zmienną obiektową, natomiast nazwa kla-sy stała się nowym specyfikatorem typu danych.

W definicji klasy możemy zauważyć procedurę:

�� ������������������������� ���

Delphi odpowiednio inicjuje formularz (tylko jeden raz), kiedy jest on tworzony poraz pierwszy. Sender jest pewną zmienną typu TObject, wołaną przez wartość. W rze-czywistości Sender reprezentuje pewną właściwość, polegającą na tym, iż każdyobiekt łącznie z formularzem (oraz każdy obiekt VCL i CLX) musi być w pewiensposób poinformowany o przyszłym przypisaniu mu pewnego zdarzenia (w przypad-ku formularza zdarzenie to polega na jego inicjalizacji).

TObject jest bezwzględnym przodkiem wszystkich komponentów i obiektów VCLoraz CLX i umieszczony jest na samym szczycie hierarchii obiektów.

Z rysunku 4.1 możemy odczytać, iż standardowa definicja klasy składa się z kilku czę-ści. Sekcja public służy do deklarowania funkcji i procedur (czyli metod) oraz zmien-nych (zwanych polami), które w przyszłości mogą być udostępniane innym. Zasadni-czą różnicą pomiędzy metodami a zwykłymi funkcjami czy procedurami jest to, żekażda metoda posiada niejawny parametr Self, wskazujący na obiekt będący przed-miotem wywołania tej metody. Sekcję public często nazywamy interfejsem obiektu.Sekcja private przeznaczona jest dla pól i metod widzianych jedynie wewnątrz klasy.

Page 6: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 51

Oprócz elementów wymienionych, definicja klasy może posiadać jeszcze sekcje pro-tected oraz published. W części protected można definiować pola i metody widocznedla macierzystej klasy i klas po niej dziedziczących. Deklaracje zawarte w sekcji pu-blished (publikowanej) pełnią taką samą rolę, jak deklaracje umieszczone w sekcjipublic (publicznej). Różnica pomiędzy nimi polega na tym, iż te pierwsze nie tworzątzw. informacji czasu wykonania.

Zdarzenia

Zdarzenie (ang. event) określane jest jako zmiana, która występuje w aktualnym sta-nie obiektu i jest źródłem odpowiednich komunikatów, przekazywanych do aplikacjilub bezpośrednio do systemu. Reakcja obiektu na wystąpienie zdarzenia udostępnianajest aplikacji poprzez procedurę obsługi zdarzeń (ang. event procedure) będącą wy-dzieloną częścią kodu. Rolę zdarzeń w aplikacji najlepiej jest prześledzić, wykonującpraktyczne ćwiczenie.

Tradycyjnie już założymy na dysku nowy katalog. Po uruchomieniu Delphi 6 znany-mi nam już poleceniami menu zapiszmy w nim główny moduł aplikacji, który na-zwiemy Unit_08.pas. Zapiszmy również projekt aplikacji pod nazwą Projekt_08.dpr.

Rozmiary formularza ustalimy, korzystając z cech Height (wysokość) i Width (szero-kość), znajdujących się w karcie właściwości (Properties) Inspektora Obiektów. Jeżelichcemy, aby po uruchomieniu formularz nie „rozpływał” się po ekranie w odpowie-dzi na kliknięcie pola maksymalizacji, w Inspektorze Obiektów rozwińmy cechę Con-straints (ograniczenie) i we właściwe miejsca wpiszmy żądane rozmiary formularza(w pikselach), tak jak pokazano na rysunku 4.2.

Rysunek 4.2.

Ograniczenie

rozmiarów

formularza

Przejdźmy następnie do cechy Position i wybierzmy poScreenCenter. Wybrane przy-pisanie spowoduje, że w momencie uruchomienia aplikacji formularz pozostaniew centrum ekranu (ale nie pulpitu poDesktopCenter); jeżeli oczywiście w InspektorzeObiektów cechy Align (zakotwiczenie) nie ustawiliśmy inaczej niż w pozycji alNone.

Na tak przygotowanym formularzu umieśćmy teraz dwa komponenty reprezentująceklasę TButton z karty Standard. Korzystając z Inspektora Obiektów oraz z karty wła-ściwości, cechy Caption przycisków Button1 oraz Button2 zmieńmy odpowiednio na&Zamknij i &Tekst. Znak &, który występuje w nazwach przycisków, spowoduje, żelitera, występująca bezpośrednio za nim, stanowić będzie klawisz szybkiego dostępudo procedury obsługi wybranego zdarzenia. W podobny sposób możemy zmienić ce-chy Font wybranych przycisków. Dla każdego z przycisków stworzymy proceduręobsługi odpowiedniego zdarzenia. Klikając dwukrotnie przycisk Zamknij lub w wido-ku drzewa obiektów (Object TreeView) odpowiednio oznaczony komponent, dosta-niemy się do wnętrza właściwej procedury obsługi zdarzenia:

Page 7: ABC Delphi 6

52 ABC Delphi 6

�� ���������"#��������� $������������� �����%������

Już w tym miejscu możemy zauważyć, iż w definicji klasy program Delphi wygene-rował automatycznie deklarację przycisku oraz deklarację procedury obsługującegogo zdarzenia. Korzystając z notacji kropkowej, kompilator automatycznie został poin-formowany, do której klasy należy wywoływana procedura.

Użycie notacji kropkowej stanowi informację dla kompilatora, że przykładowa pro-cedura Button1Click() należy do przykładowej klasy TForm1 (jest metodą zdefinio-waną w klasie TForm1).

Należy zawsze pamiętać, iż szkielety procedur obsługi odpowiednich zdarzeń, np. ta-kich jak ��������� ��, zostaną automatycznie wygenerowane przez Delphi w od-powiedzi na dwukrotne kliknięcie danego przycisku. W żadnym wypadku procedurtych nie należy wpisywać samodzielnie.

Omawianą procedurę obsługi zdarzenia wypełnimy przedstawionym poniżej kodem,co spowoduje, że po naciśnięciu wybranego przycisku aplikacja zostanie zamknięta.

�� ���������"#��������� $������������� �����%����&���� �����"��������������

Każdy standardowy program Delphi (oparty na formularzu) zawiera pewną zmiennąglobalną o nazwie Application typu TApplication. W czasie tworzenia nowego pro-jektu Delphi konstruuje obiekt aplikacji i przypisuje mu właśnie zmienną Application.Obiekty klasy TApplication przechowują informacje odnośnie zasad współpracy apli-kacji z systemem operacyjnym. Informacje te dotyczą np. rozpoczynania i kończeniadziałania aplikacji czy tworzenia okna głównego programu. Istnieje wiele metod kla-sy TApplication. Jedną z nich jest ����������, umożliwiająca zamknięcie aplikacji.

Zajmiemy się teraz zaprojektowaniem procedury obsługi zdarzenia przycisku Button2,który nazwaliśmy Tekst. Po kliknięciu tego przycisku, bezpośrednio na formularzuzostanie wyświetlony prosty tekst. Skorzystamy z tego, iż formularz, będący w istocieteż komponentem, posiada swoje własne płótno (ang. canvas), reprezentowane przezklasę TCanvas, posiadającą właściwość Canvas. Procedura obsługi naszego zdarzeniabędzie wyglądać następująco:

�� ���������"#�����'��� $������������� �����%����������"����"������ �#������������"����"(��%)���*+���������"��,�����������(��%)������-.������/���)�����-.�����������������0� ��1�2������$� ���1�3���)��40������

Powyższy przykład ilustruje sposób odwoływania się do obszaru płótna poprzez wła-ściwość Canvas klasy TCanvas z wykorzystaniem właściwości czcionka (Font). Za-stosowana metoda ���������:

�� �������,�����5.�6��7���%��� �������,�������%��

Page 8: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 53

pozwala na umieszczenie dowolnego tekstu identyfikowanego przez stałą Textw miejscu formularza o współrzędnych X, Y (odległość liczona jest w pikselach, na-tomiast lewy górny róg formularza posiada współrzędne 0, 0).

Może również zdarzyć się i taka sytuacja, w której zechcemy zamknąć formularz, ko-rzystając bezpośrednio z jego pola zamknięcia (por. rysunek 3.2). Zamykając w tensposób działającą aplikację, należy mieć na uwadze fakt, iż w Windows 9x bezpo-średni sposób zamknięcia działającego programu może nie działać w pełni poprawnie(nie dotyczy to Win 2000, NT i XP). Aby mieć pewność, że w momencie zamknięciaaplikacji wszystkie jej zasoby zostaną prawidłowo zwolnione, skorzystamy ze zda-rzenia ������. Klikając (tylko raz) w obszar formularza w inspektorze obiektów,przejdźmy do zakładki Events (zdarzenia). Zdarzenie ������ określmy jako ���������� (rysunek 4.3) i potwierdźmy klawiszem Enter.

Rysunek 4.3.

Zdarzenie OnClose

W ten sposób Delphi automatycznie wygeneruje procedurę obsługi zdarzenia

�������������������� �������& ������������& ������

Zmiennej ����� (akcja) można tutaj przypisać jeden z elementów typu wyliczeniowego

����������& �������� �8���.� �(���.� ����.� �9����2���

gdzie:

� ����� oznacza, że formularz nie zostanie zamknięty;

� ������ oznacza, że formularz nie zostanie zamknięty, lecz ukryty;

� ������ oznacza, że formularz zostanie zamknięty z jednoczesnymzwolnieniem wszystkich zasobów pamięci, z których aktualnie korzysta;

� ��������� oznacza, że formularz zostanie zminimalizowany.

Page 9: ABC Delphi 6

54 ABC Delphi 6

Procedurę obsługi zdarzenia ����������� wypełnimy następującym kodem:

�� ���������"�������������������� �����& ������������& ��������%���� �����9����%�#�,�+.�0:�$��; �������$� ���<0.0=1�%�0.��������9#>6?�8����9#>7��8@=?��7�8����A�����73>6?����������& �������� ����������73>8����������& �������� �8��������������

Skorzystaliśmy tutaj z omawianej wcześniej instrukcji ��������� oraz z funkcji ������ ������, wyświetlającej odpowiedni komunikat w okienku dialogowym.

Projekt aplikacji Projekt_08.dpr, wykorzystującej omawiane zdarzenia, znajduje sięw katalogu Kody\08\, natomiast na wydruku 4.1 zamieszczono kod źródłowy modułuUnit_08.pas.

Wydruk 4.1. Moduł Unit_08.pas projektu Projekt_08.dpr

�����=���>+B�

����A� �

����/����1�.�9����%��.����=����.��������.C��)� �.��������.����.�#������.��������

����������� ���������#���������#������#�����'���#�������� �����#��������� $������������� ����� �����#�����'��� $������������� ���

�� ������������������������� ������& ������������& ������

�������� �������� ���������!����� �� ���� ��� ���������!����

������������

������������

�DE�F"3�9!

GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"#�����'��� $������������� �����%��

Page 10: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 55

��������"����"������ �#������������"����"(��%)���*+���������"��,�����������(��%)������-.������/���)�����-.�����������������0� ��1�2������$� ���1�3���)��40������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"�������������������� ������& ������������& ��������%���� �����9����%�#�,�+.�0:�$��; �������$� ���<0.0=1�%�0.��������9#>6?�8����9#>7��8@=?��7�8����A�����73>6?���������& �������� ����������73>8���������& �������� �8��������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"#��������� $������������� �����%�����&���� �����"��������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH���"

Zajrzyjmy teraz do katalogu, w którym został zapisany nasz projekt. Oprócz plików,wymienionych w rozdziale 1, pojawiły się tam 3 dodatkowe:

� .dpp — plik Diagram Delphi Page. Można w nim zapisać diagramy będącewizualizacją logicznych relacji pomiędzy widocznymi i niewidocznymikomponentami, składającymi się na całość projektu. Relacje takie możnauzyskać, korzystając z zakładki Diagram.

� .dfm — plik zawierający opis formularza. Dyrektywa kompilatora !"#$lub !"#%&�'#�%$ dołącza do projektu zewnętrzny plik zasobów, zawierającyopis formularza. Plik zasobów jest włączany do końcowego plikuwynikowego .exe w czasie łączenia projektu.

� .res — plik zasobów Windows.

Żadnego z nich nie powinnyśmy utracić.

Plik projektu Delphi .dpr środowiska graficznego różni się nieco od swojego odpowied-nika aplikacji konsolowych. Programy Delphi są bardzo krótkie. Wynika to z faktu, iżaplikacje z interfejsem graficznym zazwyczaj wywołują procedurę inicjalizacyjną �(�(��������)����������, następnie tworzony jest formularz (lub formularze) Applica-tion.CreateForm(TForm1,Form1), w którym uruchamiane są procedury obsługi zdarzeń�((��������#���. Aplikacja zamykana jest poprzez główny formularz w odpowiedzina wywołanie procedury obsługi odpowiedniego zdarzenia �((������������������(patrz wydruk 4.1). Typowy plik kodu źródłowego projektu Delphi przedstawiony jestna wydruku 4.2.

Page 11: ABC Delphi 6

56 ABC Delphi 6

Wydruk 4.2. Typowy plik programu Delphi

��%�� ���$�>+B�

�������.=���>+B����0=���>+B"���0�����!�

�DE�F"E?�!

��%����&���� �����"7�������2����&���� �����"������������.��������&���� �����"E������"

Deklaracja ���� tworzy listę modułów wchodzących w skład programu. Nazwa modułumoże być poprzedzona dyrektywą �, specyfikującą nazwę pliku. Moduły bez dyrek-tywy � są modułami bibliotecznymi i nie stanowią części kodu źródłowego projektu.

Wykorzystujemy własne funkcjei procedury

Własne procedury i funkcje możemy umieszczać w programie Delphi na parę sposobów.Zapoznamy się teraz z dwoma sposobami — najprostszymi i najczęściej stosowanymi.

Definicję funkcji lub procedury umieszczamy bezpośrednio w kodzie programu w sekcjiimplementacji modułu:

���������������������������DE�F"�A!�� ����� �1�'��8����,��7���%������7���%��������.2��7���%����%����2������A�������������������%�������2��2F,���������"9���"I����"&���7�������,�J0�������;%��0J���������������������7���������J0�0J7�������2��������������

Wyświetlanie kolejnych liczb całkowitych, będących kolejnymi potęgami całkowitegoparametru x, dokonywane jest w komponencie edycyjnym Memo1, będącym reprezen-tantem klasy TMemo z karty Standard. Ponieważ nasza procedura nie została zadeklaro-

Page 12: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 57

wana w definicji klasy formularza, więc odwołanie się w jej wnętrzu do odpowiedniegokomponentu edycyjnego wymaga, aby jawnie wskazać, iż komponent ten należy doformularza Form1. Wyświetlanie kolejnych liczb całkowitych dokonywane jest za po-średnictwem funkcji )���&���� formatującej wartość liczbową (wartość w postaciliczby całkowitej) na odpowiedni łańcuch znaków.

Dużo subtelniejszym (ale nie zawsze opłacalnym sposobem) jest uczynienie funkcjilub procedury jawnym obiektem klasy formularza TForm1. Należy wówczas definicjęnagłówkową funkcji lub procedury uzupełnić o nazwę klasy, do której ma przynale-żeć. Musimy ponadto omawiane funkcje lub procedury zadeklarować w definicji klasyw jednej z sekcji, np.

������������� �������������#���������#����������9������9�������#�����'���#����������#�����*���#������������ �����#��������� $������������� ��������� �����#�����'��� $������������� ��������� �����#�����*��� $������������� ����������������� �������� ���������!������ ����� �1�'��8�,.������������������ ������ ���� ��� ���������!���������������������������������DE�F"�A!GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������" �1�'��8�,.������������������.�2������������%����2������A�������������������%�������2��2F,������9���"I����"&���7�������,�J0�������;%��0J���������������������7���������J0�0J7�������2��������������

Korzystając z tego sposobu definiowania własnej funkcji lub procedury, możemy we-wnątrz nich bez problemów odwoływać się do innych obiektów formularza. Wszystkiewłasności, cechy, zdarzenia i metody właściwe tym obiektom będą widoczne w na-szej funkcji lub procedurze.

Page 13: ABC Delphi 6

58 ABC Delphi 6

Metody przeciążane

Chociaż można przypuszczać, iż pojęcia procedur lub funkcji przeciążanych (przeła-dowywanych) należy wprowadzać na bardziej zaawansowanym kursie programowa-nia, to jednak wydaje się, iż w sytuacji kiedy środowiska programistyczne stają sięcoraz bardziej rozbudowane, powinniśmy posiadać pewne wiadomości na ten temat.Jest to szczególnie ważne w momencie, kiedy zechcemy samodzielnie posługiwać sięplikami pomocy.

Pisząc programy w Delphi, możemy zadeklarować wiele funkcji czy procedur o tejsamej nazwie, ale o różnej postaci argumentów. W momencie wywołania danej proce-dury czy funkcji kompilator powinien je rozróżniać. Do deklaracji procedur (funkcji)przeładowywanych służy dyrektywa �*������ (przeładowanie). Najlepszym (i jedy-nym) sposobem zapoznania się z ideą funkcji (procedur) przeładowywanych jest samo-dzielne napisanie prostej aplikacji, w której funkcje te zostaną wykorzystane. Stworzy-my program wykorzystujący znane nam już procedury obliczające kolejne całkowitepotęgi wybranej liczby, ale w ten sposób, by jednocześnie można było korzystać z pro-cedur, których parametry wołane są przez zmienną i przez wartość. Przy okazji zapo-znamy się z podstawowymi własnościami komponentu edycyjnego TMemo.

W skład formularza projektu Kody\09\Projekt_09.dpr będą wchodzić trzy przyciskibędące reprezentantami klasy TButton oraz jeden reprezentant klasy TMemo. Umie-śćmy je na formularzu w sposób pokazany na rysunku 4.4. W inspektorze obiektówwłaściwość Caption formularza Form1 zmieńmy na Projekt_09.

Rysunek 4.4.Podstawoweelementy formularzaprojektu Projekt_09.dpr

W inspektorze obiektów własności Caption komponentów Button1, Button2 i Button3zmieńmy odpowiednio na &Oblicz — wywołanie przez zmienną, &Zamknij i O&blicz— wywołanie przez wartość. Można również skorzystać z ich własności Font, abydobrać odpowiednią czcionkę. Należy oczywiście pamiętać o uprzednim zaznaczeniuwybranego komponentu, np. poprzez pojedyncze kliknięcie go myszą.

Ponieważ należy się spodziewać, iż w komponencie edycyjnym Memo1 będą wyświe-tlane kolejne liczby, musimy zadbać o możliwość pionowego przewijania zawartościtego komponentu. W tym celu w inspektorze obiektów jego właściwość ScrollBarsustalmy jako ssVertical. Jeżeli zechcemy, aby zawartość komponentu mogła być prze-wijana zarówno w pionie, jak i w poziomie, wystarczy wybrać ssBoth.

Page 14: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 59

W momencie wybrania reprezentanta klasy TMemo, w oknie edycji zobaczymy jegonazwę. Aby nie była ona wyświetlana, należy skorzystać z własności Lines i poprzezTStrings w oknie edytora skasować napis Memo1. Kiedy wszystkie potrzebne kom-ponenty zostaną już rozmieszczone na formularzu, możemy jego rozmiary odpowied-nio do nich dopasować. W tym celu w inspektorze obiektów jego własności AutoSizewystarczy przypisać wartość True.

Po tych wstępnych czynnościach nie pozostaje nam nic innego jak zaimplementowaćw programie dwie procedury +�,��-��.�� obliczające kolejne całkowite potęgi Y wy-branej liczby całkowitej X. Musimy również wypełnić treści procedur odpowiednichzdarzeń, podobnie jak zostało to pokazane na wydruku 4.3.

Wydruk 4.3. Kod głównego modułu Unit_09.pas projektu Projekt_09.dpr, wykorzystującegoprzeciążane procedury

�����=���>+K�

����A� �

������/����1�.�9����%��.����=����.�L������.���������.�C��)� �.��������.����.��3����%�.���������

������������� �������������#���������#����������9������9�������#�����'���#����������#�����*���#������������ �����#��������� $������������� ��������� �����#�����'��� $������������� ��������� �����#�����*��� $������������� ����������������� �������� ���������!������ ����� �1�5��6�,.��������������������������� ����� �1�5��6����,.����7���%������������������ ������ ���� ��� ���������!������

��������������

������������

�DE�F"�A!

�� ���������" �1�5��6����,.����7���%��������.2��7���%����%����2������A�������������������%�������2��2F,�

Page 15: ABC Delphi 6

60 ABC Delphi 6

�����9���"I����"&���7�������,�J0�������;%��0J���������������������7���������J0�0J7�������2��������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������" �1�5��6�,.������������������.2������������%����2������A�������������������%�������2��2F,������9���"I����"&���7�������,�J0�������;%��0J���������������������7���������J0�0J7�������2��������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"#��������� $������������� �������.����7���%����%����9���"������������*������+��� �1�5��6��.�������GG1�1�M������2�2�2����N����GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"#�����*��� $������������� �����%����9���"��������� �1�5��6�'.��+���GG1�1�M������2�2�1���OP����GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"#�����'��� $������������� �����%�����&���� �����"�����������������"

Program skompilujemy, korzystając z klawisza F9 lub opcji menu Run, Run. Śledząckod programu, możemy też zauważyć, iż w celu skasowania zawartości komponentuMemo1 posługujemy się metodą �������.

Wyjątki

Podobnie jak w przypadku metod przeciążanych, ktoś mógłby powątpiewać w celowośćwprowadzania pojęcia wyjątku w kursie programowania, przeznaczonym dla osóbmniej zaawansowanych. Należy jednak zdawać sobie sprawę z faktu, iż wyjątki jakoobiekty pełnią bardzo ważną rolę we wszystkich współczesnych systemach operacyj-nych oraz środowiskach programowania i pewne własności kompilatora, które jeszczedo niedawna uważano za bardzo zaawansowane, obecnie już takimi być przestają.

Page 16: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 61

Wyjątki pozwalają osobie piszącej kod na uwzględnienie sytuacji, w której programw jakimś momencie wykonywania może ulec niekontrolowanemu zakończeniu. Wy-jątek może być umiejscowiony w dowolnej metodzie. W Delphi podstawową klasą,zajmującą się obsługą wyjątków, jest Exception (ang. wyjątek). Klasa ta wywodzi siębezpośrednio z klasy TObject. Z kolei z Exception (chodź nie bezpośrednio) wywodzisię klasa EMathError, będąca z kolei nadklasą (klasą bazową) dla zbioru niezwykleużytecznych klas, obsługujących wyjątki, powstałe przy wykryciu przez kompilatorbłędów operacji matematycznych na liczbach zmiennopozycyjnych (liczbach dzie-siętnych). Wyjątki dziedziczące z EMathError zostały przedstawione w tabeli 4.1.

Tabela 4.1. Klasy dziedziczące z EMathError

Klasa wyjątku Znaczenie

?7������&%���� Przekroczenie zakresu zmienności zadeklarowanego typu danych

?7�������� Nieprawidłowa operacja zmiennoprzecinkowa

?���A��1 Przekroczenie zakresu typu zmiennoprzecinkowego

?=���A��1 Wartość typu zmiennoprzecinkowego jest zbyt mała

?:��3����� Zmiennoprzecinkowe dzielenie przez zero

Delphi posługuje się dwoma wyrażeniami przeznaczonymi do obsługi wyjątków.Z pierwszym, a zarazem podstawowym z nich, zapoznamy się obecnie. Wyrażenie��/�������(������ uaktywnia procedurę obsługi wyjątku przejmującą kontrolę naddalszym wykonywaniem programu, w przypadku gdy zostanie wykonana jakaś nie-dozwolona operacja. Jako przykład niech nam posłuży prosty algorytm wykonującyoperację zmiennopozycyjnego dzielenia dwóch liczb, które wprowadzimy do odpo-wiednich komponentów edycyjnych. Bez trudu możemy przewidzieć, iż wyjątek po-wstanie przy próbie wykonania dzielenia na znakach nie będących liczbami lub przypróbie dzielenia przez zero.

Zaprojektujmy bardzo prostą aplikację, wykonującą zmiennopozycyjne dzielenie dwóchliczb, wprowadzanych z klawiatury do dwóch nowoczesnych komponentów edycyj-nych LabeledEdit1 i LabeledEdit2. Wynik będzie przechowywany w komponencieLabeledEdit3.

Stwórzmy nowy formularz projektu Projekt_10.dpr, w skład którego wchodzić będądwa przyciski (reprezentujące klasę TButton) oraz trzy komponenty edycyjne (repre-zentujące klasę TLabeledEdit z karty Additional). W inspektorze obiektów właściwo-ściom Text komponentów LabeledEdit1 i LabeledEdit2 przypiszmy wartości 0,0, abyich cechy Text nie posiadały wartości nieokreślonej. Cechę Text komponentu Labele-dEdit3 wykasujmy. Komponenty reprezentujące klasę TLabeledEdit posiadają moż-liwość automatycznego ich opisu. Są one jakby połączeniem komponentów z klasTLabel i TEdit. Rozwijając w inspektorze obiektów opcje właściwości EditLabelkomponentu LabeledEdit1 (obok nazwy właściwości w inspektorze obiektów pojawisię znaczek „–”) opiszmy jego cechę Caption jako Liczba 1. Podobnie opiszemywszystkie komponenty edycyjne, tak jak przedstawiono to na rysunku 4.5.

Page 17: ABC Delphi 6

62 ABC Delphi 6

Rysunek 4.5.

Rozmieszczenie i opis

komponentów

reprezentujących

klasę TLabeledEdit

Bardzo często korzystanie z różnego rodzaju komponentów ułatwiają nam dymkipodpowiedzi (ang. hint). Jeżeli zechcemy je zastosować na potrzeby naszych okienekedycji, musimy zamknąć opcje właściwości EditLabel (obok nazwy tej właściwościw inspektorze obiektów pojawi się znaczek „+”). Zaznaczmy myszką wybrany kom-ponent i odszukajmy w inspektorze obiektów jego właściwość Hint, którą opiszemyjako Podaj pierwszą liczbę. Aby dymek podpowiedzi był rzeczywiście widoczny w trak-cie działania programu, właściwości ShowHint należy nadać wartość ����. Analo-gicznie postąpimy z następnym komponentem edycyjnym.

Przystąpmy obecnie do wypełniania głównego modułu Unit_10.pas naszego formula-rza odpowiednim kodem. W sekcji implementacji modułu zadeklarujmy własną klasęEFloatingPointError (wyjątek dzielenia zmiennopozycyjnego) przechwytującą wy-jątki, która będzie dziedziczyć po klasie EMathError. Dodatkowo zastosujmy dwiedeklaracje ������������ , przechowujące odpowiednie komunikaty, informująceo powstaniu wyjątku podczas zmiennopozycyjnego dzielenia dwóch liczb:

�������������DE�F"�A!�������?�������% ����?���� �����?9��)?������� �����%���9�%����0#MN������ ���2�������2� ���� )��Q�0����9�%'���0 R����2���������2�2�2����Q�0�

W tym wypadku znaki formatowania 0� pozwalają na zduplikowanie komunikatóww języku polskim i angielskim.

Procedurę obsługi zdarzenia ��������� ��, uruchamianego przyciskiem &Oblicz,wypełnimy następującym kodem:

�� ���������"#��������� $������������� �����%������������I������?���*"��,�����������������������I������?����"��,��G���������������������������������������������I������?���'"��,��������, �����������?,��?7�����������������������?�������% ����?�"��������9�%�.�S?,"9����%�T����������?,��?:��3��������������������?�������% ����?�"��������9�%'.�S?,"9����%�T�������������

Page 18: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 63

W klauzuli ��/�������(�, przeznaczonej do obsługi błędów, umieściliśmy zapis właści-wej operacji dzielenia dwóch liczb. Funkcje &����������� dokonują konwersji ciągu zna-ków, przechowywanych w cechach Text komponentów LabeledEdit1 oraz LabeledE-dit2, na zmiennopozycyjną postać numeryczną, czyli po prostu na liczby z przecinkami.Używając operatora dzielenia zmiennopozycyjnego „/”, te dwie liczby podzielimyprzez siebie, natomiast wynik dzielenia zostanie z kolei przypisany cesze Text kom-ponentu edycyjnego reprezentowanego przez LabeledEdit3. Aby postać numerycznaliczby mogła być wyświetlana w oknie edycyjnym, musi zostać zamieniona na łań-cuch znaków (w tym wypadku typu string). Dokonujemy tego, stosując funkcję ��������&���� konwertującą postać numeryczną liczby na odpowiedni łańcuch znaków.

Każde wyrażenie ��/�������(������ może posiadać jedną lub więcej sekcji on: %�< ����1,/23� �> ��, z których każda deklaruje odrębną klasę wyjątku. Delphi prze-szukuje sekcję � w zapisanym porządku (od góry do dołu), poszukując aktualnie pa-sującej klasy wyjątku odpowiadającego występującemu błędowi.

Ogólnie rzecz biorąc, każdy kod potencjalnie mogący wygenerować wyjątek (w na-szym przypadku dzielenie zmiennopozycyjne) powinien mieć możliwość przekazaniajego obiektu do wyrażenia raise (zakańczać, zbierać). W tym miejscu należy wyko-rzystać własną klasę wyjątku %������ +���%�����1 ����������� z konstruktoremkonwertującym komunikat egzemplarza wyjątku na łańcuch znaków

����� ������������ �����9�%������%�� �����&%��������A� ������

gdzie argument Args jest tzw. wariantową tablicą otwartą (array of const), pozwalają-cą na przekazywanie niejednorodnych komunikatów (Messages).

Może zdarzyć się i taka sytuacja, w której kompilator w sekcji ��/���1����(������nie znajdzie pasującego obiektu wyjątku. Wówczas należy użyć konstrukcji ��/�������(���������������������:

�� ���������"#��������� $������������� �����%������������I������?���*"��,�����������������������I������?����"��,��G���������������������������������������������I������?���'"��,��������, �����������?,��?7�����������������������?�������% ����?�"��������9�%�.�S?,"9����%�T����������?,��?:��3��������������������?�������% ����?�"��������9�%'.�S?,"9����%�T����������������������������������

Mamy nadzieję, iż przedstawione w poprzednim punkcie rozważania nie są zbytskomplikowane dla mniej zaawansowanych Czytelników. Jeżeli jednak ktoś czuje sięnieco zagubiony pośród tych pojęć, zawsze można przedstawioną wyżej konstrukcjęznacznie uprościć poprzez wyświetlanie komunikatu wyjątku poprzez okno dialogo-we MessageBox():

Page 19: ABC Delphi 6

64 ABC Delphi 6

�� ���������"#��������� $������������� �����%������������I������?���*"��,�����������������������I������?����"��,��G���������������������������������������������I������?���'"��,��������, �����������?,��?7������������������9����%�#�,�+.�0#MN������ ���2�������2� ���� )0.0=1�%�0.������������������9#>�U����������?,��?:��3���������������9����%�#�,�+.�0 R����2���������2�2�2��0.0=1�%�0.�9#>�U����������������������������������

Na wydruku 4.4 przedstawiono kompletny kod źródłowy głównego modułu aplikacji,wykorzystującej obiekty wyjątków powstałych podczas operacji zmiennopozycyjnegodzielenia dwóch liczb.

Wydruk 4.4. Kod głównego modułu Unit_10.pas projektu KODY\10\Projekt_10.dpr,wykorzystującego przykładowe klasy wyjątków

�����=���>�+�����A� �������/����1�.�9����%��.����=����.�L������.���������.�C��)� �.��������.����.��3����%�.��������.�?,������

������������� �������������#���������#����������I������?�������I������?��������I������?���'���I������?��������I������?���*���I������?��������#�����'���#������������ �����#��������� $������������� ��������� �����#�����'��� $������������� ����������������� �������� ���������!������� ������ ���� ��� ���������!������

��������������

������������

�DE�F"�A!

�������?�������% ����?���� �����?9��)?���

���� �����%���9�%����0#MN������ ���2�������2� ���� )��Q�0����9�%'���0 R����2���������2�2�2����Q�0�

Page 20: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 65

�� ���������"#��������� $������������� �����%������������I������?���*"��,�����������������������I������?����"��,��G���������������������������������������������I������?���'"��,��������, �����������?,��?7�����������������������?�������% ����?�"��������9�%�.�S?,"9����%�T�������GG9����%�#�,�+.�0#MN������ ���2�������2� ���� )0.0=1�%�0.������������������9#>�U����������?,��?:��3��������������������?�������% ����?�"��������9�%'.�S?,"9����%�T�������GG9����%�#�,�+.�0 R����2���������2�2�2��0.0=1�%�0.�9#>�U����������������������������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"#�����'��� $������������� �����%�����&���� �����"�����������������"

Powyższy algorytm najlepiej jest testować, uruchamiając program wynikowy Pro-jekt_10.exe.

Operacje na plikach

Zarówno w Windows, jak i Linux wszelkie operacje wejścia-wyjścia realizowane sąza pomocą czytania z plików lub pisania do plików. Wszystkie urządzenia zewnętrzne,łącznie z końcówką użytkownika, traktowane są jako pliki wchodzące w skład szero-kiego systemu plików. Niniejszy podrozdział poświęcony jest pewnym aspektom re-alizacji przez Delphi różnego rodzaju operacji na plikach.

Większość operacji plikowych, pochodzących ze standardowego Pascala, działa rów-nież w graficznym środowisku Delphi 6. Przypomnijmy, iż standardowo nazwa plikumoże być zmienną typu File lub TextFile. Wywołaniem procedury

�� �����&���%����������������8��������%��

dokonujemy przypisania nazwy pliku do zmiennej plikowej. Procedura

�� �����E����������S��������E� ��2���/���T���

otwiera istniejący plik. Tryb otwarcia pliku zależy od przypisania zmiennej FileModeodpowiedniej wartości. Domyślnie przyjmowana jest wartość 2 pozwalająca na od-czyt i zapis do pliku. Przypisanie zmiennej FileMode wartości 0 przed wywołaniemprocedury #������ spowoduje otwarcie pliku w trybie tylko do odczytu danych, na-tomiast wartości 1 — w trybie tylko do zapisu. Z kolei procedura

�� �����E�1���������������S��E� ��2���/���T���

Page 21: ABC Delphi 6

66 ABC Delphi 6

tworzy nowy plik z jednoczesnym jego otwarciem. Plik zamykamy, wywołując pro-cedurę:

�� ���������������������

Zaprojektujmy aplikację, której zadaniem będzie wczytanie pliku tekstowego z dyskuoraz jego ponowne zapisanie po ewentualnej modyfikacji.

Umieśćmy na formularzu po jednym reprezentancie klas TRichEdit i TCoolBar z kartyWin32. Dodatkowo uzupełnimy go trzema komponentami reprezentującymi klasęTSpeedButton z karty Additional oraz po jednym komponencie z klas TMainMenui TButton z karty Standard oraz TOpenDialog i TSaveDialog z karty Dialogs. Sposóbrozmieszczenia wymienionych komponentów na formularzu obrazuje rysunek 4.6.

Rysunek 4.6.Sposóbrozmieszczeniakomponentówna formularzuprojektuProjekt_11.dpr

Zaprojektujmy proste menu, dzięki któremu będziemy mogli utworzyć nowy plik,wczytać istniejący i ewentualnie powtórnie zapisać na dysku w wybranym katalogu.Aby dostać się do okna służącego do tworzenia menu głównego, należy zaznaczyćkomponent MainMenu1, a następnie dwukrotnie kliknąć myszką pole Items karty zda-rzeń inspektora obiektów (oczywiście, ten sam efekt otrzymamy, klikając dwukrotniesamą ikonę na formularzu). Zmieńmy cechę Caption (nagłówek) na &Plik, pojawi sięwówczas nowe pole obok naszej opcji. W ten sposób możemy tworzyć nawet bardzorozbudowane menu, ale o tym wszystkim jeszcze sobie powiemy w dalszej części książki.Teraz jednak wskażmy pole poniżej i cesze Caption przypiszmy &Nowy, następnieprzejdźmy do karty Events inspektora obiektów i zdarzeniu OnClick przypiszmyNewFileClick. Klikając teraz dwa razy pole &Nowy, od razu znajdziemy się wewnątrzprocedury obsługi zdarzenia ��,�������� ��. Powróćmy do okna Form1.MainMenu1i przejdźmy niżej. Następną opcję zatytułujmy &Otwórz. W karcie zdarzeń inspektoraobiektów jej cechę Name zmieńmy na OpenFile, natomiast w karcie zdarzeń zdarze-niu OnClick przypiszmy FileOpenClick. Dwukrotnie klikając, dostaniemy się downętrza procedury obsługi zdarzenia �����(����� ��. Procedurę tę wypełnimy od-powiednim kodem:

�� ���������"����������� $������������� �������7���������,��������3���������%�

Page 22: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 67

��%����E� )?����"I����"����������A�����3����%�"?,� �����)��������%��������&���%������7�����.�����3����%�"����8����������E�����7�������������1)��������?���7�������������������%������������E���I��7�����.�3���������������E� )?����"I����"&���3���������������������������������7����������������"���������0?�� ���S0J�����3����%�"����8���J0T0�������������

W bardzo podobny sposób zaprojektujmy pozostałe części składowe menu, tak jakpokazano na rysunku 4.7.

Rysunek 4.7.

Elementy składowe

głównego menu

projektu

Projekt_11.dpr

W omawianym programie menu Plik, Otwórz będzie zdublowane jednym z przyciskówTSpeedButton. Najpierw na formularzu umieśćmy komponent TCoolBar, natomiastbezpośrednio na nim kolejno komponenty TSpeedButton. Ich cechy Name zmieńmy,posługując się inspektorem obiektów, odpowiednio na FileOpen, CopyText, PasteText,CutText. Korzystając z właściwości Glyph, rozwińmy opcję TBitmap i umieśćmy nakażdym z przycisków TSpeedButton odpowiednią mapę bitową, tak jak przedstawio-no na rysunku 4.6. Rysunek taki możemy wykonać samodzielnie, korzystając z Edy-tora Graficznego Delphi (menu Tools, Image Editor), którego obsługa nie różni sięw istocie od zasad obsługi programu graficznego, jakim jest Paint.

Aby przycisk FileOpen obsługiwał znaną nam już procedurę obsługi zdarzenia ������(����� ��, wystarczy w karcie zdarzeń inspektora obiektów jego zdarzeniu OnC-lick przypisać FileOpenClick().

Na wydruku 4.5 zamieszczono kompletny kod aplikacji Projekt_11.dpr. W funkcji ������������� wykorzystaliśmy właściwość InitialDir obiektów TOpenDialog i TSaveDialog.Właściwość ta już w momencie uruchomienia aplikacji pozwala ustalić odpowiedniąścieżkę dostępu do aktualnego katalogu. Z kolei wykorzystując właściwość Filter (ry-sunek 4.8) tych obiektów, zapewnimy możliwość odczytania plików posiadającychwymagane przez nas rozszerzenia.

Page 23: ABC Delphi 6

68 ABC Delphi 6

Rysunek 4.8.

Właściwość Filter

klas TOpenDialog

i TSaveDialog

Dymki podpowiedzi do poszczególnych przycisków uzyskamy, korzystając z właści-wości Hint oraz ShowHint. Śledząc poniższy wydruk, zauważymy też, że aby kompo-nenty TOpenDialog i TSaveDialog, niewidoczne przecież w trakcie uruchomieniaprogramu, generowały zdarzenia, polegające na wyświetleniu odpowiednich okiendialogowych, należy w funkcjach odpowiednich zdarzeń skorzystać z metody %���������. Plik zapisujemy na dysku, korzystając z procedury obsługi zdarzenia &�*������������ ��.

Procedury zdarzeniowe ����������� ��, +������������ ��, ��(/�������� ��, zaim-plementowane w odpowiednich przyciskach, zgrupowanych w panelu CoolBar1, ko-rzystają z metody #��4%������������(5������, #��4%����1 +�����������(5������,#��4%������(/�����(5������, zapewniając możliwość usunięcia fragmentu tekstu,wstawienia fragmentu tekstu znajdującego się w schowku (ang. clipboard) oraz skopio-wania fragmentu tekstu do schowka. Możliwe jest również zaznaczenie całości tekstuprzy wykorzystaniu metody #��4%����&����������. Aby powtórzyć ostatnio wyko-naną (na tekście) operację, należy skorzystać z metody #��4%��������������������,którą możemy już samodzielnie zastosować.

Wydruk 4.5. Kod głównego modułu Unit_11.pas projektu Projekt_11.dpr

�����=���>�������A� �

������/����1�.�9����%��.����=����.��������.�C��)� �.���������.����.�3����%�.��������.�������.���������.�����/��.�#������.�9�����

������������� �������������#���������#����������E� )?�������E� )?������������3����%��������3����%���������#���������#������������,���������#���������� ������,���������#���������������,���������#����������9���9�������9���9������������3����%��������3����%�������������&����9���7������������������9���7�������8�1�������9���7���

Page 24: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 69

���������&���� ��������9���7��������� �����#��������� $������������� ��������� ������������������������� ��������� �����������,���� $������������� ��������� ����� ������,���� $������������� ��������� ����������,���� $������������� ��������� ���������������� $������������� ��������� �����8�1������� $������������� ��������� �������������&���� $������������� ��������� ������������������������� �����������������������������& ������������& ������������ ������������@���������������� ��������������������������������������������#��������

�������������� �������� ���������!���������������%������� ��������������� ����������>�������%��������� ������ ���� ��� ���������!������

��������������

������������

�DE�F"3�9!

���� �����%��������0=1�%��V0����'���0:�$��; �������$� ���0�GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"#��������� $������������� �����%����� �����9����%�#�,�+.� �)���'�.� �)�����.���������9#>6?�8����9#>7��8@=?��7�8����A�����73>6?����������&���� �����"���������������73>8���&������������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"�������������������� �����%��������3����%�"7������3�����?,�� ����� ��)� �����+���������3����%�"7������3���������3����%�"7������3������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"������,���� $������������� �����%����E� )?����"���������������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������" ������,���� $������������� �����%����E� )?����" ���������������������

Page 25: ABC Delphi 6

70 ABC Delphi 6

GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"�����,���� $������������� �����%����E� )?����"��������������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"���������� ����������>�������%����%������������������>��������������������0Q��H�Q�0.�S?,�� �����8��������>��.��������������������&���� �����"�����T������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"����������� $������������� �������7���������,��������3���������%���%����E� )?����"I����"����������A�����3����%�"?,� �����)��������%��������&���%������7�����.�����3����%�"����8����������E�����7�������������1)��������?���7�������������������%������������E���I��7�����.�3���������������E� )?����"I����"&���3���������������������������������7����������������"���������0?�� ���S0J�����3����%�"����8���J0T0�������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"8�1������� $������������� �����%��������������0#�2���21�0����E� )?����"I����"���������E� )?����"9���A��������&I�?�����GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"��������&���� $������������� ������������������,��������%�����A�����3����%�"?,� �����)��������%��������&���%�������������.�����3����%�"����8����������E�1�������������������/���I���������.�E� )?����"��,�������������������������������������"���������0:��������S�0�J����3����%�"����8��J�0T0�������E� )?����"9���A��������&I�?�������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"�������������������� ��������������������������������& ������������& ������

Page 26: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 71

��%����& ������ ���������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"�������@���������������� ������������������������������������������#����������%����� �����9����%�#�,�+.� �)���'�.� �)�����.���������9#>6?�8����9#>7��8@=?��7�8����A�����6?��������������������E=?������8��������������������&I�?������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH���"

Strukturalna obsługa wyjątków

Być może temat niniejszego podrozdziału może się wydawać mało adekwatny w książ-ce traktującej o podstawach programowania w Delphi, jednak przekonamy się, iż jeston naturalnym rozwinięciem poruszanych uprzednio zagadnień i wcale nie takim trud-nym pojęciowo, jak ktoś mógłby sądzić.

Oprócz wyrażenia ��/�������(������6 Delphi może posługiwać się również konstruk-cją ��/��������/�����. Różnica pomiędzy nimi polega na tym, iż wyrażenie ��/��������/ nie jest traktowane przez kompilator jako jawna konstrukcja obsługującawyjątki pozwala natomiast na wykonanie części programu, występującego po słowie�����/, nawet w przypadku wcześniejszego wykrycia jakiegoś wyjątku. W celu wy-jaśnienia przedstawionego problemu posłużymy się przykładem procedury obsługizdarzenia czytającego określony plik, który powinien znajdować się na dysku. Plikprzeczytamy metodą „znak po znaku” za pomocą zmiennej �4������� typu �4��.

�� ���������"#�����'��� $������������� �������7���������,���������8��������%����)�� �����)����%����E� )?����"I����"����������8����0 ��$"�,�0���&���%������7�����.��8������������E�����7�������������������1)��������?���7�������������������%������������E����7�����.��)�� ��������������E� )?����"I����"&����)�� ���������������������A������

Page 27: ABC Delphi 6

72 ABC Delphi 6

�����������������7������������������, ����������?,��?7����?�����������)�19����%��0�#MN����1� ������$�"����1�W.�0J�������������������0 2�����$����������������$�"0�������������"���������0?�� ���S0J��8���J0T0�

����

Podczas testowania, a następnie analizowania powyższego algorytmu bez trudu zauwa-żymy, iż w pierwszej kolejności zostaną wykonane instrukcje pomiędzy klauzulami��/ oraz �����/. W następnej kolejności wykonywane będą instrukcje zawarte po-między �����/ i �� (polegające na zamknięciu pliku bez względu na to, czy zostałon otwarty prawidłowo, czy nie) niezależnie od rezultatu wykonania pierwszej grupyinstrukcji czytających znaki z pliku. Najbardziej zewnętrzny blok ��/�������(������obrazuje znaną nam już ideę obsługi wyjątków. Pokazany sposób obsługi wyjątkównosi angielską nazwę Structural Exception Handling (w skrócie SEH). Dzięki zasto-sowaniu SEH dokonujemy rozdziału miejsca, w którym może wystąpić wyjątek (np.próba otwarcia nieistniejącego pliku) od miejsca, w którym będzie on obsługiwany.Zastosowany przez nas wyjątek EInOutError jest w rzeczywistości klasą wyjątkówobsługujących operacje wejścia-wyjścia.

Tablice otwarte

W stosunku do standardowego języka Pascal Delphi znacznie rozszerza pojęcie tabli-cy. Jednym z takich rozszerzeń są tablice otwarte, które z reguły występują w roli pa-rametrów procedur lub funkcji i mogą posiadać dowolne rozmiary. W przypadku, gdyprocedura lub funkcja nie będzie modyfikować zawartości tablicy otwartej, deklaruje-my ją za pomocą słowa kluczowego ����. Słowa kluczowego *�� używamy w dekla-racji funkcji lub procedury modyfikującej zawartość takiej tablicy. Ponieważ w trak-cie działania program powinien w jakiś sposób kontrolować aktualny rozmiar takiejtablicy, musimy wskazać jej dolną i górną granicę. Do tego celu służą funkcje 7�,��i �� 4��.

Jako przykład rozpatrzmy prostą funkcję &����%�������, obliczającą sumę elemen-tów jednowymiarowej tablicy otwartej Data:

A�� ��������A?������ �����3����������A�3��������3�������������7���%����%����E�������+���A�����I�1�3��������(�%)�3�����������E�������E�����J3���S�T�����

Page 28: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 73

Widzimy, że deklaracja tablicy otwartej (z elementami np. typu Double) w charakte-rze argumentu funkcji przyjmuje bardzo prostą postać:

�����3����������A�3�����

Wywołanie w programie funkcji z argumentem w postaci tablicy otwartej nie powin-no sprawić żadnego kłopotu nawet początkującemu programiście Delphi. Wyświetleniewyniku (np. w komponencie edycyjnym TEdit z karty Standard), zwracanego przezfunkcję &����%�������, może nastąpić w procedurze obsługi wybranego zdarzenia:

�� ���������"#��������� $������������� �����%����?����"��,����������������A?������SH�.'.*.-.HXT�������

Widzimy, że w najprostszym wypadku wystarczy wywołać powyższą funkcję z ar-gumentem w postaci kolejnych elementów tablicy, zapisanych w nawiasach kwadra-towych.

Tablice dynamiczne

Różnica pomiędzy tablicami otwartymi i dynamicznymi jest dosyć subtelna. Polegana tym, iż deklaracja tablicy użyta jako parametr bez typu indeksu jest tablicąotwartą, natomiast tablica bez indeksu, deklarowana jako zmienna lokalna, glo-balna, pole klasy lub nowy typ danych jest tablicą dynamiczną.

Do funkcji (lub procedury) deklarującej swój argument jako tablicę otwartą możnaprzekazywać tablice dynamiczne. Funkcja ma wtedy dostęp do elementów tablicy dy-namicznej, jednak nie ma możliwości zmienić jej rozmiaru. Ponieważ tablice otwartei dynamiczne są deklarowane identycznie, jedynym sposobem zadeklarowania para-metru jako tablicy dynamicznej jest zadeklarowanie nowego typu identyfikatora dlatypu tablicy dynamicznej. Przykład takiego działania został pokazany poniżej, gdzierównież wykorzystano funkcję &����%������� do obliczania sumy wszystkich ele-mentów tablicy dynamicznej Data. Ciąg liczb w prosty sposób czytany jest z pliku:

�� ���������"#�����'��� $������������� �������3�����������A�3��������GG������ ������� 2����2� )�1��N ����������������������������GG�1���O �������3������������,��������L������3��������7��7���%����%����&���%�������.�0��Y����"���0����E����������7��+���1)��������?������������%������E���I���.�L�������������I��%�)�3���.�I��%�)�3����J���

Page 29: ABC Delphi 6

74 ABC Delphi 6

����3���S7T����L���������E� )?����"I����"&�������������3���S7T�������7����7J�������������������������?����"��,����������������A?������3����������

Typ OleVariant

Jako przykład zastosowania w programie typu OleVariant pokażemy, w jaki sposóbbardzo szybko można stworzyć klienta OLE, wyświetlającego aktualną wersję zain-stalowanego w systemie PowerPointa, i ewentualnie z poziomu kodu Delphi urucho-mić go.

Technologia OLE (ang. Object Linking and Embedding) umożliwia osadzanie, łą-czenie i wzajemną wymianę różnych obiektów danych przy jednoczesnej pracy wie-lu aplikacji Windows (OLE 2).

Ole Automation jest częścią standardu OLE 2. Umożliwia zapisywanie w aplikacjisekwencji działań OLE w postaci ciągu poleceń, które dany program ma zinterpre-tować.

Component Object Model, w skrócie COM jest standardem, pozwalającym współ-dzielić obiekty pomiędzy wiele aplikacji. Określa też zasady komunikacji pomiędzyobiektami. Obiekty takie muszą być rozróżniane już na poziomie systemu opera-cyjnego.

Przejdźmy do karty Servers, zawierającej kilkadziesiąt elastycznych klas, służącychdo wizualizacji aktualnie dostępnych w systemie serwerów COM.

Zaprojektujmy naprawdę prostą aplikację, składającą się z jednego komponentu re-prezentującego klasę TPowerPointApplication, jednego reprezentującego klasę TRi-chEdit oraz trzech TButton, tak jak przedstawiono to na rysunku 4.9.

Rysunek 4.9.

Aplikacja

wykorzystująca

przykładowy

egzemplarz klasy

TPowerPointApplication

z karty Servers

W najprostszym przypadku w celu ustanowienia połączenia z wybranym serweremCOM wykorzystamy metodę �������, w celu wizualizacji połączenia skorzystamyz metody 8���5��, natomiast aby rozłączyć się z wybranym uprzednio serwerem mu-simy skorzystać z metody 9���������.

Page 30: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 75

Aby utworzyć klienta OLE, należy skorzystać z funkcji ����������52����� z modułuComObj. Parametrem aktualnym tej funkcji jest nazwa odpowiedniej klasy, tak jakzostało to pokazane na wydruku 4.6.

Wydruk 4.6. Kod głównego modułu Unit_12.pas projektu Projekt_12.dpr

�����=���>�'�

����A� �

������/����1�.�9����%��.����=����.L������.�������.�C��)� �.���������.����.�3����%�.��������.�������.�������.��������.�9� ��B�

������������� �������������#���������#����������#�����'���#����������E� )?�������E� )?��������#�����*���#���������� �1� ����&���� ��������� �1� ����&���� ������������ �����#��������� $������������� ��������� �����#�����'��� $������������� ��������� ������������������������� ��������� �����#�����*��� $������������� ����������������� �������� ���������!������� ������ ���� ��� ���������!������

��������������

������������

�DE�F"3�9!

GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"#�����'��� $������������� ������� �1� ����&�������L��������%���������� �1� ����&������������������ ��0 �1� ����"&���� �����0������E� )?����"I����"&���0 �1� �����1�����0J �1� ����&��"L����������, �������&���� �����"9����%�#�,�0 �1� ��������������2��������1���"0.���������������������������0#MN����1� �������$� ��0.�9#>�U��

����������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"#��������� $������������� ���

Page 31: ABC Delphi 6

76 ABC Delphi 6

��%���� �1� ����&���� ������"3�� ���� ������&���� �����"��������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"�������������������� �����%������ �1� ����&���� ������"����� ��������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"#�����*��� $������������� �����%���� �1� ����&���� ������"L��������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH���"

Widzimy, że sposób posługiwania się typami wariantowymi w kontekście tworzeniaklienta OLE wybranego serwera COM jest bardzo prosty. Połączenie się z innymi do-stępnymi serwerami pozostawimy Czytelnikom jako ćwiczenie do samodzielnegowykonania.

Rekordy w Delphi

Rekord w Delphi odgrywa bardzo podobne znaczenie jak w przypadku standardowegojęzyka Pascal. Jeżeli zachodzi w programie konieczność przydzielenia wystarczającejilości pamięci dla większej liczby zmiennych (elementów), stosowanie w programierekordów daje dużo lepsze wyniki w porównaniu z posługiwaniem się klasami, podjednym wszakże warunkiem, mianowicie zakładamy, że ilość operacji wykonywa-nych na elementach rekordu będzie stosunkowo niewielka. Jako przykład wykorzy-stania w środowisku graficznym Delphi prostego rekordu rozpatrzmy pewną modyfi-kację omawianego wcześniej przykładu rekordu, służącego do przechowywaniainformacji o studentach.

Zaprojektujmy formularz składający się z sześciu komponentów TLabeledEdit orazpięciu TButton. W inspektorze obiektów we własności EditLabel cechy Caption eg-zemplarzy klasy TlabeledEdit zmieńmy odpowiednio na Imię, Nazwisko, EgzaminMatematyka, Egzamin Fizyka, Egzamin Informatyka oraz Opinia. Własności Captionkomponentów Button1, Button2, Button3, Button4 i Button5 zmieńmy odpowiednio na&Nowy, &Poprzedni, &Zapisz dane, N&astępny i &Koniec. Rozmieszczenie i opis po-szczególnych komponentów, wchodzących w skład formularza, zatytułowanego Pro-jekt_13, pokazano na rysunku 4.10.

Bez trudu zauważamy, iż komponenty LabeledEdit3, LabeledEdit4 i LabeledEdit5przechowywać będą liczby, dlatego aby w przyszłości uniknąć przykrych niespodzia-nek, w inspektorze obiektów ich cechom Text przypiszmy zerowe wartości. CechyText pozostałych egzemplarzy klasy TLabeledEdit wyczyśćmy.

Page 32: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 77

Rysunek 4.10.

Formularz projektu

Projekt_13.dpr

Po to, aby nasz program był naprawdę funkcjonalny, przewidzimy możliwość zapisudanych na dysku. W tym celu w sekcji implementacji modułu zadeklarujemy rekordpod roboczą nazwą TStudent wraz ze zmienną S tego typu oraz zmienną plikową Ftypu TStudentFile (typ file przeznaczony jest dla plików binarnych):

������������

�DE�F"�A!������������������ ������7��������%S�XT�����8�21��$�������%S'+T�����?%2���9�������%�������?%2�����2�����%�������?%2���7�A�����%�������Z�$��������������%S-+T����������������������A�����A������������������������������������������������E� ��7���%��

Jeżeli programista nie poda innej deklaracji, plik w Delphi zawsze jest reprezentowa-ny jako sekwencja rekordów o ustalonej długości. Dlatego aby uzyskać możliwośćsekwencyjnego dostępu do rekordów pliku, musimy zadeklarować zmienną CurRec(Current Record).

W sekcji prywatnej klasy zadeklarujemy cztery procedury, których celem będzie wy-świetlenie w komponentach edycyjnych aktualnych danych (procedura ShowData),wyczyszczenie zawartości komponentów edycyjnych (ClearData), zapisanie w plikuna dysku aktualnej zawartości elementów rekordu (SaveData) oraz wczytanie danychz dysku (LoadData). Ich zapis w sekcji implementacji modułu będzie bardzo prosty:

Page 33: ABC Delphi 6

78 ABC Delphi 6

�� ���������"�)�13������%�����I������?����"��,����"7������I������?���'"��,����"8�21��$�����I������?���*"��,��������������"?%2���9�������I������?���-"��,��������������"?%2�����2�����I������?���X"��,��������������"?%2���7�A�����I������?���4"��,����"Z�$�������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"I���3������%����E�����.�������)�13��������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"����3������%�����I������?����"��,���00����I������?���'"��,���00����I������?���*"��,���0+0����I������?���-"��,���0+0����I������?���X"��,���0+0����I������?���4"��,���00�����GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"����3������%������"7����I������?����"��,������"8�21��$���I������?���'"��,������"?%2���9��������������I������?���*"��,�������"?%2�����2������������I������?���-"��,�������"?%2���7�A������������I������?���X"��,�������"Z�$����������I������?���4"��,�����/�����.��������

Zauważymy, iż dane czytamy za pomocą procedury #�����61&�, natomiast zapisujemyza pomocą procedury :������61&�, gdzie � jest zmienną plikową, a & identyfikuje po-szczególne pola rekordu.

W tego typu prostszych programach, jeżeli oczywiście nie mamy innych wymagań,postępujemy z reguły w ten sposób, aby już w momencie uruchomienia aplikacjiostatnio zapisane rekordy pliku były widoczne w poszczególnych komponentach edy-cyjnych. Efekt taki uzyskamy, odpowiednio wypełniając procedurę tworzącą formu-larz ������������:

�� ���������"�������������������� �����%���������3���������E� ��+����&���%�������.�0��������3���"���0������A�����?,�����0��������3���"���0���)���������%���������E���������������1)��������?��������

Page 34: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 79

���������I���3����������������������������������%�����������������3���������������E�1������������������������

Najpierw czyścimy pola edycji, wywołując procedurę �����9���. Następnie zmiennejidentyfikującej aktualny rekord pliku przypisujemy wartość zero (ustawiamy się nazerowym rekordzie pliku), gdyż początkiem każdego pliku jest rekord o numerze 0.Z kolei za pomocą procedury ���� ������ przypisujemy nazwę pliku o określonymtypie do zmiennej plikowej. Dalej, sprawdzamy czy plik o podanej nazwie istnieje nadysku w aktualnym katalogu. Jeżeli plik takowy istnieje, otwieramy go procedurą #������� z jednym parametrem w postaci zmiennej plikowej. Dane z pliku czytane są domomentu napotkania znaków końca pliku EOF (End of File). Może się zdarzyć, żeplik o podanej nazwie nie będzie istnieć na dysku (np. pierwsze uruchomienie aplika-cji). Wówczas należy go utworzyć, wywołując z jednym parametrem procedurę #�,��������.

Po wypełnieniu odpowiednich rubryk zapisujemy je na dysku w sposób bardzo pro-sty, korzystając z przycisku Zapisz dane, wyzwalającego procedurę obsługi zdarzenia:

�� ���������"#�����*��� $������������� �����%���������3��������)�13��������

W celu rozpoczęcia wypełniania nowego rekordu uruchamiamy procedurę obsługizdarzenia:

�� ���������"#��������� $������������� �����%�������������7� ���E� .����������$��.���E� ����������?������������3����������3���������$��.���E� ������

W instrukcji powtarzającej ��(���������� za pomocą procedury )��� zwiększamyaktualny numer rekordu w pliku o jeden. Używanie tej procedury w tzw. ciasnych pę-tlach daje dużo lepsze rezultaty w porównaniu z tradycyjnym przypisaniem:

��E� ����E� J��

Procedurą &�� �� przesuwamy pozycję w pliku na miejsce wskazane przez numeraktualnego istniejącego rekordu CurRec. Czynność tę wykonujemy do momentu na-potkania końca pliku. Następnie okna edycji są czyszczone i zapisywane, a numer po-zycji w pliku przesuwany jest na aktualne miejsce CurRec.

Page 35: ABC Delphi 6

80 ABC Delphi 6

W sposób bardzo podobny możemy np. poszukać następnego wypełnionego rekordu.Czynność tę wykonujemy za pomocą procedury obsługi zdarzenia:

�� ���������"#�����-��� $������������� �����%����7� ���E� .��������$��.���E� �����A�����?�������)��������%��������E�����.�������������$��.���E� ���������)�13�������������������������������%������������7� ���E� .�H����GG�������.� ����E� ����E� H���������������$��.���E� �������������)�19����%��0���N%��;���$���� ����$��2������0������������������

Na wydruku 4.7 pokazano kompletny kod źródłowy głównego modułu Unit_13.pasaplikacji projektu Kody\13\Projekt_13.dpr.

Wydruk 4.7. Kod źródłowy modułu Unit_13.pas

�����=���>�*�

����A� �

������/����1�.�9����%��.����=����.�L������.��������.�C��)� �.��������.����.��3����%�.��������.�?,������

������������� �������������I������?�������I������?��������I������?���'���I������?��������I������?���*���I������?��������I������?���-���I������?��������I������?���X���I������?��������I������?���4���I������?��������#���������#����������#�����'���#����������#�����*���#����������#�����-���#����������#�����X���#������������ �����#�����X��� $������������� ��������� �����#�����*��� $������������� ��������� ������������������������� ��������� �����#��������� $������������� ��������� �����#�����'��� $������������� ��������� �����#�����-��� $������������� ����������������� �������� ���������!������ ������)�13���������� ���������3����

Page 36: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 81

������ ���������3���������� �����I���3����������� ������ ���� ��� ���������!������

��������������

������������

�DE�F"�A!������������������ ������7��������%S�XT�����8�21��$�������%S'+T�����?%2���9�������%�������?%2�����2�����%�������?%2���7�A�����%�������Z�$��������������%S-+T����������������������������A������������������������������������������������E� ��7���%��GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"�)�13������%�����I������?����"��,����"7������I������?���'"��,����"8�21��$�����I������?���*"��,��������������"?%2���9�������I������?���-"��,��������������"?%2�����2�����I������?���X"��,��������������"?%2���7�A�����I������?���4"��,����"Z�$�������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"I���3������%����E�����.�������)�13��������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"����3������%�����I������?����"��,���00����I������?���'"��,���00����I������?���*"��,���0+0����I������?���-"��,���0+0����I������?���X"��,���0+0����I������?���4"��,���00�����GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"����3������%������"7����I������?����"��,������"8�21��$���I������?���'"��,��

Page 37: ABC Delphi 6

82 ABC Delphi 6

����"?%2���9��������������I������?���*"��,�������"?%2�����2������������I������?���-"��,�������"?%2���7�A������������I������?���X"��,�������"Z�$����������I������?���4"��,�����/�����.��������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"#�����X��� $������������� �����%���������3�����������������������&���� �����"��������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"#�����*��� $������������� �����%���������3��������)�13��������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"�������������������� �����%���������3���������E� ��+����&���%�������.�0��������3���"���0������A�����?,�����0��������3���"���0���)���������%���������E���������������1)��������?�����������������I���3����������������������������������%�����������������3���������������E�1������������������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"#��������� $������������� �����%�������������7� ���E� .����������$��.���E� ����������?������������3����������3���������$��.���E� ������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"#�����'��� $������������� �����%�����A����E� H���[�+��)��������%����������E� ��+����������$��.���E� ���������)�19����%��0���N%��;����� 2N��$����$��2������0�������������������

Page 38: ABC Delphi 6

Rozdział 4. ♦ Object Pascal w wydaniu Delphi 83

����������%������������7� ���E� .H����������������$��.���E� ������������E�����.�����������������$��.���E� �������������)�13��������������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH�� ���������"#�����-��� $������������� �����%����7� ���E� .��������$��.���E� �����A�����?�������)��������%��������E�����.�������������$��.���E� ���������)�13�������������������������������%������������7� ���E� .�H������GG�������.� ����E� ����E� H���������������$��.���E� �������������)�19����%��0���N%��;���$���� ����$��2������0������������������GGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH���"

Testowanie przedstawionej aplikacji jest bardzo proste. Na pobranym z serwera FTPWydawnictwa Helion pliku, w aktualnym katalogu znajduje się przykładowy plikSdudentsData.dat z informacjami o trzech wybranych studentach. Możemy samo-dzielnie go przeszukiwać i uzupełniać. Należy jednak pamiętać, aby każdy nowo wy-pełniony rekord od razu zapisać na dysku.

Warto pamiętać, iż procedury &�� �� nie można stosować do wykonywania opera-cji na plikach tekstowych (TextFile). Jeżeli chcemy przesuwać pozycję w pliku tek-

stowym, należy skorzystać z funkcji bibliotecznej API &������+�������.

Podsumowanie

Celem niniejszego rozdziału było zaprezentowanie Czytelnikom pewnych bardzoważnych pojęć, z którymi nader często spotykamy się, tworząc aplikacje w nowoczesnymśrodowisku Delphi 6. Chociaż może się wydawać, iż omawianie na kursie programo-wania dla osób mniej zaawansowanych takich terminów, jak metody przeładowywane,wyjątki i klasy wyjątków, tablice otwarte i dynamiczne, serwery COM czy przeszu-kiwanie rekordów może być czynnością „na wyrost”, to jednak należy zdawać sobiesprawę, że obecnie terminy te posiadają już zupełnie fundamentalne znaczenie i ichznajomość (chociażby pobieżna) daje nam przepustkę do samodzielnego studiowaniaplików pomocy, które są nieocenionym i bogatym źródłem informacji o kompilatorze.