Delphi __ Kompendium __ Roz14.pdf

(899 KB) Pobierz
Delphi :: Kompendium :: Roz...
Delphi :: Kompendium :: Rozdział 14 - 4programmers.net http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_14
Logowanie | Rejestracja | Forum | Pomoc | Reklama | Szukaj
Strona główna :: Delphi :: Kompendium
Rozdział 14
Copyright © 2000-2006 by Coyote Group 0.9.3-pre3
Czas generowania strony: 0.9116 sek. (zapytań SQL:
12)
Edytuj Historia
Komponenty VCL i CLX
Zanim przejdziemy do właściwego procesu tworzenia komponentów, konieczne będzie dokładne zapoznanie się
z zasadami ich działania. Co prawda zarówno o klasach, jak i o VCL mówiłem już w rozdziale 3., lecz tamta
wiedza była konieczna do dalszego projektowania aplikacji w Delphi. Tym razem poznasz architekturę
komponentów VCL oraz CLX ze strony projektanta ? dowiesz się, jak to wszystko działa i jak jest ze sobą
połączone.
Spis treści
1 Czym jest komponent?
2 VCL
3 CLX
3.1 Tworzenie aplikacji opartych na CLX
3.2 CLX a VCL
3.3 Architektura CLX
4 Windows a Linux
4.1 Kompilacja warunkowa
5 Rodzaje komponentów
5.1 Komponenty wizualne
5.2 Komponenty niewizualne
5.3 Komponenty graficzne
6 Hierarchia komponentów
6.1 TObject
6.1.1 Metody klasy TObject
6.1.1.1 ClassName
6.1.1.2 ClassNameIs
6.1.1.3 ClassInfo
6.1.1.4 ClassParent
6.1.1.5 ClassType
6.1.1.6 FieldAddress
6.1.1.7 MethodAddress
6.2 TPersistent
6.2.1 Metoda Assign
6.2.2 Metoda AssignTo
6.2.3 Metoda DefineProperties
6.3 TComponent
6.3.1 Właściwości klasy TComponent
6.3.1.1 ComponentCount
6.3.1.2 ComponentIndex
6.3.1.3 Components
6.3.1.4 ComponentState
6.3.1.5 Name
6.3.1.6 Owner
6.3.2 Metody klasy TComponent
6.4 TControl
6.4.1 Właściwości klasy TControl
6.5 TWinControl i TWidgetControl
6.5.1 Właściwości klas TWinControl i TWidgetControl
6.5.2 Zdarzenia
6.6 Klasy TCustom
6.7 TGraphicControl
7 Budowa komponentu
7.1 Właściwości
7.1.1 Rodzaje właściwości
7.2 Zdarzenia
7.3 Metody
8 RTTI
8.1 Właściwości obiektu
8.2 Dokładniejsze informacje o obiekcie
9 Podsumowanie
W tym rozdziale:
dowiesz się, jak funkcjonuje klasa VCL;
dowiesz się, czym jest biblioteka CLX;
poznasz elementarne metody i właściwości podstawowych klas.
Czym jest komponent?
Delphi jako środowisko wizualne udostępnia różne kontrolki ? tzw. komponenty, służące do szybkiego
projektowania aplikacji. Komponenty są ?klockami?, którymi posługuje się programista w procesie budowania
aplikacji.
Patrząc na komponenty ze strony projektanta aplikacji, mamy do czynienia z wygodnymi i łatwymi w obsłudze
narzędziami. Nie interesuje nas, jak one działają i jaki kod znajduje się ?w środku?. Ważne są zdarzenia,
metody, właściwości i zadania, jakie spełniają. W rzeczywistości wiele komponentów jest ze sobą powiązanych
i korzysta z tych samych modułów, klas i bibliotek.
Kluczem do poznania VCL oraz CLX jest zrozumienie zasady działania różnych typów danych, poznanie
1 z 12
2009-03-14 15:46
RSS | Forum | Pastebin |
Regulamin | Pomoc | Usuń
cookies | Prawa autorskie |
Kontakt | Reklama
77981940.012.png 77981940.013.png 77981940.014.png 77981940.015.png
 
