background image

Wydawnictwo Helion

ul. Chopina 6

44-100 Gliwice

tel. (32)230-98-63

e-mail: helion@helion.pl

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 NOWOŒCIACH

ZAMÓW INFORMACJE

O NOWOŒCIACH

ZAMÓW CENNIK

ZAMÓW CENNIK

CZYTELNIA

CZYTELNIA

FRAGMENTY KSI¥¯EK ONLINE

FRAGMENTY KSI¥¯EK ONLINE

SPIS TREŒCI

SPIS TREŒCI

DODAJ DO KOSZYKA

DODAJ DO KOSZYKA

KATALOG ONLINE

KATALOG ONLINE

Delphi 6.

Vademecum

profesjonalisty. Tom I

Autorzy: Xavier Pacheco, Steve Teixeira

T³umaczenie: Andrzej Gra¿yñski

ISBN: 83-7197-690-9

Tytu³ orygina³u:

Format: B5, stron: oko³o 620

Zawiera CD-ROM

Delphi 6 Developer's Guide

Teixeira i Pacheco wci¹¿ dziel¹ siê z czytelnikami sw¹ wiedz¹ i doœwiadczeniem, ucz¹c,

jak tworzy siê aplikacje bazodanowe — lokalne, wielowarstwowe i internetowe oraz

nowe komponenty, biblioteki DLL itd. Czytaj¹c tê ksi¹¿kê, masz niepowtarzaln¹ okazjê

podnieœæ swoje kwalifikacje, gdy¿ umo¿liwia ona zapoznanie siê m.in. z zasadami

tworzenia aplikacji miêdzyplatformowych, metodologi¹ tworzenia komponentów i ich

edytorów, filozofi¹ programowania obiektowego i programowaniem wspó³bie¿nym.
Niniejsza ksi¹¿ka, napisana przez dwukrotnych laureatów nagrody za najlepsz¹ ksi¹¿kê

o Delphi, przyznanej przez czytelników Delphi Informant, stworzona przez programistów

dla programistów, to miarodajny przewodnik po nowoœciach Delphi 6.

Czytaj¹c Delphi 6. Vademecum profesjonalisty, poznasz miêdzy innymi:

"

"
"

"
"
"

"
"

historiê Delphi i techniczne oraz ekonomiczne uwarunkowania jego rozwoju,
bogactwo œrodowiska IDE i wspó³dzia³anie jego elementów w procesie tworzenia

aplikacji,
najwa¿niejsze elementy jêzyka Object Pascal,
szczegó³y biblioteki CLX i zasady tworzenia aplikacji miêdzyplatformowych dla

Windows i Linuksa,
mechanizm komunikatów Windows i zasady ich obs³ugi w tworzonych

aplikacjach,
podstawy tworzenia i wykorzystywania bibliotek DLL,
realizacjê programowania wspó³bie¿nego za pomoc¹ w¹tków i w³ókien oraz

mechanizmów synchronizuj¹cych,
zastosowanie nowych komponentów bazodanowych dbExpress i dbGo for ADO.

background image

    
    
    



      

       !

Rodzina produktów Delphi ....................................................................................................21
Delphi — co i dlaczego?........................................................................................................23

Komfort wizualnego projektowania aplikacji .................................................................24
Szybkość kompilacji kontra efektywność generowanego kodu ......................................25
Możliwości języka programowania w kontekście jego złożoności.................................26
Elastyczność i skalowalność architektury baz danych ....................................................27
Wzorce projektowania i użytkowania wymuszone przez strukturę środowiska .............27

Nieco historii..........................................................................................................................28

Delphi 1 ...........................................................................................................................28
Delphi 2 ...........................................................................................................................29
Delphi 3 ...........................................................................................................................30
Delphi 4...........................................................................................................................31
Delphi 5 ...........................................................................................................................31
Delphi 6 ...........................................................................................................................32

Środowisko zintegrowane Delphi 6 .......................................................................................32

Okno główne....................................................................................................................32
Projektant formularzy ......................................................................................................34
Inspektor obiektów ..........................................................................................................35
Edytor kodu .....................................................................................................................36
Eksplorator kodu..............................................................................................................36
Hierarchia obiektów ........................................................................................................36

Kod źródłowy projektu ..........................................................................................................36
Prosta aplikacja ......................................................................................................................38
Jeszcze o zdarzeniach... .........................................................................................................40

Niekontraktowy charakter obsługi zdarzeń .....................................................................40

Prototypowanie kodu .............................................................................................................41
Rozbudowa zestawu komponentów i konfigurowalne środowisko.......................................42
Top 10 — gorąca dziesiątka IDE...........................................................................................42

1. Uzupełnianie klas ........................................................................................................42
2. Udostępnianie deklaracji symbolu...............................................................................43
3. Od deklaracji do definicji ............................................................................................43
4. Dokowanie...................................................................................................................43
5. Object Browser ............................................................................................................44
6. GUID ...........................................................................................................................44
7. Wyróżnianie składni plików C++................................................................................44

background image



    

8. Znaczniki To Do… ......................................................................................................45
9. Menedżer projektów ....................................................................................................45
10. Code Insight...............................................................................................................45

Podsumowanie .......................................................................................................................46

!  "#$%     &

Komentarze ............................................................................................................................47
Nowości w zakresie procedur i funkcji..................................................................................48

Puste nagłówki wywołań .................................................................................................48
Przeciążanie .....................................................................................................................49
Domyślne parametry........................................................................................................50

Zmienne .................................................................................................................................51
Stałe .......................................................................................................................................52
Operatory ...............................................................................................................................55

Operator przypisania........................................................................................................55
Operatory porównania .....................................................................................................55
Operatory logiczne ..........................................................................................................55
Operatory arytmetyczne ..................................................................................................56
Operatory bitowe .............................................................................................................57
Operatory zwiększania i zmniejszania ............................................................................57
Operatory „wykonaj i przypisz” ......................................................................................58

Typy języka Object Pascal.....................................................................................................58

Porównanie typów ...........................................................................................................59
Znaki ................................................................................................................................59
Mnogość łańcuchów… ....................................................................................................59
Typy wariantowe .............................................................................................................74
Typ Currency ...................................................................................................................88

Typy definiowane przez użytkownika ...................................................................................89

Tablice .............................................................................................................................89
Rekordy ...........................................................................................................................93
Zbiory ..............................................................................................................................94
Obiekty ............................................................................................................................97
Wskaźniki ........................................................................................................................98
Aliasy typów..................................................................................................................101

Rzutowanie i konwersja typów............................................................................................102
Zasoby łańcuchowe..............................................................................................................104
Instrukcje warunkowe..........................................................................................................104

Instrukcja If....................................................................................................................105
Instrukcja wyboru ..........................................................................................................106

Pętle .....................................................................................................................................106

Pętla For.........................................................................................................................106
Pętla While...Do.............................................................................................................107
Pętla Repeat...Until ........................................................................................................108
Procedura Break()..........................................................................................................108
Procedura Continue ()....................................................................................................109

Procedury i funkcje ..............................................................................................................110

Przekazywanie parametrów do procedur i funkcji ........................................................111

Zasięg deklaracji ..................................................................................................................118
Moduły.................................................................................................................................118

Dyrektywa uses..............................................................................................................119
Cykliczna zależność między modułami ........................................................................120

Pakiety .................................................................................................................................122

Wykorzystywanie pakietów ..........................................................................................123
Składnia pakietu ............................................................................................................123

background image





Programowanie zorientowane obiektowo............................................................................123

Środowisko bazujące na obiektach kontra środowisko zorientowane obiektowo.........125

Wykorzystanie obiektów w Delphi......................................................................................126

Deklarowanie obiektów i kreowanie zmiennych obiektowych .....................................126
Destrukcja obiektu .........................................................................................................127
Metody...........................................................................................................................127
Właściwości...................................................................................................................131
Widoczność elementów obiektu ....................................................................................133
Wewnątrz obiektów .......................................................................................................134
TObject — protoplasta wszystkich klas ........................................................................135
Interfejsy ........................................................................................................................136

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

Wyjątki jako klasy .........................................................................................................144
Wyjątki a przepływ sterowania w programie ................................................................145
Ponowienie wyjątku ......................................................................................................147

RTTI.....................................................................................................................................148
Podsumowanie .....................................................................................................................149

  $'( 

Natura komunikatów............................................................................................................151
Typy komunikatów ..............................................................................................................152
Jak funkcjonuje system komunikatów Windows?...............................................................152
Obsługa komunikatów w kategoriach Delphi......................................................................154

Struktury specyficzne dla różnych typów komunikatów ..............................................155

Przetwarzanie komunikatów................................................................................................155

Kontraktowy charakter obsługi komunikatów ..............................................................157
Zwrotne przekazywanie wyniku obsługi komunikatu...................................................158
Zdarzenie OnMessage klasy TApplication....................................................................159

Wysyłanie własnych komunikatów .....................................................................................159

Metoda Perform() ..........................................................................................................160
Funkcje SendMessage() i PostMessage() ......................................................................160

Komunikaty niestandardowe ...............................................................................................160

Komunikaty powiadamiające ........................................................................................161
Wewnętrzne komunikaty VCL ......................................................................................161
Komunikaty definiowane przez użytkownika ...............................................................163

Anatomia systemu komunikatów VCL................................................................................165
Związek komunikatów ze zdarzeniami Delphi....................................................................174
Podsumowanie .....................................................................................................................174

          

&  )* +

Założenia ogólne..................................................................................................................179

