20.doc

(293 KB) Pobierz

 

Rozdział 20.
Tworzenie komponentów









C:\Dokumenty\Roboczy\Delphi 4 dla kazdego\20.doc              761










Rozdzia³ 20. ¨ Tworzenie komponentów              799

Delphi udostępnia szeroki asortyment komponentów możliwych do wykorzystania w tworzonych aplikacjach. W skład oferowanych komponentów wchodzą proste kontrolki Windows, jak również specjalizowane komponenty nie wywodzące się z tego środowiska. Mimo to, może się zdarzyć tak, że będziesz musiał stworzyć komponent według własnego pomysłu, aby zrealizować zadanie, którego nie są w stanie wykonać komponenty preinstalowane. Aby skonstruować komponent należy wykonać następujące kroki:

1.                                       Rozpocząć proces tworzenia przy pomocy okna dialogowego nowego komponentu (New Component).

2.                                       Dodać właściwości, metody i zdarzenia do klasy komponentu.

3.                                       Przetestować komponent.

4.                                       Dodać komponent do Palety Komponentów.

W tym rozdziale poznasz zasady tworzenia komponentów. Podobnie jak w przypadku innych aspektów Delphi, również i ten okaże się w miarę prosty, po bliższym zapoznaniu się z nim. Zasady tworzenia poznasz budując komponent o nazwie TFlashingLight. Jest to zwykły komponent typu Label z migoczącym tekstem. Nim rozdział ten dobiegnie końca będziesz już wiedział, w jaki sposób tworzy się proste komponenty.

Tworzenie nowego komponentu

Tworzenie komponentów wymaga wyższego poziomu umiejętności programistycznych niż ten, który osiągnąłeś do tej pory. Po pierwsze trzeba stworzyć klasę dla nowego komponentu. Klasa ta musi być odpowiednio zaprojektowana tak, aby niektóre z jej właściwości były wyświetlane przez Inspektor Obiektów, podczas gdy inne będą dostępne tylko w czasie wykonania. Dodatkowo, niemal z całą pewnością trzeba będzie stworzyć klika metod dla komponentu. Niektóre z metod będą prywatnymi metodami komponentu; inne będą publiczne, dzięki czemu użytkownik komponentu będzie miał do nich dostęp. W końcu, niezbędne może okazać się również utworzenie kilku zdarzeń komponentu. Jak widać, z zagadnieniem tym wiąże się trochę pracy. Tworzenie komponentów opiera się na czystym programowaniu.

Okno dialogowe nowego komponentu

Okno dialogowe nowego komponentu (New Component) umożliwia szybkie rozpoczęcie procesu tworzenia. Aby wyświetlić to okno, wybierz polecenie File | New; kiedy otwarte zostanie Repozytorium, kliknij dwukrotnie na ikonie Component.

Okno New Component podczas tworzenia nowego komponentu przedstawione zostało na rysunku 20.1.

 

Rysunek 20.1.

Okno dialogowe nowego komponentu

 

Pole Ancestor type służy do określenia klasy macierzystej dla nowego komponentu. Klasy wszystkich zainstalowanych komponentów są dostępne na liście rozwijalnej tego pola. Tworząc nowy komponent należy wybrać klasę podstawową, która najlepiej odpowiada typowi komponentu, jaki chcemy stworzyć.

Przykładowo, komponent FlashingLabel jest po prostu etykietą, która miga. Do rozpoczęcia jego budowy w zupełności wystarczy standardowy komponent Label, dlatego jako klasę przodka można wybrać TCustomLabel. Z drugiej jednak strony, gdybyśmy chcieli zbudować komponent służący np. do tworzenia skrótów Windows, jako klasę podstawową należałoby wtedy przyjąć TComponent (klasę podstawową wszystkich komponentów) ponieważ nie istnieje żaden inny komponent VCL, który mógłby służyć jako lepsza podstawa do rozpoczęcia pracy.

 

