Professional Documents
Culture Documents
PRZYKADOWY ROZDZIA
SPIS TRECI
KATALOG KSIEK
KATALOG ONLINE
Delphi. Almanach
Autor: Ray Lischner
ISBN: 83-7197-469-8
Tytu oryginau: Delphi in a Nutshell. A Desktop Quick
Reference
Format: B5, stron: okoo 560
TWJ KOSZYK
DODAJ DO KOSZYKA
CENNIK I INFORMACJE
ZAMW INFORMACJE
O NOWOCIACH
ZAMW CENNIK
CZYTELNIA
FRAGMENTY KSIEK ONLINE
Wydawnictwo Helion
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
e-mail: helion@helion.pl
"
"
"
"
"
"
Moduy..................................................................................................................................... 13
Programy.................................................................................................................................. 16
Biblioteki ................................................................................................................................. 17
Pakiety ..................................................................................................................................... 19
Typy danych ............................................................................................................................ 20
Zmienne i stae......................................................................................................................... 37
Obsuga wyjtkw ................................................................................................................... 38
Operacje na plikach ................................................................................................................. 43
Funkcje i procedury ................................................................................................................. 44
Klasy i obiekty ......................................................................................................................... 49
Interfejsy .................................................................................................................................. 74
Zliczanie referencji .................................................................................................................. 79
Komunikaty ............................................................................................................................. 82
Zarzdzanie pamici .............................................................................................................. 84
Obiekty starego typu................................................................................................................ 90
!
"#
Tablica metod wirtualnych ...................................................................................................... 93
Deklaracje publikowane .......................................................................................................... 96
Modu TypInfo....................................................................................................................... 101
Metody wirtualne i dynamiczne ............................................................................................ 110
Inicjalizacja i finalizacja ........................................................................................................ 111
!$!
%& '
Wtki i procesy ...................................................................................................................... 119
Klasa TThread........................................................................................................................ 128
Klasa TIdThread .................................................................................................................... 134
Funkcje BeginThread i EndThread........................................................................................ 137
Lokalny obszar wtku............................................................................................................ 137
Procesy................................................................................................................................... 138
Transakcje Futures................................................................................................................. 146
(#
" ))
*&
)
Kody typu wariantowego....................................................................................................... 513
Typy tablic otwartych ............................................................................................................ 514
Offsety wirtualnej tablicy metod ........................................................................................... 515
Kody bdw czasu wykonania ............................................................................................. 516
Kody bdw CLX................................................................................................................. 518
!! )+
Operatory unarne ................................................................................................................... 521
Operatory mnogociowe ........................................................................................................ 523
Operatory addytywne............................................................................................................. 524
Operatory porwnania ........................................................................................................... 526
!
! )+
,!""
!"
- )
.#&
*/ ))
Bdy i wyjtki....................................................................................................................... 595
Zarzdzanie plikami............................................................................................................... 602
Operacje na acuchach ......................................................................................................... 617
Niniejszy rozdzia zawiera kompendium jzyka. Tutaj znale mona kade sowo kluczowe,
dyrektyw, funkcj, procedur, zmienn, klas, metod oraz waciwo, bdce czci jzyka
Object Pascal. Wikszo z tych elementw jest zdefiniowana w module System, natomiast niektre w module SysInit oraz Variants. Moduy te s automatycznie wczane do kadego moduu
Delphi. Naley pamita, e Object Pascal nie rozrnia wielkich i maych liter, z jedynym wyjtkiem,
dotyczcym procedury Register (dla zapewnienia zgodnoci z Builderem C++).
Dla wygody Czytelnika numery bdw czasu wykonania poczone zostay z odpowiednimi nazwami
klas wyjtkw. Moduy System oraz SysUtils przeksztacaj bdy w wyjtki. Czsto mona usysze, e wyjtki nie s czci prawdziwego jzyka Object Pascal, jednak w obecnej wersji Delphi
w duej mierze przestao to by prawd. Ze wzgldu na powszechne uycie moduw System oraz
SysUtils programici Delphi znacznie lepiej posuguj si wyjtkami ni numerami bdw.
Kady element tego rozdziau naley do jednej z kilku kategorii, opisanych poniej:
Dyrektywa
Dyrektywa jest identyfikatorem, majcym specjalne znaczenie dla kompilatora, ale tylko
w specyficznym kontekcie. Poza tym kontekstem programista moe swobodnie uywa nazw
dyrektyw jako zwykych identyfikatorw. Edytor kodu rdowego stara si pomaga
programicie poprzez wytuszczanie dyrektyw, gdy s one uywane w odpowiednim
kontekcie, oraz drukowanie ich standardow czcionk, gdy maj charakter zwykych
identyfikatorw. Poniewa jednak niektre zasady jzyka dotyczce dyrektyw s bardzo
zoone, czasem edytor po prostu myli si w swoich przewidywaniach.
Funkcja
Nie wszystkie funkcje s w rzeczywistoci funkcjami; niektre z nich s wbudowane w kompilator.
Rnica nie jest na og istotna, poniewa funkcje wbudowane wygldaj i dziaaj tak,
jak zwyke funkcje, z t rnic, i nie mona pobra ich adresu. Opisy zastosowane w tym
rozdziale informuj, ktre funkcje s wbudowane, a ktre nie.
Interfejs
Deklaracja standardowego interfejsu.
Sowo kluczowe
Sowo kluczowe jest zarezerwowanym identyfikatorem, ktrego znaczenie jest okrelane przez
kompilator Delphi. Sw kluczowych nie mona uywa jako nazw zmiennych, metod lub
typw.
Procedura
Podobnie jak w przypadku funkcji, niektre procedury s wbudowane w kompilator, zatem nie
mona wyznaczy ich adresu. Pewne procedury (np. Exit) zachowuj si tak, jakby byy
wyraeniami jzyka, ale nie s zarezerwowanymi sowami kluczowymi. Uywa si ich w taki
sam sposb, jak zwykych procedur.
Typ
Niektre z typw s wbudowane w kompilator, ale wiele z nich jest jawnie zdefiniowanych
w module System lub Variants.
Zmienna
Wikszo zmiennych zdefiniowanych w jzyku Object Pascal to zmienne typw prostych,
zawarte w moduach System, SysInit oraz Variants. Rnica pomidzy tymi moduami
polega na tym, e zmienne w module System s wspdzielone przez wszystkie moduy
wchodzce w skad aplikacji, natomiast SysInit oraz Variants s przekazywane kademu
moduowi jako odrbna kopia. Brak tej wiedzy moe doprowadzi do wielu nieporozumie
podczas programowania. Inne zmienne (Self i Result) s wbudowane w kompilator i posiadaj
specjalne przeznaczenie.
function Abs(Number: typ numeryczny): typ numeryczny;
Funkcja Abs oblicza i zwraca warto bezwzgldn z argumentu. Jest wbudowana w kompilator.
Jeeli argument jest typu cakowitego, Abs sprawdza, czy warto jest ujemna i w razie
potrzeby neguje j. W zalenoci od argumentu, typem zwracanym jest Integer lub Int64.
Dla wartoci zmiennoprzecinkowych Abs zeruje bit znaku, pozostawiajc bez zmian wszystkie
pozostae bity, ujemne zero i ujemna nieskoczono staj si dodatnim zerem i dodatni
nieskoczonoci. Nawet jeli wartoci nie jest liczba, wynikiem bdzie oryginalna warto
z bitem znaku ustawionym na zero.
Jeeli argument jest typu Variant, Delphi konwertuje go na liczb zmiennoprzecinkow
i zwraca jej warto bezwzgldn typu zmiennoprzecinkowego (nawet jeli warto Variant
ma charakter cakowity).
Argument
Warto zwracana
(minus nieskoczono)
+ (plus nieskoczono)
< 0
0.0
liczba
+0.0
+0.0
+0.0
+ (plus nieskoczono)
+ (plus nieskoczono)
Double, Extended, Int64, Integer, Single
var Deklaracja absolute Wyraenie stae;
var Deklaracja absolute Zmienna;
Dyrektywa absolute nakazuje Delphi zapisanie zmiennej pod okrelonym adresem w pamici.
Adresem moe by warto numeryczna lub nazwa zmiennej. W drugim przypadku adres jest taki
sam, jaki uyty zosta dla zmiennej. Dyrektywa absolute moe by stosowana w odniesieniu
do zmiennych globalnych i lokalnych.
Odradza si stosowanie dyrektywy absolute, o ile nie jest to naprawd konieczne. W zamian
naley stosowa rekordy wariantowe, ktre s mniej bdogenne oraz atwiejsze w czytaniu
i rozumieniu.
Dyrektyw absolute naley stosowa zamiast rekordw wariantowych, jeeli nie mona
w rozsdny sposb zmieni typu zmiennej. Na przykad z dyrektywy absolute moe
skorzysta procedura, ktra musi zmienia sposb interpretacji swojego argumentu.
Dyrektywa absolute z adresem numerycznym jest pozostaoci z Delphi 1 i nie ma
adnego rzeczywistego zastosowania w nowszych, 32-bitowych systemach operacyjnych.
Przykad uycia dyrektywy absolute znale mona w opisie typw Extended oraz Double.
Record, Var
!
Deklaracja metody wirtualnej; virtual; abstract;
procedure NazwaProcedury; virtual; abstract;
Jeeli klasa potomna nie przesania metody abstrakcyjnej, naley j omin w deklaracji klasy
lub zadeklarowa z uyciem dyrektyw override i abstract (w takiej kolejnoci).
Zalecana jest druga metoda, poniewa w jasny sposb dokumentuje intencj programisty:
nieimplementowania metody. W przeciwnym wypadku osoba czytajca kod programu moe
mie trudnoci ze zrozumieniem, dlaczego metoda nie wystpuje w klasie.
Jeeli programista prbuje skonstruowa obiekt na podstawie klasy zawierajcej metod
abstrakcyjn, kompilator generuje ostrzeenie. Zazwyczaj ostrzeenie tego typu informuje
o jednym z moliwych bdw: (1) programista zapomnia zaimplementowa metod
abstrakcyjn w klasie potomnej lub (2) usiuje stworzy egzemplarz klasy bazowej,
podczas gdy powinien stworzy egzemplarz klasy potomnej.
W przypadku stworzenia egzemplarza klasy bazowej i odwoania si do jednej z jej metod
abstrakcyjnych, Delphi wywouje procedur AbstractErrorProc lub generuje bd czasu
wykonania o numerze 210 (EAbstractError).
AbstractErrorProc, class, dynamic, override, virtual
var AbstractErrorProc: Pointer;
procedure ProceduraObslugiBledu;
begin ... end;
AbstractErrorProc := @ProceduraObslugiBledu;
Kiedy wywoana zostanie metoda abstrakcyjna obiektu pochodzcego z klasy bazowej (w ktrej
metoda ta nie jest implementowana), Delphi wywouje procedur wskazywan przez zmienn
"#$%"&"'"
(
Modu SysUtils przypisuje zmiennej AbstractErrorProc procedur generujc wyjtek
EAbstractError, zatem w wikszoci aplikacji ustawianie tej zmiennej nie jest wymagane.
W przypadku zdefiniowania wasnej procedury obsugi dla bdw metod abstrakcyjnych,
naley pamita o wygenerowaniu wyjtku; jeeli procedura wykona si normalnie, Delphi
zatrzyma program.
Abstract, AssertErrorProc, ErrorProc, ExceptProc, Halt
function AcquireExceptionObject: Pointer;
W momencie gdy klauzule try-except kocz obsug wyjtku, Delphi automatycznie zwalnia
obiekt wyjtku. Funkcja ta interpretuje obsug wyjtku w taki sposb, aby obiekt wyjtku zosta
przekazany do gwnego wtku aplikacji, co zapobiega jego przedwczesnemu zwolnieniu przez
Delphi. AcquireExceptionObject zwiksza licznik referencji obiektu wyjtku, wic nie jest
on automatycznie zwalniany. Kiedy aplikacja wywouje AcquireExceptionObject, odpowiedzialn za zwolnienie obiektu wyjtku staje si procedura ReleaseExceptionObject.
// Funkcja przechwytuje wyjtki i zapisuje w licie RaiseListPtr^
function AcquireExceptionObject: Pointer;
begin
if RaiseListPtr <> nil then
begin
// Kiedy aplikacja wygeneruje wyjtek, zapisuje jego obiekt
// w RaiseListPtr^.
// Nastpnie ustawia referencj obiektu na
// nil w zawartoci wyjtku, aby zapobiec przedwczesnemu
// zwolnieniu obiektu przez Delphi.
Result := PRaiseFrame(RaiseListPtr)^.ExceptObject;
PRaiseFrame(RaiseListPtr)^.ExceptObject := nil;
end
else
Result := nil;
end;
ReleaseExceptionObject
)
Delphi przechowuje list pakietw, z ktrych skada si aplikacja. W chwili usuwania z pamici
pakietu wywoywana jest seria procedur, z ktrych kada otrzymuje uchwyt biblioteki DLL. Programista moe doda wasn procedur do nagwka listy poprzez przypisanie jej adresu do
AddModuleUnloadProc. Procedury usuwania moduw z pamici s rwnie wywoywane
podczas wychodzenia z aplikacji.
AddModuleUnloadProc jest rzeczywist procedur.
//
//
//
//
//
//
//
//
//
//
type
PResource = ^TResource;
TResource = record
Module: THandle;
Resource: TGraphicsObject;
case Boolean of
True: (Name: PChar;);
False: (ID: LongInt);
end;
var
List: TList;
procedure ByeBye(HInstance: THandle);
var
I: Integer;
Resource: PResource;
begin
for I:= List.Count-1 downto 0 do
begin
Resource := List[I];
if Resource.Module = HInstance then
begin
List.Delete(I);
"*+
Resource.Resource.Free;
Dispose(Resource);
end;
end;
end;
initialization
List:= TList.Create;
AddModuleUnloadProc(ByeBye);
finalization
RemoveModuleUnloadProc(ByeBye);
FreeAndNil(List);
end.
K
ModuleUnloadList, TModuleUnloadProcLW, PModuleUnloadRec,
RemoveModuleUnloadProc, TModuleUnloadRec, UnregisterModule
function Addr(var X): Pointer;
Addr(Zmienna)
Addr(Procedura)
Funkcja Addr zwraca adres zmiennej lub procedury (funkcji). Typem zwracanym jest wskanik
oglnego przeznaczenia Pointer. Nawet w przypadku uycia dyrektywy kompilatora $T lub
$TYPEDADDRESS, Addr zwraca zawsze wskanik typu Pointer.
Podobne dziaanie do funkcji Addr ma operator @, z t rnic, e moe zwrci wskanik okrelonego typu (jeeli wczona jest dyrektywa $T lub $TYPEDADDRESS).
Funkcja Addr jest wbudowana w kompilator.
Pointer, $T, $TYPEDADDRESS
!
var AllocMemCount: Integer;
,
Zmienna AllocMemCount nie jest w aden sposb wykorzystywana przez Delphi ma
charakter wycznie informacyjny. Zmiana jej wartoci nie ma adnego celu i nie przynosi
adnej szkody.
Programista tworzcy wasny Meneder pamici powinien sprawdzi zawarto
AllocMemCount przed wywoaniem SetMemoryManager. Zmienna AllocMemCount
powinna by wyzerowana. Jeeli jest inaczej, oznacza to, e domylny Meneder pamici
przydzieli przynajmniej jeden blok pamici. W takiej sytuacji Delphi moe prbowa zwolni
t pami przy uyciu Menedera pamici programisty. Jeeli Meneder pamici nie jest
przygotowany do rozwizania takiej sytuacji, najbezpieczniej jest zatrzyma program.
We wasnym Menederze pamici zmiennej AllocMemCount mona przypisywa liczb
aktualnie przydzielonych blokw pamici.
W przypadku stosowania bibliotek DLL, AllocMemCount moe nie odzwierciedla blokw
pamici przydzielonych innym moduom. Korzystajc z moduu ShareMem, mona wywoa
jego funkcj GetAllocMemCount w celu obliczenia liczby blokw pamici przydzielonych
wszystkim moduom uywajcym ShareMem.
AllocMemSize, Dispose, FreeMem, GetHeapStatus, GetMem, GetMemory, New,
ReallocMem, SetMemoryManager
"
var AllocMemSize: Integer;
AllocMemSize przechowuje cakowity rozmiar w bajtach wszystkich blokw pamici zaalokowanych przez Menedera pamici Delphi. Mwic inaczej, AllocMemSize reprezentuje
rozmiar pamici dynamicznej, uywanej przez aplikacj.
Zmienna AllocMemSize nie jest uywana w aden sposb przez Delphi. Zmiana jej
wartoci, chocia bezcelowa, jest nieszkodliwa.
We wasnym Menederze pamici zmiennej AllocMemSize mona przypisywa aktualny
rozmiar pamici zaalokowanej przez menedera.
W przypadku stosowania bibliotek DLL, AllocMemSize moe nie odzwierciedla blokw
pamici przydzielonych innym moduom. Korzystajc z moduu ShareMem, mona wywoa
jego funkcj GetAllocMemSize w celu znalezienia liczby blokw przydzielonych
wszystkim moduom uywajcym ShareMem.
"
-
AllocMemCount, Dispose, FreeMem, GetHeapStatus, GetMem,
GetMemoryManager, New, ReallocMem, SetMemoryManager
#
Wyraenie boolowskie and Wyraenie boolowskie
Wyraenie wartoci cakowitej and Wyraenie wartoci cakowitej
Operator and wykonuje iloczyn logiczny, jeeli jego operandy s typu boolowskiego, lub iloczyn
bitowy, jeeli operatory maj warto cakowit. Operandy cakowite mog by dowolnego typu
cakowitego, cznie z Int64. Iloczyn logiczny zwraca fasz (False), jeeli warto ktregokolwiek operandu jest faszem, i prawd, jeeli oba operandy maj warto prawdziw (True).
W przeciwiestwie do standardowego jzyka Pascal, jeeli operand po lewej stronie ma
warto faszyw, Delphi nie oblicza wartoci operandu po prawej stronie, poniewa wynikiem
caego wyraenia logicznego jest fasz. Programista moe wymusi obliczanie wartoci obu
operandw przy uyciu dyrektyw kompilatora $B lub $BOOlEVAL.
Operator and, dziaajcy na wartociach cakowitych, porwnuje ze sob kolejne pary bitw
obu operandw i ustawia wynik na zero, jeeli dowolny z nich jest zerem, lub jeden, jeeli oba
bity s jedynkami. Jeeli jeden z operandw jest mniejszy od drugiego, zostaje powikszony
przez dodanie zer na najbardziej znaczcych bitach (z lewej strony). Wynikiem operacji jest
liczba o rozmiarze wikszego z operandw.
var
I, J: Integer;
S: string;
begin
I:= $F0;
J:= $8F;
WriteLn(I and J); // Wypisuje 128 ($80)
// Zasada skracania operatora AND w nastpnym przykadzie
// uniemoliwia Delphi odwoanie si do nieistniejcego elementu
// acucha S[1].
S:= '';
if (Length(S) > 0) and (S[1] = 'X') then
Delete(S, 1, 1);
end;
Boolean, ByteBool, LongBool, Not, Or, Shl, Shr, WordBool, Xor, $B,
$BOOlEVAL
.
!$
type AnsiChar = #0..#255;
Typ AnsiChar reprezentuje 8-bitowy rozszerzony znak ANSI. W biecej wersji Delphi typ
Char jest zgodny z AnsiChar, jednak w kolejnych wersjach definicja tego typu moe zosta
zmieniona. AnsiChar pozostanie typem 8-bitowym, niezalenie od definicji typu Char.
AnsiString, Char, WideChar
"%
type AnsiString;
Typ AnsiString jest dugim acuchem (ze zliczaniem referencji), zawierajcym znaki typu
AnsiChar. Domylnie Delphi traktuje typ string jako synonim typu AnsiString. Jeeli
jednak programista uyje dyrektywy kompilatora $H- lub $LONGSTRINGS, typ string stanie
si takim samym typem, jak ShortString.
AnsiString jest przechowywany jako wskanik do rekordu, ale zamiast wskazywa pocztek
tego rekordu, wskazuje pocztek jednego z jego pl (o nazwie Data), przechowujcego faktyczne
dane. Zawarto acucha poprzedzaj pola Lenght i RefCount.
type
// Poniej znajduje si logiczna struktura typu AnsiString,
// bez zwizku z jego rzeczywist implementacj.
TAnsiString = record
RefCount: LongWord;
Length: LongWord;
Data: array[1..Length+1] of AnsiChar;
end;
Delphi zarzdza czasem ycia acuchw AnsiString poprzez zliczanie referencji. Jeeli
zajdzie taka potrzeba, licznikiem referencji mona manipulowa przy uyciu procedur
Initialize i Finalize.
Przypisanie acucha do zmiennej typu AnsiString powoduje skopiowanie wskanika do
tego acucha i zwikszenie licznika referencji. Poniewa Delphi stosuje semantyk kopiujprzy-zapisie, programista moe traktowa now zmienn w taki sposb, jakby posiadaa
"
wasn kopi acucha. Jeeli zawarto acucha, ktrego liczba referencji jest wiksza ni
jeden, zostanie zmieniona, Delphi automatycznie utworzy unikatow kopi acucha i do niej
wprowadzi modyfikacje.
Kady acuch pamita swoj dugo jako oddzieln warto typu cakowitego. Dugo
acucha moe zosta ustawiona przez wywoanie SetLength. Delphi automatycznie
wpisuje na koniec acucha znak #0 (ale nie uwzgldnia go w jego dugoci), umoliwiajc
tym samym zrzutowanie go na typ PChar, wymagany przez funkcje API Windows oraz inne
wzorowane na jzyku C.
AnsiChar, Finalize, Initialize, Length, PChar, SetLength, SetString,
ShortString, String, WideString, $H, $LONGSTRINGS
& '
function AnsiToUtf8(const S: string): UTF8String;
Funkcja konwertuje acuch S typu string (zapisany w formacie ANSI) na acuch zgodny z typem
UTF8String. Specyfik kodowania UTF-8 (8-bitowy format Unicode) jest moliwo przesyania kodw ANSI oraz ASCII praktycznie bez zmian. Tylko kody o numerach wikszych ni 127
podlegaj modyfikacji. Dziki temu np. polskie teksty nieznacznie powikszaj swoj objto.
AnsiChar, PChar, PUCS4Chars, ShortString, String, WideString, $H,
$LONGSTRINGS, UTF8String, Utf8ToAnsi, Utf8ToUnicode, UTF8Decode,
Utf8Encode, UnicodeToUtf8.
procedure Append(var F: TextFile);
Procedura Append otwiera istniejcy plik tekstowy do zapisu, ustawiajc si na jego kocu.
Wszelkie dane s dopisywane na kocu pliku.
Procedura Append jest wbudowana w kompilator. Przykad jej uycia znale mona w opisie
procedury AssignFile.
Jeeli przed Append nie zostaa wywoana procedura AssignFile, Delphi zgasza bd
wejcia-wyjcia o numerze 102.
Jeeli z jakiego powodu plik nie moe zosta otwarty, jako bd wejcia-wyjcia zgoszony
zostaje kod bdu Windows.
Procedura Append otwiera jedynie pliki tekstowe nie mona uywa jej do otwierania
plikw okrelonego typu lub innych plikw binarnych. Aby dopisa dane do pliku binarnego,
naley wywoa procedur Reset, a nastpnie przej na koniec pliku.
AssignFile, CloseFile, Eof, IOResult, Reset, Rewrite, TextFile, $I,
$IOCHECKS
&
function ArcTan(Number: typ zmiennoprzecinkowy): Extended;
Funkcja ArcTan zwraca arcustangens z liczby Number (w radianach). ArcTan jest funkcj
wbudowan.
Delphi automatycznie konwertuje argumenty typu Integer i Variant na typ
zmiennoprzecinkowy. Aby przekonwertowa argument typu Int64 na typ
zmiennoprzecinkowy, naley doda +0.0, np. 125 + 0.0.
Jeeli wartoci Number jest dodania nieskoczono, rezultatem jest /2 (lub mwic
dokadnie, przyblienie tej liczby); jeeli Number jest ujemn nieskoczonoci, rezultatem
jest przyblienie liczby -/2.
Jeeli Number jest niejawn wartoci nienumeryczn, wynikiem jest Number.
Jeeli Number jest jawn wartoci nienumeryczn, ArcTan zgasza bd czasu wykonania
nr 6 (EInvalidOp).
Cos, Sin
"
#
type Nazwa = array[typ indeksu] of typ bazowy;
type Nazwa =
type Nazwa =
Nazwa: array
Nazwa: array
// tablica
// statyczna
array[typ indeksu, ...] of typ bazowy;
// tablica
// statyczna
array of typ bazowy;
// tablica
// dynamiczna
of typ bazowy
// tablica otwarta jako parametr
// funkcji/procedury
of const
// wariantowa tablica otwarta jako parametr
// funkcji/procedury
Delphi posiada kilka rnych typw tablic: tablice statyczne, dynamiczne i otwarte.
Tablica statyczna jest tradycyjn tablic jzyka Pascal. Indeks tablicy musi by typu
porzdkowego. Tablica moe posiada wiele indeksw (wymiarw). Rozmiar tablicy
statycznej nie moe zosta zmieniony w trakcie wykonania programu.
Tablica dynamiczna jest tablic o indeksie typu Integer, ktrej rozmiar moe si
zmienia w trakcie wykonania programu. Doln granic indeksu jest zawsze zero, natomiast
granica grna jest ustawiana przez procedur SetLength. Aby skopiowa tablic dynamiczn,
naley wywoa procedur Copy. Przypisanie tablicy dynamicznej skutkuje przypisaniem jedynie
referencji do tablicy bez przepisywania jej zawartoci. Do zarzdzania czasem ycia tablic
dynamicznych Delphi uywa mechanizmu zliczania odwoa. W przypadku tablic dynamicznych
nie jest stosowana zasada kopiuj-przy-zapisie (jak ma to miejsce dla acuchw).
Parametrem procedury (funkcji) moe by tablica otwarta. Procedurze mona przekaza
dowoln statyczn lub dynamiczn tablic. Delphi przekazuje dodatkowy, ukryty parametr,
stanowicy grn granic tablicy. Procedura (funkcja) nie moe zmieni rozmiaru tablicy
dynamicznej, przekazywanej jako tablica otwarta. Niezalenie od typu indeksu rzeczywistej
tablicy, parametr w postaci tablicy otwartej uywa typu Integer dla indeksu z zerem jako
doln granic.
Specjalnym typem tablicy otwartej jest wariantowa tablica otwarta, deklarowana jako array of
const. Kady element takiej tablicy jest konwertowany na rekord TVarRec. Wariantowa tablica
otwarta jest najczciej stosowana w procedurach i funkcjach przyjmujcych zmienn liczb
argumentw (do ktrych naley midzy innymi funkcja Format z moduu SysUtils).
Tablica elementw typu AnsiChar, Char lub WideChar ma specjalny charakter, kiedy
indeks typu cakowitego rozpoczyna si od zera. Delphi traktuje tak tablic jako acuch lub
dugi acuch (o ile nie zostanie wyczona dyrektywa kompilatora $EXTENDEDSYNTAX lub
$X) z jednym wyjtkiem tablicy znakw nie mona przekaza do procedury przez zmienn
acuchow. Referencj tablicy mona przekaza przez argument do procedury, ktra
przyjmuje parametr typu PChar lub PWideChar. Delphi automatycznie przekazuje adres
pierwszego znaku w takiej tablicy.
Tablice przechowywane s w porzdku kolumnowym najszybciej zmieniajcym si
indeksem jest zawsze pierwszy indeks od prawej strony.
!
...
type
TIntArray = array of integer;
var
Counter: Integer;
TestInfo: string;
Ints: TIntArray;
implementation
{$R *.dfm}
// Doczenie komunikatu do pliku logowania.
function Log(const Fmt: string; const Args: array of
const):string; overload;
begin
Result:=Format(Fmt, Args);
end;
// Doczenie losowej liczby do tablicy dynamicznej.
// Poniewa tablice dynamiczne i tablice otwarte uywaj tej samej
// skadni, dla parametru tablicy dynamicznej trzeba zastosowa
// specjalnie nazwany typ.
procedure AppendRandomInt(var Ints: TIntArray);
begin
SetLength(Ints, Length(Ints) +1);
Ints[High(Ints)] := Random(MaxInt);
end;
//-----------------------------------------procedure TForm1.Button1Click(Sender: TObject);
var I : Integer;
begin
//
...
for I := 1 to 10 do
AppendRandomInt(ints);
Form1.Edit1.Text := Log('Test: #%d: %s', [I, 'Login'])
+IntToStr(Ints[High(Ints)]);
end;
end.
Copy, High, Length, Low, PAnsiChar, PChar, PWideChar, SetLength, Slice,
Type, TVarRec, $EXTENDEDSYNTAX, $X
#
Referencja obiektu as typ klasowy
Obiekt lub referencja interfejsu as typ interfejsu
Operator as konwertuje referencj obiektu na inny typ klasowy lub referencj interfejsu na inny
typ interfejsu. Po prawej stronie operatora powinien wystpowa typ klasowy lub typ interfejsu.
"
(
Jeeli obiekt lub referencja interfejsu zawiera nil, wynikiem bdzie rwnie nil.
Zadeklarowana klasa obiektu musi by potomkiem lub rodzicem typu klasowego. Jeeli
referencja obiektu nie posiada odpowiedniego typu, kompilator generuje bd. Jeeli
zadeklarowany typ jest poprawny, ale rzeczywisty typ obiektu w trakcie wykonania
programu nie jest typem klasowym, Delphi generuje bd czasu wykonania o numerze 10
(EInvalidCast).
Uycie operatora as naley ogranicza jedynie do rzutowania typw referencji obiektw.
Wyjtkiem od tej reguy s sytuacje, w ktrych typ jest znany dziki wczeniejszemu uyciu
operatora is.
Jeeli typem docelowym jest interfejs, Delphi wywouje metod QueryInterface,
przekazujc jej jako pierwszy argument identyfikator GUID typu interfejsu. Jeeli obiekt
nie implementuje interfejsu, Delphi generuje bd 23 (EIntfCastError).
// Gdy dowolne pole wyboru jest zaznaczone, uaktywnij przycisk OK.
// Ponisza procedura obsugi zdarzenia moe zosta uyta dla
// kilku pl wyboru jednoczenie.
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
if (Sender as TCheckBox).Checked then
OkButton.Enabled := True;
end;
Interface, Is, TObject
#
asm
instrukcje assemblera
end;
Blok asm jest wyraeniem, ktre mona stosowa wszdzie tam, gdzie dozwolone jest uycie
wyraenia lub bloku jzyka Pascal (np. w procedurze lub funkcji).
Wewntrz bloku assemblera mona odwoywa si do zmiennych, a take skaka do etykiet
zadeklarowanych w innym miejscu procedury. Nie naley korzysta z instrukcji skoku
w obrbie macierzystej ptli (lub do innej ptli), chyba e jest to naprawd niezbdne. Etykieta
rozpoczyna si od znaku @, jest lokalna wzgldem procedury i nie musi by deklarowana.
)
unit cpuid;
// Identyfikacja procesora
// Modu definiuje funkcj GetCpuID, ktra uywa polecenia CPUID do
// pobrania typu procesora. GetCpuID zwraca prawd, jeeli procesor
// posiada instrukcj CPUID i fasz w przeciwnym wypadku.
// Starsze wersje procesorw 486 oraz przodkowie tej serii nie
// posiadaj instrukcji CPUID.
// Copyright 1999 Tempest Software, Inc.
interface
const
VendorIntel = 'GenuineIntel';
VendorAMD
= 'AuthenticAMD';
VendorCyrix = 'CyrixInstead';
type
TCpuType = (cpuOriginalOEM, cpuOverdrive, cpuDual, cpuReserved);
TCpuFeature = (cfFPU, cfVME, cfDE, cfPDE, cfTSC, cfMSR, cfMCE,
cfCX8, cfAPIC, cfReserved10, cfReserved11, cfMTRR, cfPGE, cfMCA,
cfCMOV, cfPAT, cfReserved17, cfReserved18, cfReserved19,
cfReserved20, cfReserved21, cfReserved22, cfReserved23, cfMMX,
cfFastFPU, cfReserved26, cfReserved27, cfReserved28,
cfReserved29, cfReserved30, cfReserved31);
TCpuFeatureSet = set of TCpuFeature;
UInt4 = 0..15;
TCpuId = packed record
CpuType: TCpuType;
Family: UInt4;
Model: UInt4;
Stepping: UInt4;
Features: TCpuFeatureSet;
Vendor: string[12];
end;
// Pobranie informacji o CPU i zapisanie jej w Cpuid.
function GetCpuID(var Cpuid: TCpuId): Boolean;
implementation
function GetCpuID(var Cpuid: TCpuId): Boolean;
asm
// Sprawdzenie, czy procesor obsuguje instrukcj CPUID
// Test zmienia wartoci rejestrw EXC i EDX.
pushfd
"
pop ecx
mov edx, ecx
xor ecx, $200000
push ecx
popfd
pushfd
pop ecx
xor ecx, edx
je @NoCpuID
//
//
//
//
,
CDecl, Pascal, Register, SafeCall, StdCall
Nagwek procedury; assembler;
Dyrektywa assembler nie ma adnego znaczenia. Istnieje dla zachowania zgodnoci z Delphi 1.
Asm
procedure Assert(Test : Boolean [; const Message: string]);
Waciwe uycie procedury Assert polega na wyspecyfikowaniu warunkw, jakie musz
by spenione w celu prawidowego dziaania kodu. Wszystkie programy czyni pewne
zaoenia odnonie wewntrznego stanu obiektu, wartoci lub poprawnoci argumentw
procedury, wartoci zwracanej przez funkcj. Dobrym rozwizaniem odnonie zaoe jest to,
aby sprawdzay one bdy programistw, a nie bdy uytkownikw.
$/"
-
Chocia dziaanie funkcji Assert moe zosta wyczone przy uyciu dyrektyw kompilatora
$ASSERTIONS lub $C, zazwyczaj nie ma takiej potrzeby. Wywietlenie komunikatu
assertion error jest niepokojcym symptomem dla uytkownika, niemniej jednak o wiele
lepiej bdzie, jeeli program zakoczy si dziwnym komunikatem, ni gdyby mia dziaa
dalej i na przykad uszkodzi cenne dane uytkownika.
Niniejszy podrozdzia zawiera kilka przykadw uycia procedury Assert, wystpujcych w opisie
innych elementw jzyka patrz procedura Move, funkcja TypeInfo, funkcje VarArrayLock i VarIsArray.
AssertErrorProc, $ASSERTIONS, $C
var AssertErrorProc: TAssertErrorProc;
procedure AssertErrorHandler(const Message, Filename: string;
LineNumber: Integer; ErrorAddr: Pointer)
AssertErrorProc:= @AssertErrorHandler;
Kiedy zaoenie programu nie zostanie spenione, Delphi wywouje procedur o adresie przechowywanym w zmiennej AssertErrorProc. Kompilator przekazuje tej procedurze komunikat
oraz lokalizacj wyraenia Assert.
Programista moe zaimplementowa w tej procedurze dowolne funkcje programu, takie jak
logowanie bdu, wysyanie poczty do osoby odpowiedzialnej za sprawne dziaanie aplikacji
itp. W przeciwiestwie do innych procedur obsugi bdu, AssertErrorProc pozwala na
kontynuowanie programu od wyraenia nastpujcego za wywoaniem procedury Assert.
Jeeli AssertErrorProc wskazuje nil, Delphi generuje bd czasu wykonania 21
(EAssertError).
Modu SysUtils przypisuje zmiennej AssertErrorProc adres procedury generujcej
wyjtek EAssertError.
AbstractErrorProc, Assert, ErrorProc, ExceptProc
.
%
procedure Assign(var F: File; const FileName: string);
procedure Assign(var F: TextFile; const FileName: string);
Procedura Assign wykonuje takie samo zadanie, jak AssignFile. W nowym kodzie zalecane
jest stosowanie procedury AssignFile Assign jest nazw metody czsto stosowan w Delphi,
w zwizku z czym atwo moe doj do nieporozumienia w kodzie. Assign nie jest rzeczywist
procedur.
AssignFile
%
function Assigned(const P: Pointer): Boolean;
function Assigned(Pbj: TObject): Boolean;
function Assigned(Method: TMethod): Boolean;
Funkcja Assigned zwraca prawd, jeeli argument jest rny od nil, lub fasz, jeeli argument
jest pusty (rwny nil). Assigned nie jest rzeczywist funkcj.
Argument moe by wskanikiem, referencj obiektu lub metod.
Stosowanie funkcji Assigned zamiast bezporedniego porwnania wskanika z nil,
skutkuje spadkiem wydajnoci programu.
Jeeli wskanik jest wskanikiem funkcji, uycie Assigned daje jasno do zrozumienia
kompilatorowi, e intencj programisty nie jest wywoanie funkcji i porwnanie jej wyniku
z nil. Dlatego Assigned jest czsto stosowana do testowania wskanikw funkcji i metod.
Wskanik metody skada si z dwch czci: wskanika kodu i wskanika danych. Assigned
sprawdza jedynie bardziej znaczce sowo referencji kodu: jeeli sowo to zawiera zero,
referencja metody jest rwna nil. Wskanik kodu jest ignorowany przez Assigned.
procedure TForm1.Button1Click(Sender: TObject);
var P: Pointer;
01"
begin
P := nil;
if Assigned(P) then
Edit1.Text:='wskanik nie dotyczy funkcji';
GetMem(P, 1024);
FreeMem(P, 1024);
if Assigned(P) then
Edit1.Text:=' testowana funkcja GetMem()';
end;
Nil
%(
procedure AssignFile(var F: File; const FileName: string);
procedure AssignFile(var F: TextFile; const FileName: string);
AssignFile przypisuje nazw pliku do pliku o okrelonym lub nieokrelonym typie lub do pliku
tekstowego (przed otwarciem). AssignFile nie jest rzeczywist procedur.
Jeeli przed wywoaniem jednej z procedur Append, Reset lub Rewrite nie zostanie
wywoana procedura AssignFile, zgoszony zostanie bd wejcia-wyjcia o numerze 102.
Delphi interpretuje pusty acuch jako konsol. W aplikacji typu konsolowego do konsoli
przypisywane s automatycznie pliki Input i Output. Prba uycia pliku konsolowego
w aplikacji z interfejsem graficznym skutkuje bdem wejcia-wyjcia o numerze 105.
var
LogFile: string = 'c:\log.txt';
// Dodanie komunikatu do pliku dziennika. Przykad w opisie sowa
// kluczowego Keyword demonstruje inn przecion procedur Log.
procedure Log(const Msg: string); overload;
var
F: TextFile;
begin
AssignFile(F, LogFile);
// Prba otwarcia pliku, ktra powiedzie si tylko w przypadku, gdy
// plik istnieje.
{$IOCHECKS Off}
Append(F);
{$IOCHECKS On}
if IOResult <> 0 then
// Plik nie istnieje, naley go zatem utworzy.
Rewrite(F);
WriteLn(F, Msg);
CloseFile(F);
end;