Która wersja? .................................................................................................................179
Moduły, komponenty i pakiety......................................................................................181
Zmiany w środowisku IDE............................................................................................181

Zgodność pomiędzy Delphi i Kyliksem ..............................................................................182

Nie w Linuksie...............................................................................................................183
Różnice między kompilatorami.....................................................................................183
Indywidualne cechy platformy systemowej ..................................................................184

Nowości Delphi 6 ................................................................................................................184

Definiowalne typy wariantowe......................................................................................185
Jawne wartościowanie elementów typu wyliczeniowego .............................................185
Dyrektywa $IF...............................................................................................................185
Możliwa niezgodność plików *.DFM ...........................................................................185

background image



    

Migracja z Delphi 5 .............................................................................................................185

Zmiana wartości stałych typowanych............................................................................185
Negacja wartości typu Cardinal.....................................................................................186

Migracja z Delphi 4.............................................................................................................186

Zmiany w zakresie biblioteki RTL ................................................................................186
Zmiany w bibliotece RTL..............................................................................................187
Zmiany w zakresie obsługi Internetu.............................................................................188
Zmiany w obsłudze baz danych.....................................................................................188

Migracja z Delphi 3 .............................................................................................................189

32-bitowe liczby całkowite bez znaku...........................................................................189
64-bitowe liczby całkowite............................................................................................190
Typ Real ........................................................................................................................190

Migracja z Delphi 2 .............................................................................................................190

Zmiany w zakresie typów boolowskich ........................................................................191
Dyrektywa resourcestring..............................................................................................191
Zmiany w bibliotece RTL..............................................................................................192
Klasa TCustomForm......................................................................................................192
Metoda GetChildren()....................................................................................................192
Serwery automatyzacji ..................................................................................................193

Migracja z Delphi 1 .............................................................................................................193

Znaki i łańcuchy ............................................................................................................193
Rozmiar i zakres zmiennych..........................................................................................201
Wyrównywanie pól rekordów .......................................................................................201
32-bitowa arytmetyka ....................................................................................................202
Różnice dotyczące typu TDateTime..............................................................................203
Sekcja finalization .........................................................................................................203
Język asemblera .............................................................................................................204
Biblioteki DLL ..............................................................................................................205
Zmiany związane z systemem operacyjnym .................................................................206

Podsumowanie .....................................................................................................................210

   %, !

Natura wątków .....................................................................................................................211

Rodzaje wielozadaniowości ..........................................................................................211
Do czego może się przydać wielowątkowość?..............................................................212
Wielowątkowość a komponenty VCL...........................................................................212
Błędne wykorzystanie wielowątkowości.......................................................................213

Klasa TThread......................................................................................................................213

Obiekty wątków a zmienne ...........................................................................................216
Kończenie wątku ...........................................................................................................216
Synchroniczne wykorzystywanie komponentów VCL .................................................218
Przykładowa aplikacja wielowątkowa...........................................................................221
Priorytety i szeregowanie wątków.................................................................................222
Zawieszanie i wznawianie wątków ...............................................................................225
Pomiar czasu w ramach wątku ......................................................................................225

Współdziałanie wątków aplikacji ........................................................................................228

Pamięć lokalna wątku ....................................................................................................228
Synchronizacja wątków .................................................................................................232

Przykład zastosowania wielowątkowości: zaawansowane wyszukiwanie tekstu ...............244

Interfejs użytkownika ....................................................................................................245
Proces przeszukiwania...................................................................................................251
Zmiana priorytetu wątku przeszukującego....................................................................256

Wielowątkowy dostęp do BDE............................................................................................257

background image





Wielowątkowe operacje graficzne.......................................................................................263
Włókna.................................................................................................................................267
Podsumowanie .....................................................................................................................273

-

.$ //  !

Czym w istocie jest biblioteka DLL ....................................................................................275

Bazowy adres ładowania modułu ..................................................................................276
Nieco terminologii… .....................................................................................................277

Łączenie statyczne kontra łączenie dynamiczne..................................................................278
Korzyści płynące z używania DLL......................................................................................279

Współdzielenie kodu, zasobów i danych przez wiele aplikacji.....................................279
Ukrycie szczegółów implementacyjnych ......................................................................280

Tworzenie i wykorzystywanie bibliotek DLL .....................................................................281

Prosty przykład — poznaj siłę swych pieniędzy ...........................................................281
Formularze modalne w bibliotekach DLL.....................................................................283
Formularze niemodalne w bibliotekach DLL................................................................285

Wykorzystywanie bibliotek DLL w aplikacjach Delphi .....................................................287

Automatyczne ładowanie biblioteki DLL .....................................................................287
Ładowanie biblioteki DLL na żądanie ..........................................................................289

Procedura inicjująco-kończąca biblioteki DLL ...................................................................291

Definiowanie procedury inicjująco-kończącej ..............................................................291

Obsługa wyjątków w bibliotekach DLL ..............................................................................296

Wyjątki a klauzula Safecall ...........................................................................................297

Funkcje zwrotne...................................................................................................................297

Działanie funkcji zwrotnej.............................................................................................300
Specyficzne wyświetlanie elementów listy ...................................................................301
Wywoływanie funkcji zwrotnych z bibliotek DLL .......................................................301

Współdzielenie danych biblioteki DLL przez różne procesy ..............................................303

Tworzenie bibliotek DLL z pamięcią dzieloną .............................................................304
Dzielenie globalnych danych biblioteki przez aplikacje ...............................................307

Eksportowanie obiektów z bibliotek DLL...........................................................................310
Podsumowanie .....................................................................................................................314

          !"#$

  .    

Typy baz danych ..................................................................................................................317
Architektura bazy danych ....................................................................................................318
Połączenia z serwerami baz danych.....................................................................................318
Zbiory danych ......................................................................................................................319

Otwieranie i zamykanie zbioru danych .........................................................................320
Nawigowanie wśród rekordów zbioru danych ..............................................................323
Manipulowanie zawartością zbioru danych ..................................................................326

Pola rekordu bazy danych....................................................................................................331

Wartości pól...................................................................................................................331
Typy pól.........................................................................................................................332
Nazwy i numery pól ......................................................................................................332
Operowanie zawartością pól..........................................................................................333
Edytor pól ......................................................................................................................334
Pola typu BLOB ............................................................................................................340

Filtrowanie danych...............................................................................................................345
Przeszukiwanie zbiorów danych..........................................................................................346

FindFirst() i FindNext() .................................................................................................347
Lokalizowanie rekordu za pomocą metody Locate() ....................................................347
Przeszukiwanie tabeli za pomocą indeksów..................................................................348

background image

    

Moduły danych ....................................................................................................................352
Wyszukiwanie, zakresy, filtrowanie ....................................................................................352
Zakładki ...............................................................................................................................360
Podsumowanie .....................................................................................................................361

0  ) %$

 , $12  -

Specyfika technologii dbExpress.........................................................................................363

Jednokierunkowe zbiory danych tylko do odczytu .......................................................363
dbExpress kontra BDE ..................................................................................................364
dbExpress a aplikacje międzyplatformowe ...................................................................364

Komponenty dbExpress .......................................................................................................364

TSQLConnection...........................................................................................................364
TSQLDataSet.................................................................................................................367
Komponenty kompatybilne ...........................................................................................371
TSQLMonitor ................................................................................................................372

Edytowalne, dwukierunkowe zbiory danych dbExpress .....................................................372

TSQLClientDataSet.......................................................................................................372

Realizacja aplikacji dbExpress ............................................................................................373
Podsumowanie .....................................................................................................................373

+  ) %$  ,$34   

Strategia uniwersalnego dostępu do danych ........................................................................375
OLE DB, ADO i ODBC w zarysie ......................................................................................375
Wykorzystanie technologii dbGo for ADO .........................................................................376

Ustanawianie połączenia z bazą danych za pomocą dostawcy OLE DB ......................376
Przykładowa baza danych .............................................................................................378

Komponenty dbGo for ADO ...............................................................................................378
Przetwarzanie transakcyjne..................................................................................................384
Podsumowanie .....................................................................................................................386

%          & #'

 5   '678/8/9  0+

CLX — odsłona pierwsza....................................................................................................389
Co to jest komponent? .........................................................................................................389
Hierarchia komponentów.....................................................................................................390

Komponenty niewizualne ..............................................................................................390
Komponenty wizualne ...................................................................................................391

Struktura komponentu..........................................................................................................393

Właściwości komponentu..............................................................................................394
Metody...........................................................................................................................396
Zdarzenia .......................................................................................................................397
Komponenty jako właściciele innych komponentów ....................................................399
Komponenty rodzicielskie .............................................................................................400

Hierarchia komponentów wizualnych .................................................................................400

Klasa TPersistent ...........................................................................................................401
Klasa TComponent ........................................................................................................402
Klasa TControl ..............................................................................................................404
Klasy TWinControl i TWidgetControl..........................................................................404
Klasa TGraphicControl..................................................................................................406
Klasy kategorii TCustom…...........................................................................................406
Pozostałe klasy ..............................................................................................................407

background image



 

Wykorzystanie informacji RTTI..........................................................................................410

Informacja o genealogii i zestawie właściwości klasy ..................................................411
Przypisywanie właściwościom wartości za pośrednictwem RTTI................................433

Podsumowanie .....................................................................................................................436

  )'78/  & 

Podstawy tworzenia komponentów .....................................................................................438

