Wydawnictwo Helion
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
IDZ DO
IDZ DO
KATALOG KSI¥¯EK
KATALOG KSI¥¯EK
TWÓJ KOSZYK
TWÓJ KOSZYK
CENNIK I INFORMACJE
CENNIK I INFORMACJE
CZYTELNIA
CZYTELNIA
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
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.
!
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
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
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
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
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
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
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
!
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
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
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.
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.
$
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,
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
%
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.
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 CA< 5
@D - A= (. "5
"& (
@
EE>
;CA< 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:7F&@:A9:7F(5
'
K
I7F5
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
. " - & CA< (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:+ $" $"
"= &CA(5@ 5
"= 9 -&CA< (5@ 5
"C&CA< (5@ 5
"
K
! "#
(
EE @
" "&DB A (5@ 5
-
EE " $" $"
= A
;=
=
."= ;"5
= 9 -A<
;= 9 -
= 9 -
.2M5
< " A<
;< "
;< "
.25
CA<
;C
C5
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
B5
.5
C 5
9 -.M15
B "5
B FF5
B FB@5
B ? F5
B ? 5
B ?K 5
%)
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
;CA15
;< " A25
;: = F A;5
;>= F A;5
EE< " " " "- $" $"
9 -AM15
N -A2M5
A5
EEC,HA9 ' "
A"9 5
EEC,HA< *+ +
EE I7F
< *A< *OP D Q5
5
:+ $" $" 4
" )= &CA(5
.;= RHC-
;= AC5
< @ 5
5
5
" )= 9 -&CA< (5
.;= 9 -RHC-
;= 9 -AC5
< @ 5
K
! "#
%
5
5
" )C&CA< (5
.;CRHC-
. - &C(-
;CAC5
< @ 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,HAKD +
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).,
%
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 $ " !"
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
. " ) - & CA< (A= 5
@
D - A= 5
D - A5
.D &;B - (-
;B - &. CD - (5
3AD - 5
%$
K
5
" )- 5
.D &;B - (-
;B - &.(5
5
EE '% + # #. ! $" $%C
EE $$ ;C
" )F"C&D A< (5
CAC,D 5
5
" )< "C&D A< (5
CACOD 5
5
: '" !4
&8
EEC,HA> #!++ $"
EE< *& (
" )9:7F&@:A9:7F(5
- 5
:)3A"I9 D 5EE %
EE
5
8(
" )*F &@*A95- .A- .(5
- *F &*- .(5
EEC,HA . '
EEU@IU + U*IU
"*.
*I.*IF A
F"C&;< " (5
*I6*I3 -A
< "C&;< " (5
5
5
4
. " )> A> 5
7>&3(5
3A" &3(5
5
K
! "#
%
. " ):B@= &= A= (A= 5
@
3A3"5
EE " "
.= : -
3A3"&11;= 9 -N -(
3A3"&9 -,;= 9 -19 -N -(5
EE" + " V
3A>< 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
3A5
5
%%
K
. " )F:9-6&- .A- .5
" :>A> (A= 5
- F:9-6&- .:>(5
< "C&;< " (5
3A5
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.
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
%'
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
I5
EEB
":F N &@:A:F N (5
"IF N 5
K
! "#
%(
8(
"
"- 5@ 5
EEC,HA> #!.
"::@&- .A- .5
LA< (5@ 5
. " F ?@ & AB "N5
?@ A?@ N(A= 5@ 5
"
" "&DB A (5@ 5
"F5@ 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
&)
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 )F5
&8
C,HAIF F
F&;-(5EE 7F<
8(
IF&;-(5
- F5
5
EE + " ' J !
&8
EEC,HA '
"F )9:&@:A9:(5
.:B@= &: (:B@= &>(-
&;-(
- 5
5
8(
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@= &>(-
:)3A2
:)3A15
5
8(
. " F )F ?@ & AB "N5
?@ A?@ N(A= 5
@
:>A> 5
3A;5
.& N (
&?@ I&?@ ( P?@ I:= >
?@ I:= 3
?@ I:= F "Q(-
EEA #!""
EE ! "%)
:>A> &:?@ IK&:?@ N&?@ ((
:?@ I&:?@ N&?@ (((5
.:B@= &: (:B@= &>(-
3A
3A;5
5
5
&
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
)!22&
; 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
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(
&$
K
< "&F (
@
;<A< 5
;<< KAP2))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:+ $" $"
"<&CA< (5@ 5
. " 7<< K&>< KA< (A< 5@ 5
"<< K&>< KA< 5
CA< (5@ 5
"
" "&DB A (5@ 5
"F5@ 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
K
! "#
&
EE ## $ +
EE - # %
EE"
;<< KP2QA,25
;<< KP0QA,25
5
"< )F5
;<- );5
- F5
5
"< ) . " &D A 5
B AB (5
- . " &D B (5
.&B 3@( &D ;<(-
<& (5EE +
5
. " < )7<< K&>< KA
< (A< 5
3A;<< KP>< KQ5
5
"< )<< K&>< KA< 5
CA< (5
.;<< KP>< KQRHC-
;<< KP>< KQAC5
< @ 5
5
5
"< )<&CA< (5
.;<RH -
;<)6 3 - &;<- (5
;<AC5
.;<RH -
;<)3 - &;<- (5
;<); . " &.(5
-": 5
5
< @ 5
5
"< )< - & AB "(5
. <-
&%
K
-": 5
EE9 6 < @ "
EE
65
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 A5
8(
.F -
;<)=A"= -
;<)=A"= ;"5
" B..&= (5
&8
EEC,HA< )F
;<)F & @<< K: ? (5
8(
;<)F & @<< K: <
? (5
K
! "#
&&
- F = &= F = (5
EE $ +" UU
.&<RH ( &<< K>RH,2(-
&8
EEC,HA < #
EE# $" $" =)
.F -
;<)F A"
;<)F A5
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.
&'
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(
K
! "#
&(
F= "&< (
@
;F A; F 5EE + "-
EE + "
"F- & AB "(5
"6F& 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
"-"; &" CA (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
. " 7F; A 5@ 5
"F; &" CA (5@ 5
. " 7F"AF"5@ 5
"F"&CAF"(5@ 5
. " 73B A= 5@ 5
"3B &CA= (5@ 5
EE+ !" "-
; A;
7; 5
F A; F
;F 5
"
" "&DB A (5@ 5
"F5@ 5
-
F; A
7F;
F; 5
F"AF"
')
K
7F"
F"5
EE + $" !!"
3B A=
73B
3B
.;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 6FA6F5
;F )B D" @- AD" @- 5
5
"F= )F5
;F );5
;F A 5
- F5
5
"F= ) . " &D A 5
B AB (5
K
! "#
'
- . " &D B (5
.&B 3@(
&;F RH (
&D ;F )F"(-
F"A 5EE$ F"
5
5
. " F= )7; A; 5
3A;F ); 5
5
. " F= )7F; A 5
3A;F ); 5
5
"F= )F; &" CA (5
-"; &C(5
;F ); AC5
5
. " F= )7F"AF"5
3A;F )F"5
5
"F= )F"&CAF"(5
.;F )F"RHC-
;F )F"AC5
EE9 ; . " " #
EE !" ' "-# % + .
EE "-
.CRH -
C); . " &.(5
5
5
. " F= )73B A= 5
3A;F )3B 5
5
"F= )3B &CA= (5
;F )3B AC5
5
'
K
"F= )-"; &" CA (5
@
; A; 5
EE G" "-
EE.< .< .9.;, #
EE !
.&CRH[[(
&;F RH (
&;F )FRH (
&;F )F)D" @(-
; A;F )F); =&C()F5
.&; 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 )35EE " $ +"
*A]15EE ! J" "
5
5
"F= )F"C&D A< (5
.3B ;F ) : .-
EE # "-
&8
EEC,HA:= 9 D><. "
:=&1(
8(
=5
K
! "#
'
EE ' "- " . $%
.;F )? -
- F"C&D (5
5
5
"F= )< "C&D A< (5
.3B ;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 -
CA;F ); )D< 5
5
F= )6F
" $%
$% ! "- " )9
% $%)
4
"F= )6F& AB "(5
'$
K
;F ); )D< AC5
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 )63"5
K"
;"5EE ' +
EE " +
5EE ' !
5
- 5
5
8(
"F= )F?K 5
EE>' "
;F )63"5
K"
;"5EE ' +
EE " +
5EE ' !
5
- 5
5
&8
EEC,HAF ?@ :F N
K
! "#
'
"F= ):F N &@:A:F N (5
EE # %# $%" $"
EE # ! + " $" !
EE "- "
:)3A15
5
8(
. " F= )F ?@ & AB "N5
?@ A?@ N(A= 5
EE # %# $%" $"
EE # ! + " $" !
EE "- "
3A;5
5
)