Delphi :: Kompendium :: Rozdział 14 - 4programmers.net http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_14
hierarchii klas itp.
VCL
VCL to Visual Component Library (wizualna biblioteka komponentów). Programowanie w Delphi nie byłoby takie
łatwe dla początkujących, gdyby nie VCL. Poprzednikiem VCL była biblioteka OWL ( Object Windows Library ),
znajdująca się w Turbo Pascalu. Dla użytkownika wywołanie konstruktora Create to tylko jeden wiersz kodu,
powodujący utworzenie komponentu (obiektu). W rzeczywistości na podstawie kodu VCL wykonywany jest
szereg innych procedur, które ostatecznie dają efekt w postaci utworzenia komponentu.
CLX
Opublikowanie Delphi 6 było czymś niezwykłym ze względu na wprowadzenie biblioteki CLX ( Component Library
for Cross-Platform ), czyli międzyplatformowej biblioteki komponentów. Pojawienie się CLX wiązane jest z
wydaniem nowego środowiska programistycznego Kylix, przeznaczonego dla systemu operacyjnego Linux.
Programowanie w Kyliksie jest niezwykle podobne do programowania w Delphi ? nawet interfejs jest ten sam.
Kylix również ? tak jak Delphi ? wykorzystuje język Object Pascal, co mogło trochę dziwić w momencie edycji
produktu. W końcu Linux jest platformą, na której króluje C++.
W każdym razie w związku z pojawieniem się Kyliksa oraz biblioteki CLX przekroczona została pewna bariera ?
od tej pory możliwe jest tworzenie aplikacji zgodnych zarówno z systemem Windows, jak i Linuks.
Tworzenie aplikacji opartych na CLX
Aby stworzyć aplikację działającą w oparciu o CLX, wystarczy z menu File wybrać polecenie New/CLX
Application . Wówczas zmieniona zostanie zawartość palety komponentów oraz edytora kodu.
CLX a VCL
Sam akronim VCL może dawać do zrozumienia, że mamy do czynienia z całkowicie wizualną biblioteką. W
rzeczywistości tak nie jest, bo VCL zawiera również komponenty, które nie są widoczne, ale jednak odpowiadają
za wykonywanie jakichś czynności. Pisząc programy działające w systemie Windows, korzystamy ze
standardowych kontrolek tego systemu (chociażby kontrolka TButton ), zawartych w bibliotece User32.dll lub
CommCtrl32.dll . Natomiast w przypadku CLX komponenty z tej biblioteki są oparte na tzw. widgetach ,
zawartych w bibliotece Qt. Owa biblioteka zawiera niezależne klasy, które swoim wyglądem oraz
funkcjonalnością przypominają standardowe kontrolki Windows.
Słowo widget jest skrótem słów Window Gadget.
Architektura CLX
Architektura CLX jest nieco bardziej złożona niż VCL. Mamy tu bowiem kilka grup komponentów. Oprócz grupy
wizualnej ? VisualCLX ? istnieją jeszcze komponenty BaseCLX (moduły wspólne dla Delphi i Kyliksa), DataCLX
(komponenty zapewniające dostęp do technologii dbExpress ? będziemy o tym mówić w kolejnej części książki)
oraz NetCLX (technologie internetowe).
VCL jest zbudowany na bazie kontrolek WinAPI, zawartych m.in. w bibliotekach User32.dll oraz ComCtrl32.dll .
W przypadku CLX grupa komponentów VisualCLX jest oparta na bibliotece Qt .
Hierarchia klas jest ona bardzo podobna do hierarchii komponentów VCL. Dodano parę nowych klas, inne
zamieniono miejscami, lecz starano się zachować maksymalną kompatybilność pomiędzy CLX i VCL ? tak, aby
przenoszenie kodu odbywało się z jak najmniejszym nakładem pracy.
Windows a Linux
Można by przypuszczać, że dla programisty tworzącego swoje aplikacje w języku Object Pascal nie ma
znaczenia, na jakiej platformie będzie uruchamiany ów program. Oczywiście należy jednak pamiętać o pewnych
elementach charakterystycznych dla danego systemu. Przykładem może być konieczność zwracania uwagi na
nazewnictwo plików w Linuksie ? w systemie tym rozróżniane są np. nazwy modułów na liście uses .
W systemie Linux używany jest inny znak separatora katalogów. W Windows jest to znak backslash (\), a
w Linuksie ? slash (/). Właściwy dla konkretnej platformy znak można odczytać ze stałej PathSeparator .
Pamiętasz, jak podczas omawiania bibliotek DLL wspominałem o konwencjach wywołania stdcall , safecall
i cdecl ? W Kyliksie należy zmienić tę klauzulę na cdecl , gdyż tylko taka forma jest prawidłowa.
Tworząc programy w Kyliksie, należy unikać modułów oraz funkcji charakterystycznych dla Windows ?
np. modułów Windows , ActiveX , ComServ, ComObj itp. ? gdyż nie odnajdziemy tam takich technologii
jak BDE, COM czy ActiveX.
Bardzo ważne jest zapamiętanie, że w Linuksie nie możemy korzystać z komunikatów. Niedopuszczalne
jest zatem wysyłanie komunikatów czy ich przechwytywanie ? np. WM_CHAR itp.
Większość klas nazywa się tak samo. Pamiętaj jednak, że klasa TWinControl w CLX nazywa się
TWidgetControl . Ze względów kompatybilności zachowano jednak również klasę TWinControl , która jest
równoważna klasie TWidgetControl .
Unikaj stosowania funkcji typowych dla Windows: Win32Check , RaiseLastWin32Error .
W systemie Linux nie ma Rejestru ? nie możesz więc korzystać z klasy TRegistry .
Nazwy modułów CLX rozpoczynają się od litery Q ? np. QControls .
System Linux nie używa liter do określania dysków, tak jak ma to miejsce w Windows. Wszystko opiera
się na charakterystycznym systemie plików, gdzie istnieją tylko katalogi główne ? np. /usr
Kompilacja warunkowa
Zarówno w Delphi, jak i w Kyliksie istnieje możliwość wprowadzenia charakterystycznego dla danej platformy
kodu. Wszystko dzięki tzw. symbolom kompilacji warunkowej.
{$IFDEF LINUX}
// kod dla Linuksa
{$ENDIF}
Dla systemu Linux takim symbolem jest LINUX , a dla Windows może to być WIN32 i MSWINDOWS :
{$IFDEF WIN32}
// kod dla Windows
{$ENDIF}
2 z 12
2009-03-14 15:46
77981940.001.png 77981940.002.png 77981940.003.png 77981940.004.png
Delphi :: Kompendium :: Rozdział 14 - 4programmers.net http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_14
Dzięki takiemu prostemu rozwiązaniu można wprowadzać charakterystyczne dla danej platformy elementy
kodu.
Rodzaje komponentów
Komponenty w Delphi dzielą się na wizualne oraz niewizualne ? bynajmniej nie chodzi tutaj o właściwość
Visible , której zmiana na True powoduje ukrycie komponentu.
Komponenty wizualne
Nieprzypadkowo dla określenia komponentu wizualnego często używam w tej książce słowa kontrolka ( control ).
Należy zdać sobie sprawę z tego, że kontrolka to obiekt wizualny, będący w stanie odbierać komunikaty od
użytkownika. Kontrolki mają właściwości mogące określić ich położenie względem projektanta formularzy. Mogą
być także aktywowane (focus). Komponenty wizualne wywodzą się z klasy TControl . Przykładami kontrolek
wizualnych są TButton , TLabel , TListView , TComboBox itp.
Komponenty niewizualne
Komponentem jest każdy obiekt, mogący znaleźć się w palecie komponentów. Niektóre z tych obiektów są
widoczne po uruchomieniu programu, niektóre jednak nie. Komponenty niewidoczne wywodzą się z klasy
TComponent , lecz mimo tego, że ich nie widać, pełnią inną funkcję, często o wiele ważniejszą niż rola obiektów
wizualnych. Przykładem komponentów niewidocznych jest komponent TTimer , TOpenDialog (ogólnie wszystkie
komponenty z palety Dialogs ) oraz komponenty z palety Indy .
Komponenty graficzne
Niektóre komponenty Delphi mimo swego charakteru wizualnego nie posiadają zdolności interakcji z
użytkownikiem ? nie mogą więc stać się aktywne. Nie posiadają także uchwytu, a ich klasą bazową jest
TGraphicControl .
Przykładem takich komponentów są TPaintBox i TImage .
Hierarchia komponentów
Na rysunku 14.1 przedstawiona została hierarchia komponentów VCL. Naturalnie jest to tylko fragment
ogromnej pajęczyny klas.
Rysunek 14.1. Hierarchia komponentów VCL
W CLX ze względów kompatybilności starano się zachować identyczne nazewnictwo klas. Różnica pojawia się w
klasie TWinControl , która w CLX nosi nazwę TWidgetControl . Pamiętaj o tym, że w CLX nie ma klasy
TRegistry , lecz możesz korzystać z klasy TRegINIFile .
TObject
Klasa TObject jest podstawowym fundamentem całej struktury VCL oraz CLX. Zawiera wiele podstawowych
metod, obecnych we wszystkich klasach. Wszystko dzięki dziedziczeniu ? w czasie, gdy pozostałe klasy
dziedziczą po klasie TObject , przejmują jej wszystkie metody. Klasa ta odpowiada za tak podstawowe
czynności, jak:
tworzenie i usuwanie instancji komponentu,
alokację i zwalnianie potrzebnej pamięci,
obsługę komunikatów,
zwracanie informacji na temat rodzaju klasy, nazwy itp.
Metody klasy TObject
Klasa TObject definiuje jedynie metody, które mogą być później używane przez wszystkie inne kontrolki VCL.
Spis najważniejszych metod klasy TObject znajduje się poniżej.
ClassName
class function ClassName: ShortString ;
Owa funkcja zwraca nazwę klasy ? przykład:
ShowMessage ( Button1. ClassName ) ;
Powyższy kod spowoduje wyświetlenie rzeczywistej nazwy klasy, czyli TButton .
ClassNameIs
class function ClassNameIs ( const Name : string ) : Boolean ;
Funkcja sprawdza, czy podana w parametrze klasa odpowiada tej, z której jest wywoływana funkcja. Najlepiej
objaśnić to na przykładzie:
3 z 12
2009-03-14 15:46
77981940.005.png 77981940.006.png 77981940.007.png 77981940.008.png 77981940.009.png
Delphi :: Kompendium :: Rozdział 14 - 4programmers.net http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_14
Button1. ClassNameIs ( ?TButton? ) ; // funkcja zwróci True
Button1. ClassNameIs ( ? TObject ? ) ; // funkcja zwróci False
ClassInfo
class function ClassInfo: Pointer ;
Funkcja zwraca wskaźnik do tablicy zawierającej informacje takie jak typ obiektu, właściwości itp. Wrócimy do
tego nieco później.
ClassParent
class function ClassParent: TClass;
Informacja o klasie bazowej dla naszego komponentu jest zwracana przez funkcję ClassParent . Dzięki owej
funkcji możemy odwołać się do innych właściwości klasy bazowej, nie znając jej podczas tworzenia programu.
ClassType
function ClassType: TClass;
Funkcja działa podobnie jak ClassParent . Jedyna różnica polega na tym, że zwraca ona informacje na temat
klasy, z której jest wywoływana ? np.:
ShowMessage ( Button1. ClassType . ClassName ) ;
Po wykonaniu takiego kodu w okienku wyświetlony zostanie napis TButton . Inna sprawa, że taki sam efekt
uzyskamy, korzystając z funkcji ClassName .
FieldAddress
function FieldAddress ( const Name : ShortString ) : Pointer ;
Funkcja FieldAddress zwraca wskaźnik do właściwości znajdującej się w pamięci. Nazwa właściwości musi
zostać podana w parametrze.
MethodAddress
class function MethodAddress ( const Name : ShortString ) : Pointer ;
Funkcja działa podobnie jak FieldAddress , tyle że ta zwraca wskaźnik do metody umieszczonej w pamięci ? nie
zaś właściwości.
Więcej opisów metod klasy TObject możesz znaleźć w systemie pomocy Delphi lub (w
języku polskim) pod adresem http://4programmers.net/Delphi
TPersistent
Klasą drugą po TObject w całej hierarchii jest TPersistent . Oczywiście większość metod dziedziczy po
TObject , ale wprowadza także swoje metody.
Klasy TPersistent możesz użyć jako klasy bazowej w momencie, gdy deklarujesz klasy, które nie mają być
komponentem. Jaka jest więc różnica między TObject a TPersistent ? Otóż klasa TPersistent może być
przodkiem dla wszystkich klas mogących zapisywać wartości do właściwości, które następnie mogą być
przechowywane w pliku *.dfm (lub *.xfm ? dla Kyliksa).
Metoda Assign
procedure Assign ( Source: TPersistent ) ; virtual ;
Metoda Assign , obecna w klasie TPersistent , powoduje skopiowanie danych (właściwości) z jednego obiektu
do drugiego.
Metoda AssignTo
procedure AssignTo ( Dest: TPersistent ) ; virtual ;
AssignTo działa odwrotnie niż procedura Assign . Powoduje skopiowanie danych do innego obiektu, określonego
w parametrze Dest .
Metoda DefineProperties
procedure DefineProperties ( Filer: TFiler ) ; virtual ;
Procedura DefineProperties umożliwia przechowanie w pliku *.dfm dodatkowych danych ? tym pojęciem
4 z 12
2009-03-14 15:46
77981940.010.png
Delphi :: Kompendium :: Rozdział 14 - 4programmers.net http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_14
zajmiemy się kolejnym rozdziale.
TComponent
Klasa TComponent , jak można wywnioskować z nazwy, jest przodkiem wszystkich komponentów. Komponenty
dziedziczące po TComponent mogą:
być zintegrowane z IDE Delphi, w tym mogą być umieszczone na palecie komponentów;
jeden obiekt typu TComponent może posiadać inny obiekt (być jego rodzicem);
komponenty mogą być konwertowane na obiekty COM lub kontrolki ActiveX.
Obiekty COM są wynalazkiem firmy Microsoft, stąd obecne są jedynie na platformie Windows.
Klasa TComponent wprowadza szereg nowych właściwości oraz metod, obecnych później we wszystkich
komponentach (w końcu wszystkie komponenty pochodzą od klasy TComponent ).
Właściwości klasy TComponent
Klasa TComponent zawiera wiele ciekawych właściwości, które przedstawiłem poniżej.
ComponentCount
property ComponentCount: Integer ;
Właściwość ComponentCount zwraca liczbę obiektów umieszczonych na danym komponencie (rysunek 14.2.):
procedure TMainForm. Button1Click ( Sender: TObject ) ;
begin
Application. MessageBox ( PChar ( 'Na formularzu znajdują się ' + IntToStr ( ComponentCount ) + '
komponenty),
' Tak ', MB_OK)
end;
Rysunek 14.2. Program demonstrujący znaczenie właściwości ComponentCount
ComponentIndex
property ComponentIndex: Integer ;
Inna właściwość klasy TComponent ? Components[] to tablica komponentów. Do konkretnego obiektu można się
odwołać, podając jego indeks. Taki indeks natomiast jest zwracany przez właściwość ComponentIndex .
ShowMessage ( IntToStr (
Button1. ComponentIndex )) ;
W powyższym przypadku w okienku pojawi się cyfra 1 jako numer identyfikacyjny dla komponentu Button1 .
Components
property Components [ Index : Integer ] : TComponent;
Jak wspomniałem powyżej, jest to tablica wszystkich elementów (komponentów) umieszczonych na danym
obiekcie. Do konkretnej kontrolki można się odwołać, podając w nawiasie kwadratowym jej indeks:
Components [ 1 ] . Free ;
Powyższy kod spowoduje zniszczenie obiektu określonego numerem 1.
ComponentState
property ComponentState: TComponentState;
Sygnalizuje stan komponentu. Może zwrócić wartości takie, jak przedstawione w tabeli 14.1.
Tabela 14.1. Możliwe elementy typu TComponentState
Element Opis
csDesigning Komponent jest w trakcie projektowania, np. jego właściwości są zmieniane
csDestroying Komponent za chwilę zostanie zniszczony
csFixups Komponent jest podłączony do innego komponentu znajdującego się na innym formularzu
csLoading Komponent jest właśnie ładowany (tworzony)
5 z 12
2009-03-14 15:46
77981940.011.png
Zgłoś jeśli naruszono regulamin