Czy tworzenie nowego komponentu w ogóle jest konieczne? ......................................438
Etapy tworzenia nowego komponentu ..........................................................................439
Rejestrowanie komponentu ...........................................................................................460
Testowanie komponentu................................................................................................461
Wybór ikony dla komponentu .......................................................................................463

Przykładowe komponenty....................................................................................................464

Rozszerzenia kontrolek Win32......................................................................................464
Komponent TddgRunButton .........................................................................................473

Komponenty-pojemniki — TddgButtonEdit .......................................................................478

Koncepcja ......................................................................................................................479
Definiowanie właściwości .............................................................................................479
Definiowanie zdarzeń ....................................................................................................480
TddgDigitalClock — jeszcze jeden przykład definiowania zdarzeń.............................482
Umieszczanie kompletnych formularzy w palecie komponentów ................................485

Podsumowanie .....................................................................................................................487

 !  : '  &0+

Komponenty pseudowizualne..............................................................................................489

Niestandardowe podpowiedzi kontekstowe ..................................................................489

Animowane komponenty .....................................................................................................493

Komponent TddgMarquee.............................................................................................494
Testowanie komponentu TddgMarquee ........................................................................504

Tworzenie edytorów właściwości........................................................................................506
Definiowanie nowej klasy edytora.......................................................................................506

Edycja właściwości w postaci linii tekstu .....................................................................508
Rejestracja nowego edytora właściwości ......................................................................512
Edycja właściwości za pomocą okna dialogowego .......................................................512

Edytory komponentów.........................................................................................................516

TComponentEditor ........................................................................................................516
TDefaultEditor...............................................................................................................517
Przykład edycji komponentu .........................................................................................517
Rejestracja edytora komponentu ...................................................................................519

Przechowywanie w strumieniach niepublikowanych danych komponentu.........................520

Określenie strumieniowalnego charakteru właściwości................................................520

Kategoryzacja właściwości..................................................................................................530

Klasy kategorii właściwości ..........................................................................................531

Kolekcje komponentów — klasy TCollection i TCollectionItem .......................................535

Przykładowy element kolekcji — klasa TRunBtnItem .................................................537
TRunButtons — kolekcja komponentu .........................................................................537
Implementacja — współpraca kolekcji i jej elementów

z komponentem macierzystym ...................................................................................538

Edycja kolekcji i jej elementów w dialogowym edytorze właściwości ........................545

Podsumowanie .....................................................................................................................550

  ;#4 

CLX — co to jest? ...............................................................................................................551
Architektura CLX ................................................................................................................552

background image

!

    

Z Windows do Linuksa........................................................................................................555

Nie ma komunikatów….................................................................................................555
Przykładowe komponenty .............................................................................................556

Edytory środowiskowe CLX ...............................................................................................585
Pakiety .................................................................................................................................589

Konwencje nazewnicze .................................................................................................590
Pakiety wykonywalne....................................................................................................591
Pakiety środowiskowe ...................................................................................................593

Ikony komponentów ............................................................................................................596
Podsumowanie .....................................................................................................................597

( $

  <' * == -5
<  -5

background image

Rozdział 13.

Trzy  poprzednie  rozdziały  poświęcone  były  architekturze  i  projektowaniu  komponen-
tów  VCL,  przeznaczonych  dla  platformy  MS  Windows.  W  niniejszym  rozdziale  zaj-
miemy się podstawami projektowania komponentów CLX, umożliwiających tworzenie
aplikacji zarówno dla Windows, jak i dla Linuksa. Tak się szczęśliwie składa, iż znacz-
na  część  umiejętności  nabyta  podczas  projektowania  komponentów  VCL  okaże  się
przydatna również w odniesieniu do komponentów CLX.

CLX — wymawiane najczęściej jako „clicks” — to akronim od Component Library for
Cross-Platform,  czyli  „międzyplatformowej  biblioteki  komponentów”;  pojawił  się  po
raz  pierwszy  w  związku  z  Kyliksem  —  wywodzącym  się  z  Delphi  narzędziem  typu
RAD  dla  Linuksa.  Biblioteka  CLX  jest  jednak  czymś  więcej  niż  tylko  adaptacją  VCL
na  gruncie  Linuksa:  jej  obecność  w  Delphi  6  umożliwia  (po  raz  pierwszy  w  historii
Delphi) przekroczenie granic Windows i tworzenie aplikacji zgodnych zarówno z Del-
phi, jak i Kyliksem.

Ponadto biblioteka VCL (w Delphi) utożsamiana bywa raczej z komponentami wizual-
nymi  (również  w  nazwie),  co  nie  powinno  dziwić  wobec  faktu,  iż  komponenty  te  sta-
nowią większą jej część (i jednocześnie lwią część palety komponentów). Tymczasem
architektura CLX jest nieco bardziej złożona, bo oprócz wizualnych komponentów grupy



 zawiera także komponenty 

 

 

 i 

 

.

 

  to  grupa  klas  i  modułów  wspólnych  dla  Delphi  6  i  Kyliksa  —  należą  do  niej

m.in. moduły 

 

 

 i 

 

, określane w Delphi (od początku) mianem

biblioteki  RTL.  Mimo  iż  moduły  te  stanowić  mogą  składniki  aplikacji  obydwu  typów
—  VCL  i  CLX  —  za  aplikację  CLX  zwykło  się  uważać  taką,  której  strona  wizualna
zrealizowana została na podstawie klas grupy 



.



  stanowi  odmianę  tego,  co  większość  programistów  skłonna  jest  uważać

(w Delphi) za VCL, jednak oparta jest nie na standardowych kontrolkach Windows

background image



 

K

     

z bibliotek 

  

 czy 

  

, lecz na tzw. widżetach

1

 zawartych w bibliote-

ce 



.  Do  grupy 

 

  zaliczają  się  komponenty  zapewniające  dostęp  do  danych  za

pomocą  nowej  technologii 

 

,  natomiast  nowe,  międzyplatformowe  oblicze

WebBrokera ucieleśniają komponenty grupy 

 

.

W  niniejszym  rozdziale  skoncentrujemy  się  głównie  na 



,  ze  szczególnym

uwzględnieniem tworzenia nowych komponentów na bazie tej architektury. Opiera się
ona (jak już wcześniej wspominaliśmy) na bibliotece 



 („cute”) firmy Troll Tech, sta-

nowiącej  niezależną  od  konkretnej  platformy  bibliotekę  klas  C++,  realizujących  funk-
cjonalność  widżetów  składających  się  na  interfejs  użytkownika.  Ściślej  —  w  chwili
obecnej biblioteka 



 zawiera elementy charakterystyczne dla środowisk MS Windows

oraz X Window System, może więc być wykorzystywana zarówno na potrzeby aplika-
cji windowsowych, jak i linuksowych; na jej podstawie zrealizowano właśnie linukso-
wy menedżer okien KDE.

Biblioteka 



  nie  jest  bynajmniej  jedyną  dostępną  międzyplatformową  biblioteką  klas;

to,  iż  Borland  zdecydował  się  właśnie  na  nią,  wynika  z  kilku  istotnych  przyczyn.  Po
pierwsze,  jej  klasy  podobne  są  w  dużym  stopniu  do  klas  komponentów  VCL  —  na
przykład  ich  właściwości  zrealizowane  zostały  z  udziałem  metod  dostępowych 

 

xxxx/



xxxx, po drugie — wykorzystują podobny do VCL mechanizm powiadamiania

o zdarzeniach (tzw. sygnały). Wreszcie po trzecie — jej widżety to nic innego jak stan-
dardowe  kontrolki  interfejsu  użytkownika,  spełniające  tę  samą  rolę  co  standardowe
kontrolki  Windows.  To  wszystko  pozwoliło  na  stworzenie  komponentów  biblioteki
CLX  przez  „nadbudowanie”  pascalowych  otoczek  wokół  gotowych  widżetów  —  za-
miast budowania całej architektury „od zera”.

Jak przed chwilą stwierdziliśmy, 



 jest grupą klas Object Pascala zbudowanych

na bazie funkcjonalności widżetów biblioteki 



 — co stanowi analogię do komponentów

VCL  zbudowanych  na  bazie  standardowych  kontrolek  Windows  i  biblioteki  Windows
API. Podobieństwo to nie jest bynajmniej przypadkowe, lecz wynika z jednego z celów
projektowych:  łatwości  przystosowywania  istniejących  aplikacji  VCL  do  architektury
CLX.  Rysunki  13.1  i  13.2  przedstawiają  hierarchiczną  strukturę  klas  w  obydwu  tych
środowiskach; przyciemnione prostokąty na rysunku 13.1 wyróżniają podstawowe klasy
biblioteki VCL.

Już na pierwszy rzut oka widać różnicę pomiędzy obydwiema hierarchiami — w archi-
tekturze CLX pojawiły się nowe (w stosunku do VCL) klasy, niektóre zostały przesu-
nięte do innych gałęzi. Różnice te zaznaczone zostały na rysunku 13.2 za pomocą rozja-
śnionych  prostokątów.  I  tak,  na  przykład,  komponent  zegarowy  (

   

)  nie  wywodzi

się  już  bezpośrednio  z  klasy 

 ! !

,  lecz  z  nowej  klasy 

 "! ! !

,  stano-

wiącej klasę bazową do obsługi wszystkich tych przypadków, gdy komponent niewizu-
alny wymaga dostępu do uchwytu (handle) jakiejś kontrolki 



. Innym przykładem jest

etykieta 

  

, nie będąca już kontrolką graficzną, lecz wywodząca się z klasy 

 # 

! 

, która wykorzystuje różnorodne możliwości kształtowania obrzeża widżetów 



.

                                                          

1

  To spolszczona postać angielskiego terminu widget, który jest zlepkiem słów Visual Gadget — przyp. tłum.

background image

  

K

!  "#  



  Hierarchia klas VCL

Nieprzypadkowe jest także podobieństwo nazw klas bazowych kontrolek wizualnych
— 

 $!! 

 (VCL) i 

 $% ! 

 (CLX): charakterystyczny dla Windows człon

„Win”  ustąpił  miejsca  charakterystycznemu  dla  CLX  „Widget”.  Mając  na  względzie
łatwość przenoszenia kodu źródłowego Borland zdefiniował klasę 

 $!! 

 także

w bibliotece CLX, stanowi ona jednak tylko synonim klasy 

 $% ! 

. Można

było  oczywiście  uniknąć  tej  nieco  mylącej  w  skutkach  (zwłaszcza  dla  nieświadomego
użytkownika) operacji i utworzyć dwa oddzielne moduły dla obydwu grup kontrolek,
a później odróżniać je za pomocą symboli kompilacji warunkowej; utrudniłoby to jed-
nak przenoszenie kodu źródłowego (identyfikator 

 $!! 

 straciłby rację bytu, a jego

systematyczna zmiana na 

 $% ! 

 wymagałaby dodatkowej fatygi), zaś w apli-

kacjach  międzyplatformowych  konieczne  byłoby  utrzymywanie  dwóch  identyfikatorów
na oznaczenie klasy bazowej kontrolek.

background image

$

 

K

     

Zwróć uwagę, iż utrzymywanie w pojedynczym pliku kodu dla obydwu typów
komponentów (VCL i CLX) jest czymś jakościowo różnym od tworzenia kodu
uniwersalnego komponentu CLX, dającego się użyć zarówno w Delphi 6, jak
i w Kyliksie (takimi komponentami zajmiemy się w dalszej części rozdziału).

  Hierarchia klas CLX

Na  szczęście  różnice  przedstawione  na  rysunku  13.2  nie  mają  zbyt  dużego  znaczenia
dla  twórców  aplikacji,  ponieważ  większość  komponentów  VCL  posiada  na  gruncie
CLX  identycznie  nazwane  odpowiedniki.  Nie  mają  jednak  takiego  szczęścia  twórcy
nowych komponentów — zmiany w hierarchii klas mają dla nich znaczenie zasadnicze.

Strukturę hierarchii klas można łatwo zobaczyć za pomocą przeglądarki obiektów
(Object Browser) w Delphi 6 i w Kyliksie; jednak ze względu na synonim 

 $!! ,

uzyskamy dwie identyczne hierarchie (dla 

 $% !  i  $!! ).

Pomiędzy  VCL  i  CLX  istnieje  jeszcze  więcej  podobieństw,  których  nie  sposób
uwzględnić na przedstawionych rysunkach. Na przykład znane z VCL płótno (

!&

)

ma w CLX niemal identyczną naturę i wykorzystywane jest w bardzo zbliżony sposób,

background image

  

K

!  "#  



choć  oczywiście  różnice  pomiędzy  obydwoma  środowiskami  przesądzają  o  jego
odmiennej  implementacji:  w  VCL  jest  ono  otoczką  kontekstu  urządzenia,  zaś  w  CLX
—  analogicznego  mechanizmu  zwanego  malarzem  (painter),  mimo  to  obydwa  te  me-
chanizmy reprezentowane są przez tę samą właściwość 

"!

. Ponadto, z uwagi na wymóg

łatwości  przenoszenia  kodu,  niemal  identycznie  wyglądają  interfejsy  komponentów
w obydwu  grupach  —  pod  względem  repertuaru  właściwości  publicznych  (

'

)

i publikowanych (

( 

) oraz zdarzeń (

)!'*

)!(!%

)!+ , 

) i ich metod

