![]() |
Turbo Pascal.
|
![]() |
Pożyteczne drobiazgi, czyli moduły biblioteczne
Ile razy zastanawiałeś się, jak wyczyścić ekran, zmienić kolor tekstu czy wprowadzić znak z klawiatury bez naciskania klawisza Enter? Wykonanie tych czynności nie wymaga zachodu: wystarczy wywołać odpowiednią procedurę biblioteczną. Jak sama nazwa wskazuje, procedura taka nie jest na stałe "wbudowana" w język programowania, lecz pobierana z oddzielnego pliku (biblioteki) i dołączana do programu w trakcie tzw. konsolidacji (następującej po kompilacji).
Pascalowe pliki biblioteczne noszą nazwę modułów (ang. unit). Wersja 7.0 oferuje programiście dziesięć modułów standardowych:
System - wszystkie procedury standardowe; Crt - obsługa monitora, klawiatury i głośnika; Dos - obsługa funkcji systemowych (wywołania funkcji systemu MS-DOS); Graph - bsługa grafiki; Strings - obsługa łańcuchów ASCIIZ; WinDos - odpowiednik modułu DOS wykorzystujący łańcuchy ASCIIZ; Printer - obsługa drukarki; Overlay - obsługa tzw. nakładek; Turbo3 - moduł "uzgadniający" z Turbo Pascalem 3.0; Graph3 - obsługa tzw. grafiki żółwia (używanej w Turbo Pascalu 3.0). Oddzielna, obszerna grupa modułów tworzy bibliotekę Turbo Vision, którą nie będziemy się tutaj zajmować.
Jak nietrudno zauważyć, każdy moduł "specjalizuje się" w określonych operacjach (wyjątkiem jest moduł System, zawierający wszystkie procedury i funkcje standardowe). Najczęściej używane moduły (System, Crt, Dos, Printer i Overlay) umieszczono w specjalnym pliku TURBO.TPL, ładowanym do pamięci wraz z IDE Turbo Pascala, dzięki czemu ich zawartość dostępna jest natychmiast. Kod pozostałych modułów zapisany jest w odpowiednich plikach z rozszerzeniem .TPU. Niezależnie od tego, czy kod modułu znajduje się na dysku, czy jest ładowany do pamięci, aby wykorzystać dowolny jego element, za nagłówkiem programu musisz umieścić deklarację
uses nazwa-modułu;
Jeśli wykorzystujesz kilka różnych modułów, musisz rozdzielić ich nazwy przecinkami.
Chociaż moduły traktowane są najczęściej jako biblioteki procedur, zawierają one również dane w postaci stałych (np. definiujących kolory, jak Red=2), zmiennych (np. ustalających sposób otwierania plików - FileMode, czy też obsługi monitora - DirectVideo) i typów (np. DateTime - typ rekordowy przeznaczony do przechowywania czasu i daty, PointType - typ opisujący punkt na płaszczyźnie). Zarówno procedury, jak i dane możesz wykorzystywać bez ograniczeń, a także przysłaniać własnymi definicjami. Pamiętaj jednak, że ceną za dostęp do zawartych w module obiektów jest powiększenie objętości gotowego programu, wynikające z dołączenia "importowanego" kodu i danych. Jeśli zależy Ci na minimalizacji wielkości kodu wynikowego, zastanów się, czy koniecznie musisz używać np. modułu Crt. Generalnie jednak należy zalecić używanie modułów bibliotecznych, gdyż dają one programiście możliwość skorzystania ze sprawdzonych rozwiązań wielu problemów, zwalniając od konieczności wymyślania ich na własną rękę.
Stosuj moduły biblioteczne. Spośród wymienionych wyżej modułów najczęściej stosowane są: Crt, umożliwiający efektywną (i efektowną) obsługę komunikacji z użytkownikiem, Graph, realizujący operacje w trybie graficznym, oraz Dos, umożliwiający wykonywanie funkcji systemowych. Ponieważ omawianie treści poszczególnych modułów jest kwestią drugorzędną (nasza książka ma przede wszystkim uczyć programowania, a nie służyć jako leksykon języka), a także ze względu na szczupłość miejsca, ograniczymy się do omówienia kilku najpopularniejszych elementów modułów Crt i Dos wraz z prostymi przykładami. Z tych samych przyczyn zrezygnujemy z omawiania bardzo obszernej zawartości modułu Graph, odsyłając zainteresowanych Czytelników do literatury [2].
Zaczniemy od modułu Crt, wspomagającego operacje wejścia i wyjścia z użyciem konsoli. Z procedur "ulepszających" obsługę ekranu i klawiatury chyba najczęściej wykorzystywana jest bezparametrowa procedura ClrScr, powodująca wyczyszczenie ekranu. Przykład jej użycia znajdziesz w funkcji Menu naszego programu bibliotecznego. Jeśli dodatkowo przy okazji czyszczenia ekranu chciałbyć zmienić kolory, możesz wykorzystać procedury TextColor i TextBackground:
TextColor(kolor-tekstu)
TextBackground(kolor-tła)zmieniające odpowiednio kolor znaków oraz tła. Oczywiście zamiast liczbowych wartości kolorów (kto by je pamiętał...) najlepiej stosować stałe symboliczne (np. Blue=1 dla koloru niebieskiego). Efekt działania obu procedur widoczny jest dopiero po wykonaniu kolejnych operacji wyjścia (lub wyczyszczenia ekranu), zaś bieżące wartości kolorów przechowywane są w zmiennej TextAttr.
Procedura GotoXY służy do wyprowadzania tekstu na zadanych współrzędnych (ekran tekstowy liczy sobie 25 wierszy po 80 znaków; wiersze i znaki numerowane są od 1). Przykładowe wywołanie
for i := 1 to 24 do begin GotoXY(i,i); write('*'); end; wyświetli na ekranie ukośną linię złożoną z gwiazdek. Zbliżone zastosowanie ma procedura Window:
Window(x1, y1, x2, y2)
umożliwiająca wyznaczenie na ekranie okienka ograniczającego obszar wypisywania tekstu do prostokąta o współrzędnych x1, y1 (lewy górny róg) i x2, y2 (prawy dolny róg). Działanie procedury Window najlepiej ilustruje poniższy przykład:
Window(10, 10, 20, 20); { okienko 10x10 }
write('W tym okienku wypisuje sie bardzo dlugi tekst');Obydwie procedury umożliwiają skuteczne tworzenie ładnych menu czy "formularzy" niewielkim nakładem kosztów, chociaż często okazuje się, że lepiej w tym celu wykorzystać np. bibliotekę Turbo Vision.
Aby wprowadzić z klawiatury pojedynczy znak bez naciskania klawisza Enter warto wykorzystać funkcję ReadKey. Zwraca ona kod ASCII znaku odpowiadającego klawiszowi albo - w przypadku naciśnięcia klawisza funkcyjnego lub specjalnego - tzw. rozszerzony kod klawisza poprzedzony znakiem o kodzie 0 (w tym przypadku konieczne są dwa wywołania). Funkcja ReadKey jest stosowana głównie do realizacji menu (vide program Katalog) i innych wymyślniejszych operacji wykorzystujących klawiaturę. Spokrewniona z nią funkcja KeyPressed służy do badania stanu bufora klawiatury: jeśli przed jej wywołaniem naciśnięto jakiś klawisz, zwróci ona wartość true. Warto pamiętać, że KeyPressed nie opróżnia bufora klawiatury, toteż kolejne wywołania będą zwracały true aż do chwili, kiedy znak zostanie odczytany np. wywołaniem funkcji ReadKey. Z tego też względu funkcji KeyPressed należy używać bardzo ostrożnie, zastępując ją w miarę możliwości wywołaniem ReadKey.
Realizację efektów dźwiękowych umożliwiają procedury Sound, NoSound i Delay. Pierwsze dwie odpowiednio włączają i wyłączają wewnętrzny głośniczek komputera, powodując generowanie dźwięku o częstotliwości określonej parametrem. Procedura Delay umożliwia ustalenie długości trwania dźwięku. Ponieważ głośnik komputera PC obsługiwany jest sprzętowo, musisz pamiętać o wyłączeniu dźwięku procedurą NoSound, w przeciwnym przypadku może on być generowany nawet po zakończeniu programu. Krótką demonstrację efektów dźwiękowych pokazano poniżej:
for i := 1 to 8 do begin Sound(1000); { dźwięk o częstotliwości 1 kHz } Delay(100); { opóźnienie 100 milisekund } NoSound; { wyłącz dźwięk } Delay(100); { jeszcze jedno opóźnienie } end; Procedury i dane zawarte w module Dos wykorzystywane są znacznie rzadziej, głównie przez bardziej doświadczonych programistów. Pozwalają one na wykonywanie operacji na systemie plików, obsługę zegara systemowego oraz zarządzanie procesami (programami) i tzw. przerwaniami (co jest zabawą nie zawsze bezpieczną).
Elementarne informacje o systemie plików możesz uzyskać za pomocą funkcji (procedur) DiskSize, DiskFree, GetDir, FindFirst i FindNext. Pierwsze dwie funkcje zwracają całkowitą pojemność oraz ilość wolnego miejsca dla zadanego dysku (w bajtach), zaś procedura GetDir umożliwia określenie nazwy bieżącego katalogu:
GetDir(0, s); { 0 oznacza dysk bieżący }
writeln('Biezacy katalog: ', s); { s jest typu string }
writeln('Pojemnosc dysku: ', DiskSize(0), ' bajtow.');
writeln('Wolne miejsce: ', DiskFree(0), ' bajtow.');Warto wiedzieć, że dyski w systemie DOS numerowane są od jedynki (która odpowiada dyskowi A:), zaś wartość 0 oznacza zawsze dysk bieżący.
Procedury FindFirst i FindNext wykorzystywane są na ogół do sprawdzania obecności pliku na dysku i odczytu listy plików zawartych w katalogu. Poniżej przedstawiono typową konstrukcję wyświetlającą listę plików zawartych w katalogu głównym dysku C:
FindFirst('c:\*.*', AnyFile, OpisPliku); { znajdź pierwszy } { plik } while DosError = 0 do { szukaj aż do wyczerpania plików } begin FindNext(OpisPliku); { znajdź kolejny plik } writeln(OpisPliku.Name); end; Procedura FindFirst znajduje pierwszy plik o nazwie zadanej pierwszym parametrem i tworzy tzw. rekord opisu pliku (zmienna OpisPliku typu SearchRec), wykorzystywany następnie przez FindNext do wyszukiwania kolejnych plików. Zmienna DosError przechowuje wynik ostatnio wykonanej funkcji systemu operacyjnego (w naszym przypadku - funkcji wyszukania pliku), przy czym wartość 0 odpowiada wykonaniu bezbłędnemu, natomiast pozostałe wartości są kodami odpowiednich błędów zwracanymi przez DOS.
Na tym zakończymy nasze krótkie spotkanie z modułami bibliotecznymi. Z konieczności omówiliśmy w nim zagadnienia najbardziej podstawowe, pomijając szczegółowy opis zawartości modułów. Jeśli okaże się, że jest Ci potrzebna jakaś funkcja lub struktura danych, najlepiej zrobisz przeglądając odpowiednie tematy systemu pomocy, ewentualnie odwołując się do literatury.
W kolejnym rozdziale pokażemy, jak tworzyć własne moduły i jakie z tego płyną korzyści.
Zapamiętaj
- Pascalowe moduły biblioteczne zawierają wiele użytecznych procedur i struktur danych.
- Aby odwołać się do zawartości modułu, musisz umieścić na początku programu deklarację uses.
- Wykorzystanie modułów powoduje powiększenie objętości skompilowanego programu.
- Najczęściej wykorzystywanymi modułami są Crt (obsługa monitora i klawiatury), Graph (obsługa grafiki) oraz Dos (obsługa wywołań funkcji systemowych).
Poprzedni | Spis treści | Następny | Wersja spakowana |