Delphi udostępnia kilka klas, które można użyć jako klasy podstawowe dla nowych komponentów. Nazwy tych klas zaczynają się od frazy TCustom. Przykładowo – klasą podstawową dla TLabel jest TCustomLabel. Tworząc nowy komponent można użyć jednej z klas TCustom… jako klasy podstawowej. Klasy typu TCustom… posiadają właściwości, które najprawdopodobniej będą potrzebne dla danego typu komponentu, nie są one jednak publikowane (właściwości publikowane to właściwości wyświetlane przez Inspektor Obiektów w czasie projektowania). Wszystko co trzeba zrobić, aby właściwości zostały opublikowane to ponownie zadeklarować właściwości klasy podstawowej w sekcji published deklaracji klasy komponentu. Ma to znaczenie niebagatelne, gdyż klasa pochodna nie jest w stanie anulować opublikowania właściwości w klasie macierzystej.

Rozpoczęcie od klasy TCustom umożliwia dokładne określenie właściwości, które mają być publikowane.

Podczas wyprowadzania nowego komponentu z komponentu istniejącego, wykorzystywana jest jedna z cech Object Pascala – dziedziczenie. O dziedziczeniu mowa była w rozdziale trzecim „Klasy i programowanie obiektowo zorientowane”. Dziedziczenie obiektu oznacza w rzeczywistości przejęcie wszelkich cech, jakimi dysponuje dany obiekt i dodanie własnej funkcjonalności. Klasa z której dziedziczone są własności, nazywana jest klasą macierzystą, podstawową, lub bazową (ang. base class), z kolei nową klasę nazywa się klasą pochodną lub potomną (ang. derived class). W poprzednim przykładzie klasą bazową była TCustomLabel, a klasą potomną – TFlashingLabel.

Po wybraniu klasy przodka w polu Class Name wpisz nazwę klasy tworzonego komponentu. Nazwa ta powinna zaczynać się od litery T i opisywać funkcję, jaką spełnia klasa. Komponent, którego budową zajmiesz się już niedługo w tym rozdziale, będzie nosił nazwę TFlashingLabel. Jeżeli wpisana zostanie nazwa klasy, która istnieje już w bibliotece komponentów, okno dialogowe dodania komponentu poinformuje o tym w chwili kliknięcia w przycisk OK. Kontynuacja procesu zależy więc od wpisania unikalnej nazwy klasy.

 

Nie ma żadnego szczególnego powodu, dla którego należy rozpoczynać nazwę klasy od litery T; jest to po prostu pewna konwencja przyjęta w nazewnictwie klas firmy Borland. (Tradycja stosowania litery T w nazwach klas firmy Borland wywodzi się z wczesnego okresu języka Turbo Pascal. Tego typu nazewnictwo było stosowane w bibliotece Turbo Vision, OWL, a obecnie w VCL.) Niektórzy programiści stosują literę T w przypadku klas dziedziczonych z klas firmy Borland, natomiast pomijają ją we własnych klasach. Decyzja należy do Ciebie.

 

Profesjonalni twórcy komponentów już dawno temu nauczyli się dbać o to, aby nazwy ich klas komponentów były unikalne. Wyobraź sobie problemy jakie mogłyby powstać, gdyby dwóch producentów komponentów nazwało swój produkt jednakową nazwą, np. TFancyLabel. W firmie TurboPower gdzie pracuję, nazwy naszych komponentów typu Async Professional zaczynają się od TApd, komponenty Orpheus rozpoczynają się od znaków TOr, komponenty Abbrevia od TAb itd. Chociaż nie ma tutaj gwarancji, iż nazwy te nie pokryją się z nazwami komponentów innych twórców, jest to jednak dosyć duża szansa gwarancja uniknięcia takiego zjawiska.

Pole Palette Page określa stronę Palety Komponentów, na której pojawić powinna się ikona komponentu. (W rzeczywistości ikona pojawi się na Palecie dopiero po zainstalowaniu pakietu środowiskowego zawierającego reprezentujący ją komponent.) Można wybrać istniejącą zakładkę Palety Komponentów lub wpisać nazwę nowej zakładki, jaką chcemy utworzyć dla danego komponentu.