dyspozycyjnych (

'*-.

(!% -.

 i 

+ , -.

).

Mimo wielu podobieństw pomiędzy analogicznymi elementami komponentów VCL i CLX,
istniejące między tymi środowiskami różnice dają znać o sobie tym wyraźniej, im bliż-
sza staje się zależność konkretnego elementu od mechanizmu charakterystycznego tylko
dla jednego ze środowisk. I tak, w środowisku Kyliksa traci sens większość odwołań do
Win32 API; mechanizmy typowe jedynie dla Windows — jak np. MAPI — muszą być
zastąpione  równoważnymi  mechanizmami  linuksowymi,  a  używające  ich  komponenty
nie  nadają  się  po  prostu  do  przeniesienia  na  platformę  linuksową.  Z  kolei  niektóre
problemy  rozwiązywane  przez  funkcje  biblioteki  RTL  muszą  być  rozwiązane  w  inny
sposób — przykładem może być czułość Linuksa na wielkość liter w nazwach plików;
Pascal, niewrażliwy na wielkość liter w identyfikatorach, staje się pod Kyliksem wraż-
liwy na wielkość liter w nazwach modułów w dyrektywach 

 

!

Linux  pozbawiony  jest  też  wielu  znanych  z  Windows  mechanizmów  systemowych
— nie ma tu technologii COM, są jednak obsługiwane interfejsy; nie ma też dokowania
okien, „dwukierunkowej” (bidirectional) obsługi tekstu, lokalizowania charakterystycz-
nego dla krajów azjatyckich itp.

Pewnym  problemem  dla  autorów  aplikacji  i  komponentów  jest  istnienie  oddzielnych
modułów, dedykowanych tylko określonym platformom, na przykład kod kontrolek win-
dowsowych  znajduje  się  w  pliku  Controls.pas,  zaś  kod  dla  widżetów  CLX  —  w  pliku
QControls.pas.  Stwarza  to  możliwość  „pomieszania”  obydwu  środowisk  w  sytuacji,
gdy komponent CLX lub aplikacja przeznaczona dla Kyliksa opracowywane są w śro-
dowisku  Delphi  6.  Tak  skonstruowany  komponent,  jeżeli  zawiera  elementy  typowe
wyłącznie dla VCL, będzie bez problemu pracował w Delphi 6, najczęściej jednak od-
mówi współpracy pod Kyliksem. Można uniknąć takiej sytuacji, gdy, za radą Borlanda,
komponenty  i  aplikacje  przeznaczone  dla  Kyliksa  będziemy  opracowywać  pod  Kylik-
sem — niestety, środowisko Kyliksa jest (w zgodnej opinii programistów) mniej kom-
fortowe od Delphi 6.

Wobec opisanych konsekwencji różnic pomiędzy VCL i CLX, nie wydaje się uzasadnione
używanie komponentów CLX w aplikacjach przeznaczonych wyłącznie dla Windows.

  

Linux (a raczej — podsystem 

/$!0

) nie implementuje typowego dla Windows me-

chanizmu komunikatów; w efekcie nie do zaakceptowania jest w Kyliksie kod źródłowy

background image

%

 

K

     

odwołujący się do identyfikatorów w rodzaju 

01  ! 0!

01 

 czy 

01(

.

Reagowaniem na zachodzące w systemie zdarzenia zajmują się w bibliotece 



 wyspe-

cjalizowane klasy — dzieje się tak niezależnie od platformy systemowej, tak więc kom-
ponent  CLX  nie  jest  zdolny  reagować  na  komunikaty  nawet  pod  Windows;  zamiast
znanych z Delphi metod z klauzulą 

 %

 (np. 

2  (!% -.

), powinien on korzy-

stać z równoważnych metod dynamicznych (

   (!% -.

), co wyjaśnimy dokładniej

w następnym punkcie.

   

W niniejszym punkcie przyjrzymy się nieco dokładniej przykładom transformacji kom-
ponentów VCL na równoważne komponenty CLX. Na początek zajmiemy się popular-
nym  „spinerem”  —  to  pomocniczy  komponent  współpracujący  najczęściej  z  polem
edycyjnym, dokonujący jego automatycznej inkrementacji lub dekrementacji; realizuje
on  wiele  interesujących  mechanizmów  (jak  specyficzne  rysowanie),  współpracę  z  kla-
wiaturą i myszą, przyjmowanie i utratę skupienia (focus) itp.

Trzy kolejne komponenty to pochodne bazowego spinera. Pierwszy z nich wzbogacony
jest o obsługę myszy i wyświetlanie specyficznych kursorów już na etapie projektowa-
nia, drugi realizuje współpracę z listą obrazków (

3% 

), trzeci natomiast współpra-

cuje z kontrolką reprezentującą pole bazy danych.

Wszystkie prezentowane w tym rozdziale moduły nadają się do wykorzystania zarówno
w Delphi 6, jak i w Kyliksie.

       

Rysunek  13.3  przedstawia  trzy  egzemplarze  komponentu 

 %!! 

  na  formularzu

aplikacji CLX. W odróżnieniu od pionowo ułożonych strzałek, charakterystycznych dla
windowsowego spinera, komponent ten posiada odpowiednie przyciski w układzie po-
ziomym: inkrementujący i dekrementujący.


Komponent
TddgSpinner
pomocny przy
wprowadzaniu
liczb całkowitych

Wydruk 13.1 przedstawia kompletny kod źródłowy modułu 

%!

 implementu-

jącego komponent 

 %!! 

. Podobnie jak spiner windowsowy, wywodzi się on

z klasy 

  ! 

 — tyle że w tym przypadku jest to klasa CLX i komponent mo-

że być używany zarówno w Windows, jak i pod Linuksem.

background image

  

K

!  "#  

&

Choć  migracja  na  platformę  CLX  rzadko  wiąże  się  ze  zmianą  nazw  komponentów,  to
jednak zasadą jest poprzedzanie nazwy modułu VCL literą 



 dla podkreślenia zależno-

ści tegoż modułu od biblioteki 



.

Każdy z prezentowanych wydruków zawiera „wykomentowane” linie stanowiące część
kodu VCL; komentarze oznaczone dodatkowo jako 

/45/  podkreślają elementy

specyficzne dla przenoszenia komponentu z VCL do CLX.

  QddgSpin.Pas — kod 'ródłowy komponentu TddgSpinner





           

  !" # "    !"    ! $%

& '#       !"    #

 ()*      +,     

          !""-# $"      

  ". "     '"+!

 -/01123* 

4

  5

 ."

 

6    7- "5

&8

9  :  6  7- " ;

< 5

8(



=  &: >(5

 ?@ "  &  AB "5 C A<   5

@D -  A=  (. "5

 "& (

 @

EE> 

;C A<   5

;< "  A<   5

;= A5

;= 9 -A<   5

;: = F A=  5

;>= F A=  5

EE9G  "   "-

;B -  A  .?@ 5

;B -  A ?@ 5

&8

EEC,HA #   "  !+  

EEB 9  

"  9:7 F &@:A9:7 F (5

background image

'

 

K

     

   I7 F 5

EEB  

"  :?  -  &@:A:  (5

  "I?  -  5

8(

 " 

"  > 5@   5

"  F = &= A=  5F A=  5

= A3 "(5@ 5

EE: 

"  F "C &D A<   (5@ 5

"  < "C &D A<   (5@ 5

. "  >   A> 5

. "  : B@ = &= A=  (A=  5

EEC,HA?  -  +  + " !

EE"I?  -  

EE

"  ?  -  5@   5

EE     J

"  -  5  "5

. "   -  & C A<   (A=  5  "5

EE  .      J

"  F?  5@   5

"  F?K 5@   5

"  * F &@* A95- .A- . (5@   5

"  : F &= A: = 5- .A- . 5

LA<   (5@   5

"  : 6&= A: = 5- .A- . 5

LA<   (5@   5

&8

EEC,HA #  "    

. "  F: 9- F &- .A- . 5

: >A> (A=  5@   5

. "  F: 9- 6&- .A- . 5

: >A> (A=  5@   5

8(

. "  F: 9- F &- .A- . 5

" : >A> (A=  5@   5

. "  F: 9- 6&- .A- . 5

" : >A> (A=  5@   5

EE: +  $" $"

"   = &C A(5@ 5

"   = 9 -&C A<   (5@ 5

"   C &C A<   (5@ 5

 "

background image

  

K

!  "#  

(

EE   @     

" "  &DB A (5@   5

 - 

EE   "  $" $"

 = A

 ;= 

    = 

 ."= ;" 5

 = 9 -A<   

 ;= 9 -

    = 9 -

 .2M5

 < "  A<   

 ;< "  

   ;< "  

 .25

 C A<   

 ;C

    C 5

EE   "  J

 B -  A  .?@ 

 ;B - 

   ;B -  5

 B -  A ?@ 

 ;B -  

   ;B -  5

EEB  "  $" $"   

 5

&8

 F5EEC,HA $" $% +  

8(

 F: 5

 ?  5

 ; 5

 N - .2M5

 N   K5

 N 5

 > - N 5

 >: 5

 - N 5

 B 5

  . 5

 C   5

 9 - .M15

 B  "5

 B FF5

 B FB@ 5

 B ? F5

 B ?  5

 B ?K 5

background image

%)

 

K

     

 B * F 5

 B * > 5

 B * 65

 B : F 5

 B : :@ 5

 B : 65

 B F5

 5

   

4

:   4

4

" " )  &DB A (5

 

 -     &DB (5

EE< " " '

;= A"= ;" 5

;= 9 -A2M5

;C A15

;< "  A25

;: = F A; 5

;>= F A; 5

EE< " "   " "- $" $"

9 -AM15

N -A2M5

A 5

EEC,HA9     '  " 

A"9  5

EEC,HA< * +  +  

EE I7 F

< * A< * OP D Q5

5

: +  $" $" 4

"   ) = &C A(5

 

 .;= RHC -

 

;= AC 5

< @  5

 5

5

"   ) = 9 -&C A<   (5

 

 .;= 9 -RHC -

 

;= 9 -AC 5

< @  5

background image

  

K

!  "#  

%

 5

5

"   ) C &C A<   (5

 

 .;C RHC -

 

 . -  &C (-

 

;C AC 5

< @  5

EE9   - 

-  5

 5

 5

5

:  !  $  4

"   )> 5

@

3A3 "5

LB.. A<   5

A 5

B.. A<   5EEC,HA 

 

 -   > 5

 - @

 

; A .); 5

> )A"= - 5

 .?  -

=-)A .)

 

 

=-)A"= ;" 5

; )A"= - 5

 5

EE9$  $%

&8

EEC,HA  KD   +  

  KD  &N  I  I(5EE. " 7F<

8(

3A3 "&;= 9 -,21

9 -,;= 9 -O2N -(5

 @)3 "  &3) .3)3)3 -3)=(5

< . 3 "&3,2,2(5

A< &;C (5

LB.. A3)O&3)=,3),

 @) KN -&(( @05

EEC,HAB ".. & + . "   KD  (

B.. A3) .O&3)3 -,3) .,

background image

%

 

K

     

 @) K9 -&(( @05

&8

EEC,HAS J    K3 "& + . "   KD  (

 K3 "&39 - @0LB.. (5

8(

 K3 "&3B.. LB.. (5

F = &: ;: = F 

3 "&11;= 9 -N -((5

F = &>;>= F 

3 "&9 -,;= 9 -19 -N -((5

 .;" -

 

=-)A .)5

F ;"3 "&3(5

 5

 5

5 )> 4

"   )F = &= A=  5

F  A=  5= A3 "(5

 

 - @

 

 .F - EE 

=-)A"= - 

 

=-)A;= 5

> )A"= - 5

3 "  &= ) .= )

= )3 -= )=(5

 .?  -

 

&8

EE "D" @       "D" @ N - -  K

> )A"D" @   5

=-)A"D" @   5

8(

> )A"D" @ = 5

=-)A"D" @ = 5

 

 

 

> )A"= - 5

=-)A"= - 5

 5

 .= : - EE $ "     !"

 

3 "  &TN - @0,2

;= 9 -,TN - @0O2(5

 

  EE $ "     !"

 

background image

  

K

!  "#  

%

3 "  &9 -,;= 9 -OTN - @0,2

9 -,TN - @0O2(5

3 "  &9 -,;= 9 - @0,2

&N - @0(,&;= 9 - @0,T(

9 -,;= 9 - @0O2

&N - @0(O&;= 9 - @0,T((5

 5

> )A"9   K5

=-)A"9  5

 5

5 )F = 4

"   )F?  5

 

 -   F?  5

EE    , $   !  

EE%   !"!+

3  5

5

"   )F?K 5

 

 -   F?K 5

EE "  , $  !  

EE !%+   !"!

3  5

5

EEC,HA?  -  +  +

EE "I?  -  

"   )?  -  5

 

 -   5

EE$ #     

3  5

5

:   J4



 ) - 

   B -  5 '% + #  

. " ! " !  C)9$%   

3   $       .  

 # )

4

. "   ) -  & C A<   (A=  5

@

D -  A=  5

 

D -  A 5

 .D  &;B -  (-

;B -  & . C D -  (5

3 AD -  5

background image

%$

 

K

     

5

"   )-  5

 

 .D  &;B -  (-

;B -  & .(5

5

EE '% + # #  .  ! $" $%C 

EE $ $   ;C

"   )F "C &D A<   (5

 

C AC ,D 5

5

"   )< "C &D A<   (5

 

C AC OD 5

5

:  '" !4

&8

EEC,HA> #! ++    $" 

EE< * &   (

"   )9:7 F &@:A9:7 F (5

 

 -   5

:)3 A"I9 D 5EE    %

EE   

5

8(

"   )* F &@* A95- .A- . (5

 

 -   * F &* - .(5

EEC,HA    . '  

EE  U@IU  + U* IU

" * .

* I .* IF A

F "C &;< "  (5

* I6* I3 -A

< "C &;< "  (5

 5

5

  4

. "   )>   A> 5

 

7 >&3 (5

3 A"  &3 (5

5

background image

  

K

!  "#  

%

. "   ): B@ = &= A=  (A=  5

@

3A3 "5

 

EE  "   " 

 .= : -

3A3 "&11;= 9 -N -(

 

3A3 "&9 -,;= 9 -19 -N -(5

EE"    +   "  V

3 A>< 3 "&3>   (5

5

"   ): F &= A: = 5

- .A- . 5LA<   (5

 

 -   : F &= - .L(5

 . &"F      (-

 ;"5EE $   

EE "    

 .&=  .( 

&: B@ = &: (: B@ = &>((-

 

;: = F A: B@ = &: (5

;>= F A: B@ = &>(5

3  5

 5

5

"   ): 6&= A: = 5

- .A- . 5LA<   (5

 

 -   : 6&= - .L(5
 .=  .-

 

 .: B@ = &>(-

< "C &;< "  (

   .: B@ = &: (-

F "C &;< "  (5

;: = F A; 5

;>= F A; 5

3  5

 5

5

. "   )F: 9- F &- .A- . 5

" : >A> (A=  5

 

 -   F: 9- F &- .: >(5

F "C &;< "  (5

3 A 5

5

background image

%%

 

K

     

. "   )F: 9- 6&- .A- . 5

" : >A> (A=  5

 

 -   F: 9- 6&- .: >(5

< "C &;< "  (5

3 A 5

5

)

Jak widać, kod źródłowy modułu niewiele różni się od wersji w VCL. Mimo iż różnic jest
niewiele, większość z nich jest jednak niezwykle istotna.

Po pierwsze, zwróć uwagę na nazewnictwo modułów: 



! 

 i 

('

; poja-

wił się też nowy moduł 

  

 wspólny dla VCL i CLX.

Po  drugie,  mimo  iż  deklaracja  klasy  komponentu  niewiele  odbiega  w  swej  postaci  od
wersji VCL — pod względem deklaracji pól i procedur zdarzeniowych — nie ma w niej
metod  obsługujących  komunikaty,  (

01 %

  i 

'1! (!% 

).  Kontrolka

 ! 

 (w CLX) zamiast wysyłać komunikat 

'1! (!% 

 przy zmianie jej wła-

ściwości 

! 

, wywołuje po prostu (dynamiczną) metodę 

! (!% -.

 — toteż

do niej przeniesiona została treść wyeliminowanej metody komunikacyjnej.

Podczas  tworzenia  komponentu  częstym  problemem  jest  obsługa  klawiszy  strzałek  (na
klawiaturze);  w  przypadku  komponentu 

 %!! 

  powodują  one  zmianę  reprezento-

wanej przez komponent wartości. W bibliotece VCL informacja o zestawie klawiszy ob-
sługiwanych przez kontrolkę przekazywana była za pomocą komunikatu 

01 %

;

w CLX nie ma komunikatów i trzeba znaleźć równoważne rozwiązanie zastępcze. Tak
się  szczęśliwie  składa,  iż  kontrolka 

 $% ! 

  definiuje  w  tym  celu  właściwość

3! + 

, której w konstruktorze przypisuje się stosowną wartość (i poszerza domyśl-

ny repertuar obsługiwanych klawiszy o klawisze strzałek).

Wynika stąd praktyczny wniosek, iż komponenty VCL używające raczej procedur zda-
rzeniowych (i metod zarządzających zdarzeniami) niż komunikatów łatwiej poddają się
przenoszeniu na platformę CLX.

Po trzecie — w konstruktorze, oprócz ustawienia właściwości 

3! + 

, dokonywana

jest korekta standardowego ustawienia koloru kontrolki. W VCL kontrolka 

 $!! 

dziedziczy  swój  kolor  od  kontrolki  macierzystej  (co  symbolizuje  wartość 

'$!0

),

tymczasem w CLX konstruktor klasy 

 $% ! 

 ustawia kolor kontrolki na 

'!

;

konieczna jest więc zmiana tego koloru na 

'$!0

.

Na  początku  niniejszego  rozdziału  stwierdziliśmy,  iż  umiejętności  nabyte  w  trakcie
projektowania komponentów VCL przydadzą się w dużym stopniu przy projektowaniu
komponentów  CLX.  Istotnie  —  deklaracje  właściwości,  metody  dostępowe,  a  nawet
procedury zdarzeniowe nie różnią się zasadniczo od tych używanych przez komponenty
VCL.  Pewnym  wyjątkiem  w  tym  względzie  jest  metoda 

,! -.

,  wymagająca  nieco

więcej przeróbek.

background image

  

K

!  "#  

%&

Pierwszą przyczyną tego stanu rzeczy jest nieobecność w CLX funkcji 

  6%!-.

,

która w wersji VCL dokonywała wyśrodkowania wyświetlanego tekstu. Funkcja ta wymaga
kontekstu urządzenia  GDI,  dostępnego  w  VCL  pod  właściwością 

!&"!

  i  nie-

obecnego w CLX, gdzie wspomniana właściwość ma całkiem inne znaczenie — wskazuje
na obiekt odpowiedzialny za wyświetlanie (painter). Odpowiednie położenie tekstu moż-
na jednak wyliczyć „ręcznie”, za pomocą dostępnych „geometrycznych” metod płótna.

Kolejna ingerencja związana jest z kolorem, w którym (domyślnie) zostałyby wyświe-
tlone przyciski. Na obydwu platformach jest to kolor 

'6' &  !

, jednak w CLX

wartość ta utożsamiana jest z 

'6' & "%(%(  

 (w module 

('

).

Wszelkie operacje wykonywane na płótnie komponentu CLX poza jego metodą
,! -. muszą być poprzedzone wywołaniem metody !&  -.; po
zako1czeniu rysowania należy wywołać metodę 

!& -..

Ostatnim z nieprzenośnych elementów VCL, przysparzającym czasem mnóstwa kłopo-
tów, są kody wirtualnych klawiszy 

&*1

xxxx, stanowiące część Windows API. CLX defi-

niuje w ich miejsce całkowicie nowy zestaw stałych rozpoczynających się od przedrostka

+ 1

. W przypadku naszego komponentu nie jest to jednak dużym problemem, ze względu

na ubogi repertuar klawiszy (4) obsługiwanych w sposób specyficzny.

I tak oto uzyskaliśmy uniwersalny komponent, przydatny zarówno w Delphi 6, jak i w śro-
dowisku  Kyliksa.  Najbardziej  spektakularnym  aspektem  tej  uniwersalności  jest  możli-
wość użycia tego samego kodu źródłowego w obydwu środowiskach!

            

Jak  widać,  przenoszenie  komponentu  do  środowiska  CLX  nie  musi  być  wcale  trudne
(chociaż odkrycie właściwości 

3! + 

 wymagało nieco wysiłku). Kiedy jednak przy-

stąpimy do rozbudowy komponentu CLX, różnice pomiędzy VCL i CLX staną się bar-
dzo wyraźne.

Wydruk 13.2 przedstawia kod źródłowy komponentu 

 % %!! 

, pochodnego

w stosunku do 

 %!! 

. Na rysunku 13.4 widać wyraźnie, jak kursor myszy zmie-

nia  swój  wygląd,  gdy  znajdzie  się  nad  jednym  z  przycisków;  rysunek  13.5  pokazuje
natomiast zmianę reprezentowanej wartości na etapie projektowania (poprzez kliknięcie
jednego z przycisków).

 
Zmiana wygl*du
kursora wywołana
przez komponent
TddgDesignSpiner

background image

%'

 

K

     

 
Edycja wła-ciwo-ci
komponentu
TddgDesignSpiner
na etapie
projektowania
aplikacji

  QddgDsnSpn.Pas — kod 'ródłowy komponentu TddgDesignSpiner



F 

      F      !" +

    !"   ! " 

     +   " ' ):#     

 $" $" C          +" " 

 -/01123* 

4

 F  5

 ."

 

6   5

&8

9  :  6  7- " ;

 5

8(



F    "& (

 @

EEC,HA"  N. 

;-AN5

&8

EEC,HAB'    " <F? 

EE!    "  # C)

EE> #  ". " C

;-AN5

EEB 9  

"  9: &@:A9: (5

   I 5

EEB  

"  :F   N  &@:A:F   N  (5

  "IF   N  5

background image

  

K

!  "#  

%(

8(

 " 

"  -  5@   5

EEC,HA> #  !  .    

"  : :@ &- .A- . 5

LA<   (5@   5

. "  F   ?@  &  AB "N5

?@ A?@ N(A=  5@   5

 "

" "  &DB A (5@   5

 "F 5@   5

 5

   

&8

EEC,HA  '  "-

W3FF  ) 4EE!"'  !"

8(

 

  ;5EEC,HA

EEC,HA . & .-     .

EE- (     "" 

EEC,HA> #   "     !  

EE

" 

= AP1))X08T,2Q.= &

W11WX1W11W11W11WTMW11W11

W11WTMW11W11W11WTMW11W11

W11WTMW11W11W11WT?W11W11

W11WTYW1W11W11WTYWX1W11

W11WTYW0MW11W1XWTYW0TW11

W1TW1W0TW11W1TWT1W1TW11

W10WT1W1TW11W10W11W1TW11

W12W11W1TW11W12W11W1TW11

W11WM1W1MW11W11WT1W1MW11

W11WT1W1MW11W11W01W21W11

W11W01W21W11W11WZ;W;MW11

W11WZ;W;MW11W11WZ;W?MW11

W11WZ;W;MW11W11W11W11W11

W11W11W11W11W11W11W11W11

W11W11W11W11W11W11W11W11

W11W11W11W11W11W11W11W11(5

:AP1))X08T,2Q.= &

W11WX1W11W11W11WZMW11W11

W11WZMW11W11W11WZMW11W11

W11WZMW11W11W11WZ?W11W11

W11WZ;W1W11W11WZ;W;1W11

W11WZ;W;MW11W1XWZ;W;W11

W1ZW;;W;W11W1ZW;;W;W11

W1XW;;W;W11W1XW;;W;W11

W12W;;W;W11W12W;;W;W11

background image

&)

 

K

     

W11W;;W;MW11W11WZ;W;MW11

W11WZ;W;MW11W11WX;W;1W11

W11WX;W;1W11W11WZ;W;MW11

W11WZ;W;MW11W11WZ;W?MW11

W11WZ;W;MW11W11W11W11W11

W11W11W11W11W11W11W11W11

W11W11W11W11W11W11W11W11

W11W11W11W11W11W11W11W11(5

4

: F    4

4

" "F    )  &DB A (5

@

= = A= N5

:= A= N5

 

 -     &DB (5

&8

EEC,HA9   

;-A&N<  " [FF > I= 63B3[(5

8(

EEC,HA     "

= = A= I"  &X0X0\= ; (5

:= A= I"  &X0X0\:; (5



;-AI"  &= = := M1(5

. 

= I &= = (5

= I &:= (5

 5

5

 "F    )F 5

 

&8

C,HAIF  F 

F &;-(5EE   7F<

8(

IF &;-(5

 -   F 5

5

EE    +   " '  J  !

&8

EEC,HA   ' 

"  F    )9: &@:A9: (5

 

 .: B@ = &: (: B@ = &>(-

 &;-(

 

 -   5

5

8(

background image

  

K

!  "#  

&

EEC,HA>  .    : :@  "    

"  F    ): :@ &- .A- . 5

LA<   (5

 

 .: B@ = &: (: B@ = &>(-

9  I &N  ;-(

 

9  I6  &N  (5

 -   5

5

&8

EEC,HA9  ' )6#     

EEF   ?@  )

"  F    ):F   N  &@:A

:F   N  (5

 

EEB !"      + $" $"

EEC       "! " )

EE7    +   " ' 

EE $" !  ! + 2,   F -

EE " +  % + J

EE ! "-!

 .: B@ = &: (: B@ = &>(-

:)3 A2

 

:)3 A15

5

8(

. "  F    )F   ?@  &  AB "N5

?@ A?@ N(A=  5

@

: >A> 5

 

3 A; 5

 .&  N  ( 

&?@ I &?@ ( P?@  I: = > 

?@  I: = 3   

?@  I: = F "Q(-

 

EE  A #!""    

EE       ! "%)

: >A> &: ?@ IK&: ?@ N&?@ ((

: ?@ I&: ?@ N&?@ (((5

 .: B@ = &: (: B@ = &>(-

3 A

 

3 A; 5

 5

5

background image

&

 

K

     

"  F    )-  5

@

;A;5

 

 -   -  5

EE6  $  !     '  $%

EE $" $" C

 ."F      -

 

;A7 > ;& .(5

&8

EEC,HA;)F   !   F   N

 .&;RH ( &;)F   RH (-

;)F   ): . 5

8(

 .&;RH ( &;)F   NRH (-

;)F   N): . 5

 5

5

)

Po  przeanalizowaniu  komentarzy  ponownie  można  zauważyć  wyeliminowanie  kodu
związanego z systemem komunikatów Windows. Dla kontrolki Windows sygnałem do
zmiany wyglądu kursora jest otrzymanie przez nią komunikatu 

01 

, w odpowie-

dzi  na  co  powinna  wywołać  funkcję 

 -.

  z  odpowiednim  parametrem.  W  CLX

nie ma komunikatów, trzeba zatem kontrolować położenie kursora za pomocą zdarzenia

)!2 2&

; gdy kursor znajdzie się nad jednym z przycisków, należy nadać kursorowi

żądany  wygląd  za  pomocą  funkcji 

$% 1 -.

,  w  przeciwnym  razie  —  za-

pewnić jego kształt domyślny przez wywołanie funkcji 

$% 1! -.

.

Osobnym  problemem  jest  samo  określenie  kształtu  kursora.  W  Windows  robi  się  to
bardzo  prosto,  na  przykład  przez  wczytanie  odpowiedniego  zasobu  za  pomocą  funkcji

-.

. W bibliotece 



 przeciążona funkcja 

1'  -.

 udostępnia różno-

rodne sposoby tworzenia kursorów, nie przewidując jednak wykorzystania w tym celu
zasobów.  Rozwiązaniem  zastępczym  (które  wykorzystaliśmy  w  naszym  przykładzie)
jest wówczas zdefiniowanie dwóch bitmap, z których pierwsza określa rozmieszczenie
czarnych i białych pikseli w obrazie kursora, druga natomiast stanowi maskę określają-
cą jego przezroczyste regiony.

Kolejne zadanie polega na spowodowaniu przejęcia przez komponent (niektórych) zda-
rzeń  myszy  na  etapie  projektowania.  Komponent  VCL  sygnalizuje  gotowość  do  takiej
obsługi,  zwracając  wartość 

7

  w  odpowiedzi  na  komunikat 

'1 %!" 

.  W  CLX

analogiczne  zadanie  spełnia  dynamiczna  metoda 

%!& !  -.

,  zwracająca  wy-

nik typu Boolean; komponent powinien ją przedefiniować stosownie do swej specyfiki.

I ostatni problem — skoro komponent 

 % %!! 

 posiada zdolność modyfikowa-

nia swej właściwości 



, modyfikacja ta nie może odbywać się bez wiedzy inspektora

obiektów.  W  VCL  mechanizmem  zapewniającym  aplikacji  łączność  z  projektantem

background image

  

K

!  "#  

&

formularzy jest interfejs ukrywający się pod właściwością 

%! 

 formularza będące-

go właścicielem komponentu; w CLX analogiczna właściwość nosi nazwę 

%! "

*

. Aby zasygnalizować zmianę zawartości komponentu, należy wywołać metodę 

2

8 

 wspomnianego interfejsu, w ramach obsługi zdarzenia 

)!(!%

 — robi się to tak

samo w VCL i CLX.

            

Kolejne rozszerzenie naszego komponentu (który nosi teraz nazwę 

 %3% !! 

)

polega na wyposażeniu go w bitmapy określające wygląd obydwu przycisków. Bitmapy
te stanowią elementy listy typu 

3% 

 (patrz rysunek 13.6) i wyświetlane są zamiast

zwykłych znaków „+” i „–”.

 
Bitmapy nadaj*ce
wygl*d przyciskom
komponentu
TddgImgListSpinner

Kod  źródłowy  modułu  implementującego  komponent  jest  przedstawiony  na  wydruku
13.3;  w  porównaniu  z  wydrukiem  13.2  zmiany  wynikające  z  przejścia  na  platformę
CLX są znacznie mniejsze.

 QddgILSpin.pas — kod 'ródłowy komponentu TddgImgListSpinner



<

      <    !"

 +F    )9! " '  $   

   !"  $%    )

 -/01123* 

4

 < 5

 ."

 

   F  < 5

&8

9  :  6  7- " ;

 F  < 5

8(

background image

&$

 

K

     



<  "&F    (

 @

;< A<  5

;< <  K AP2))0Q.<   5

;< -   A-   5

EE9 + "   J

"  <  -  &  AB "(5

 " 

"    . "  &D A 5

B   AB   (5@   5

"  F = &= A=  5F A=  5

= A3 "(5@   5

"  "  B.. &= A3 "5@A<   (5

"  - ":   5

EE: +  $" $"

"   < &C A<  (5@ 5

. "  7 < <  K&><  KA<   (A<   5@ 5

"   < <  K&><  KA<   5

C A<   (5@ 5

 "

" "  &DB A (5@   5

 "F 5@   5

 - 

 < A<  

 ;< 

    < 5

 < <  K: A<   

  K2

 7 < <  K

    < <  K5

 < <  K>A<   

  K0

 7 < <  K

    < <  K5

 5

   

 

7- "5EEC,HA:

4

: <  4

4

" "<  )  &DB A (5

 

 -     &DB (5

;< -   A-   )  5

;< -   )B -  A<  -  5

background image

  

K

!  "#  

&

EE ##    $  +

EE -    #     %

EE"    

;< <  K P2QA,25

;< <  K P0QA,25

5

 "<  )F 5

 

;< -   ); 5

 -   F 5

5

"  <  )  . "  &D A 5

B   AB   (5

 

 -     . "  &D B   (5

 .&B   3 @ ( &D ;< (-

 < & (5EE    +

5

. "  <  )7 < <  K&><  KA

<   (A<   5

 

3 A;< <  K P><  KQ5

5

"  <  ) < <  K&><  KA<   5

C A<   (5

 

 .;< <  K P><  KQRHC -

 

;< <  K P><  KQAC 5

< @  5

 5

5

"  <  ) < &C A<  (5

 

 .;< RH -

;< )6 3   -  &;< -   (5

;< AC 5

 .;< RH -

 

;< )3   -  &;< -   (5

;< );  . "  & .(5

- ":   5

 5

< @  5

5

"  <  )<  -  &  AB "(5

 

 .  < -

 

background image

&%

 

K

     

- ":   5

EE9  6  < @   "

EE     

6 5

 5

5

"  <  )- ":   5

 

EE ! $%# " '  $" 

EE"! +

 .;< )9 -H= 9 --

= 9 -A;< )9 -5

 .;< )N -HN --

N -A;< )N -5

5

"  <  )F = &= A=  5

F A=  5

= A3 "(5

@

A<   5

 

 - @

 

=-)A= 5

> )A"= - 5

3 "  &= ) .= )

= )3 -= )=(5

 .= : - EE $   +" U U

 

 .&< RH ( &< <  K: RH,2(-

 

&8

EEC,HA <    #    

EE#     $" $" =)

 .F -

;< )F  A  " 

 

;< )F  A 5

8(

 .F -

;< )=A"= - 

 

;< )=A"= ;" 5

"  B.. &= (5

&8

EEC,HA<  )F    

;< )F & @< <  K: ?  (5

8(

;< )F & @< <  K:  < 

?  (5

 

 

background image

  

K

!  "#  

&&

 -   F = &= F = (5

 

  EE $  +" UU

 

 .&< RH ( &< <  K>RH,2(-

 

&8

EEC,HA <    #    

EE#     $" $" =)

 .F -

;< )F  A  " 

 

;< )F  A 5

8(

 .F -

;< )=A"= - 

 

;< )=A"= ;" 5

"  B.. &= (5

&8

EEC,HA<  )F    

;< )F & @< <  K>?  (5

8(

;< )F & @< <  K> < 

?  (5

 

 

 -   F = &= F = (5

 5

 5

5<  )F = 4

"  <  )"  B.. &= A3 "5

@A<   (5

 

 .;< RH -

 

A= ) .O&= )3 -,= ) .( @0,

&;< )9 - @0(5

A= )O&= )=,= )( @0,

&;< )N - @0(5

 5

5

)

Lista obrazków 

 3% 

, w VCL stanowiąca otoczkę standardowej kontrolki imple-

mentowanej w bibliotece 

  

, w CLX zaimplementowana została w zupełnie

inny  sposób,  za  pomocą  tzw.  prymitywów  graficznych  biblioteki 



.  Tę  nową  imple-

mentację  zawiera  moduł 

3%

,  który  tym  samym  zastąpił  na  liście 

 

  moduł

3%

. Nie zmienił się jednak zasadniczo sposób korzystania z listy, ani też nazwa jej

klasy,  czego  wymierną  korzyścią  jest  niezmieniona  deklaracja  klasy  komponentu
(w stosunku  do  jego  wersji  VCL).  Identyczne  są  też  metody  komponentu  w  obydwu
wersjach, z jednym wszakże wyjątkiem.

background image

&'

 

K

     

Wyjątkiem tym jest metoda 

0  !-.

, różnica w stosunku do VCL wynika z faktu,

iż w CLX lista 

 3% 

 nie operuje pojęciem stanu przycisku (zwolniony, naciśnięty,

itp.)  reprezentowanego  w  VCL  przez  właściwość 

0!% 

,  stan  ten  należy  więc

rozróżniać  samodzielnie  poprzez  zmianę  koloru  tła,  który  reprezentowany  jest  przez
właściwość 

*

.  Ponadto  metoda 

 3%   0-.

  ma  w  CLX  nieco  inne  para-

metry niż w VCL, inne jest więc jej wywołanie.

    !     "  

Skoro  nadaliśmy  estetyczny  wygląd  przyciskom  komponentu,  warto  teraz  poekspery-
mentować z przechowywaną przez niego wartością, a raczej — z jej źródłem. Kolejny
komponent  pochodny  — 

 % !! 

  —  czerpie  tę  wartość  z  pola  zbioru  danych,

które reprezentowane jest przez jego właściwości 

 '

 i 

 # 

. Rysunek 13.7

przedstawia komponent 

 % !! 

 skojarzony z polem 

 ! 

 zbioru 

& ! 

.

 
Komponent
TddgDBSpinner
u/ywany do edycji
pola bazy danych

Kod  źródłowy  modułu  implementującego  komponent  został  przedstawiony  na  wy-
druku 13.4.

   QddgDBSpin.Pas — kod 'ródłowy komponentu TddgDBSpinner



F=

      F= )<

 '   <   

 "-)

 -/01123* 

4

 F= 5

 ."

 

6  < F=F=5

&8

9  :  6  7- " ;

< F=F=5

8(



background image

  

K

!  "#  

&(

F= "&<  (

 @

;F A; F 5EE + "-

EE + "  

"  F-  &  AB "(5

"  6 F&  AB "(5

"  D" @ -  &  AB "(5

&8

EEC,HA   ' 

"  :?K &@:A:?K (5  "I?K 5

"  :F   N  &@:A:F   N  (5

  "IF   N  5

8(

 " 

"    . "  &D A 5

B   AB   (5@   5

"  - ";  &" C A (5@ 5

EE  .    ! !"  

"  -  5@   5

"  * > &@* A-(5@   5

EEC,HAF?K  :?K 

"  F?K 5@   5

EEC,HAF   ?@   :F   N  

. "  F   ?@  &  AB "N5

?@ A?@ N(A=  5@   5

EE  .    .  !"  $" $%C

"  F "C &D A<   (5@   5

"  < "C &D A<   (5@   5

EE +  $" $"

. "  7 ; A; 5@ 5

. "  7 F; A 5@ 5

"   F; &" C A (5@ 5

. "  7 F" AF" 5@ 5

"   F" &C AF" (5@ 5

. "  7 3 B A=  5@ 5

"   3 B &C A=  (5@ 5

EE+ !"  "-

 ; A; 

 7 ; 5

 F A; F 

 ;F 5

 "

" "  &DB A (5@   5

 "F 5@   5

 - 

 F; A 

 7 F; 

    F; 5

 F" AF"

background image

')

 

K

     

 7 F"

    F" 5

EE   + $" !!"  

 3 B A= 

 7 3 B 

    3 B 

 .; 5

 5



?< @ ;  "&?K"   (5

 "  

< @ ;  [    "-  %[O

[<    9;[5

   

 

 5EEC,HA:

4

: F= 4

4

" "F= )  &DB A (5

 

 -     &DB (5

;F A; F )  5

EE . !"  "- #   !

EE  !  "-

;F ) A .5

EE! "   5#   $  

EE+!"   #   % 

;F )B F-  AF-  5

;F )B 6 FA6 F5

;F )B D" @ -  AD" @ -  5

5

 "F= )F 5

 

;F ); 5

;F A 5

 -   F 5

5

"  F= )  . "  &D A 5

B   AB   (5

background image

  

K

!  "#  

'

 

 -     . "  &D B   (5

 .&B   3 @ ( 

&;F RH ( 

&D ;F )F" (-

 

F" A 5EE$      F"

 5

5

. "  F= )7 ; A; 5

 

3 A;F ); 5

5

. "  F= )7 F; A 5

 

3 A;F );   5

5

"  F= ) F; &" C A (5

 

- ";  &C (5

;F );   AC 5

5

. "  F= )7 F" AF" 5

 

3 A;F )F" 5

5

"  F= ) F" &C AF" (5

 

 .;F )F" RHC -

 

;F )F" AC 5

EE9  ;  . "    "  # 

EE    !" ' "-#    % +  .

EE  "-

 .C RH -

C );  . "  & .(5

 5

5

. "  F= )7 3 B A=  5

 

3 A;F )3 B 5

5

"  F= ) 3 B &C A=  (5

 

;F )3 B AC 5

5

background image

'

 

K

     

"  F= )- ";  &" C A (5

@

;  A;  5

 

EE G"    "- 

EE.<   .< .9.;, #   

EE     ! 

 .&C RH[[( 

&;F RH ( 

&;F )F RH ( 

&;F )F )D" @ (-

 

;  A;F )F ); =  &C ()F 5

 .&;  RH.<   ( 

&;  RH.< ( 

&;  RH.9( 

&;  RH.;(-

 

  ?< @ ;  )  &< @ ;  (5

 5

 5

5

"  F= )-  5

 

EE . !" #   +

 .;F RH -

;F ): . 5

 -   -  5EE7   B - 

5

"  F= )* > &@* A-(5

 

 -   * > &* (5

 .* ]0Z- EE" " $ +?V

 

;F )3  5EE   " $ +" 

* A]15EE  ! J"  "

 5

5

"  F= )F "C &D A<   (5

 

 .3 B  ;F ) : .-

 

EE #    "- 

&8

EEC,HA:  =  9  D><. " 

:  = &1(

8(

= 5

 

 

 

background image

  

K

!  "#  

'

EE  ' "-  "  .   $%

 .;F )? -

 -   F "C &D (5

 5

5

"  F= )< "C &D A<   (5

 

 .3 B  ;F ) : .-

 

EE #    "- 

&8

EEC,HA:  =  9  D><. " 

:  = &1(

8(

= 5

 

 

 

EE  ' "-  "  .   $%

 .;F )? -

 -   < "C &D (5

 5

5



F= )F- 

  # %    "- ' A

2)S  + $%   !

0)   ' "- !"    "

X)S  + $%    "-

T)S  + #!"     "-

^)3            " 

_)9$" $%F;      

4

"  F= )F-  &  AB "(5

 

 .;F ); RH -

C A;F ); )D<   5

5



F= )6 F

        "  $%  

  $%    ! "- " )9   

       % $%)

4

"  F= )6 F&  AB "(5

 

background image

'$

 

K

     

;F ); )D<   AC 5

5



F= )D" @ - 

         "    

  "- )  +  $" $%D" @ )

    "   "-# "% $" $"

;F )D" @

4

"  F= )D" @ -  &  AB "(5

 

EE    "- G  

 .&;F RH ( ;F )D" @ -

- ";  &F; (5

5

&8

EEC,HAF?K  :?K 

"  F= ):?K &@:A:?K (5

 

EE>'   " 

;F )6 3 "5

 K" 

 ;"5EE  ' + 

EE "  +  

  5EE '   ! 

 5

 -   5

5

8(

"  F= )F?K 5

 

EE>'   " 

;F )6 3 "5

 K" 

 ;"5EE  ' + 

EE "  +  

  5EE '   ! 

 5

 -   5

5

&8

EEC,HAF   ?@   :F   N  

background image

  

K

!  "#  

'

"  F= ):F   N  &@:A:F   N  (5

 

EE   # %# $% "  $"

EE      # ! + " $" !

EE      "-  "

:)3 A15

5

8(

. "  F= )F   ?@  &  AB "N5

?@ A?@ N(A=  5

 

EE   # %# $% "  $"

EE      # ! + " $" !

EE      "-  "

3 A; 5

5

)