Pole Unit file name służy do wyspecyfikowania nazwy pliku, który będzie przechowywał kod źródłowy komponentu. Nazwa tego pliku jest tworzona automatycznie przez Delphi w oparciu o nazwę komponentu, ale w miarę potrzeby można ją zmodyfikować. Pole Search path służy do wyspecyfikowania ścieżki poszukiwań, jaką Delphi powinno stosować przy odnajdywaniu pakietów komponentu. Zazwyczaj nie ma potrzeby modyfikowania tego pola.

Przycisk Install służy do rozpoczęcia fizycznej instalacji nowego komponentu w pakiecie. Nie musisz się teraz tym przejmować, ponieważ do instalacji użyjesz domyślnego pakietu Delphi, przeznaczonego dla różnego typu komponentów.

Tworzenie komponentu FlashingLabel

Teraz możemy już przystąpić do wykonania pierwszych czynności związanych z tworzeniem komponentu TFlashingLabel. Jak wspomniałem wcześniej, będzie to standardowy komponent Label wyświetlający na ekranie migoczący tekst. Mając to w pamięci, rozpocznij pracę:

1.                                       Poleceniem File | New otwórz Repozytorium.

2.                                       Kliknij dwukrotnie na ikonie Component; wyświetlone zostanie okno dialogowe nowego komponentu (New Component).

3.                                       Z pola listy rozwijalnej Ancestor type wybierz klasę podstawową TCustomLabel.

4.                                       W polu Class Name wpisz TFlashingLabel.

5.                                       W polu Palette Page pozostaw domyślną wartość Samples; w chwili instalacji nowy komponent zostanie dodany do strony Samples Palety Komponentów.

6.                                       Kliknij na przycisk OK, aby zamknąć okno nowego komponentu. Wyświetlony zostanie Edytor Kodu wraz z nowym modułem kodu źródłowego.

7.                                       Zapisz moduł pod nazwą FlashingLabel.pas.

Postać modułu na obecnym etapie prac przedstawiona została na listingu 20.1.

Listing 20.1. FlashingLabel.pas

unit FlashingLabel;

 

interface

 

uses

  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

  StdCtrls;

 

type

  TFlashingLabel = class(TCustomLabel)

  private

    { Private declarations }

  protected

    { Protected declarations }

  public

    { Public declarations }

  published

    { Published declarations }

  end;

 

procedure Register;

 

implementation

 

procedure Register;

begin

  RegisterComponents('Samples', [TFlashingLabel]);

end;

 

end.

 

Jak widać, klasa TFlashingLabel wywodzi się z klasy TCustomLabel. Pomijając słowa kluczowe określające kategorię dostępności (private, public, protected i published) deklaracja klasy jest pusta. Po omówieniu elementów, jakie składają się na komponent, będziesz mógł przystąpić do wypełniania pustych miejsc.

Okno nowego komponentu umożliwia szybkie rozpoczęcie pracy, przez wypełnienie pewnych podstawowych części modułu. Trudniejsza cześć pracy leży oczywiście w rękach programisty, chociaż stworzona została przynajmniej procedura Register oraz deklaracja samej klasy. Zboczmy na chwilę z głównego tematu, skupiając się na procedurze Register.

Procedura Register

Rejestrowanie komponentów jest niezbędne, aby Delphi mogło wiedzieć, jakie komponenty znajdują się w bibliotece komponentów i na jakiej stronie Palety Komponentów powinny się pojawiać. Typowa procedura Register wygląda następująco:

 

procedure Register;

begin

  RegisterComponents('Samples', [TKomponent]);

end;

Aby zarejestrować komponent, procedura Register wywołuje procedurę RegisterComponents pobierającą dwa parametry. Pierwszym z nich jest nazwa strony Palety Komponentów, na której ko...

Zgłoś jeśli naruszono regulamin