Tworzenie własnych komponentów
Korzystając z BCB, nie jesteśmy skazani jedynie na korzystanie ze standardowych komponentów VCL. BCB jest środowiskiem, w którym możemy tworzyć własne komponenty. Tworzenie komponentów w BCB jest możliwe dzięki dziedziczeniu.
Wybór komponentu, na podstawie którego tworzymy nowy komponent, zależy od zadań, jakie ma on spełniać. Mamy do dyspozycji kilka możliwości:
- udostępnianie ukrytych własności
- tworzenie komponentów sterujących
- tworzenie komponentów graficznych
- tworzenie niewidocznych komponentów
Udostępnianie ukrytych własnośc
iWykorzystujemy tu mechanizm upubliczniania własności klas bazowych. Jako komponenty bazowe stosujemy (przede wszystkim) komponenty, które w swej nazwie zawierają słowo Custom (pozwalające na konfigurację). Każdy komponent z grupy Custom (na przykład: TCustomPanel) oferuje wiele własności, z których nie możemy korzystać w czasie tworzenia programu (nie znajdują się w sekcji __published).
Uaktywnienie tych własności może nastąpić podczas definicji nowego komponentu przez ponowną deklarację (i tylko deklarację) własności zabezpieczonych (protected) w komponencie rodzica w sekcji __published. Na przykład komponent TCustomPanel posiada zabezpieczoną własnośc FullRepaint (komponent TPanel dostępny w palecie komponentów, jej nie ukatywnił).
Możemy zdefiniować nowy komponent na przykład TNowyPanel, w którym własność FullRepaint będzie widoczna w inspektorze obiektów:
| 1 2 3 4 5 6 7 8 9 | class TNowyPanel: public TCustomPanel { private: protected: public: __fastcall TNowyPanel (Tcomponent* Owner); __published: __property FullRepaint; }; |
Tworzenie komponentów sterujących
Mówiąc o komponentach sterujących, mamy na myśli wszystkie te komponenty, które mogą być aktywnie w trakcie wykonania programu. Komponentem sterującym jest na przykład przycisk TButton, nie jest natomiast etykieta TLabel. Jak zapewne zauważyliście, w czasie wykonania programu, możemy przemieszczać się tabulatorem pomiędzy poszczególnymi elementami okna. Te elementy, na których się zatrzymamy, to na pewno komponenty sterujące.
Z programistycznego punktu widzenia, komponenty sterujący to te, które mają uchwyt (ang. handle) i dzięki temu można na ich rzecz wykonywać funkcję API. Każdy komponent sterujący dziedziczy (bezpośrednio lub pośrednio) z klasy TWinControl.
Tworzenie komponentów graficznych
Wszystkie inne komponenty (widoczne na formularzu podczas wykonania programu) to tzw. komponenty graficzne. W przeciwieństwie do komponentów sterujących, nie mogą one być aktywne podczas wykonania programu (nie mają własnego uchwytu). Ich dużą zaletą jest mniejsza "zasobożerność" w porównianiu z komponentami sterującymi. Przykładem komponentu graficznego jest etykieta TLabel. Tworząc komponenty graficzne dziedziczymy (bezpośrednio lub pośrednio) z klasy TGraphicControl.
Nowe własności i metody
Tworząc nowe komponenty, zazwyczaj nie poprzestaniemy na składnikach odziedziczonych z klas bazowych. Zwykle konieczne będzie dodanie nowych własności i metod.
Dodanie nowego komponentu
Do tworzenia nowych komponentów w BCB będziemy używali generatora (ang. wizard). Teraz jednak w celu lepszego zrozumienia procesu tworzenia komponentu, prześledzimy kroki, jakie wykonuje generator.
Tworzenie komponentu przebiega w kilku krokach:
- dodanie nowego modułu
- zdefiniowanie klasy dla nowego komponentu
- definicja konstruktora klasy komponentu
- rejestracja komponentu
Dodanie nowego modułu
Z głównego menu BCB wybieramy File->New, powoduje to wyświetlenie okna New Items (Nowy element). W oknie tym wybieramy pozycję Unit. W ten sposób dodaliśmy do projektu nowy moduł, w którym zapiszemy definicję komponentu. Pliki modułu po wstawieniu mają domyślne nazwy (Unit...). Zapisaujemy je więc pod wybranąprzez siebie nazwą (na przykład NowyKomponent).
Zdefiniowanie klasy dla nowego komponentu
W pliku nagłówkowym modułu (na przykład NowyKomponent.h) wpisujemy definicję klasy komponentu. Poniższy kod definiuje klasę nowego komponentu TNowyPanel:
| 1 2 3 4 5 6 7 8 9 | class TNowyPanel: public TCustomPanel { private: protected: public: __fastcall TNowyPanel (TComponent* Owner); __published: __property FullRepaint; }; |
Definicja konstruktora klasy komponentu
W ciele definicji klasy komponentu został zadeklarowany konstruktor
| 1 | __fastcall TNowyPanel (TComponent* Owner) |
W pliku źródłowym klasy (na przykład NowyKomponent.cpp) musimy zdefiniować konstruktor (nawet jeżeli będzie to definicja pusta):
| 1 2 3 | __fastcall TnowyPanel::TNowyPanel (TComponent* Owner) : TCustomPanel (Owner) { } |
Rejestracja komponentu
Rejestracja komponentu oznacza poinformaowanie BCB, jaki komponent ma być dodany i na której karcie palety ma zostac umieszczony (położenie komponentu na palecie możemy później modyfikować). Podczas rejestracji dodajemy do pliku źródłowego modułu (na przykład Nowykomponent.cpp) definicje funkcji o nazwie Register. W definicji tej funkcji należy zadeklarować tablicę o elementach typu TComponentClass (na przykład KlasyDoRejestracji).
Tablica ta będzie przechowywała identyfikatory klas komponentów do rejestracji (identyfikator ten możemy uzyskać stosując operator __classid z nazwą klasy jako argumentem):
| 1 | TComponentClass KlasyDoRejestracji[1] = { __classid (TNowyPanel)}; |
Liczba elementów w tablicy KlasyDoRejestracji, zależy od tego ile komponentów będzie rejestrowanych (możemy jednocześnie zarejestrować wiele komponentów).
W definicji funkcji Register następuje wywołanie funkcji RegisterComponents (dla każdego komponentu z tablicy komponentów). Argumentami funkcji RegisterComponents są kolejno:
- karta palety komponentów, na której komponent ma zostać umieszczony
- identyfikator tablicy z klasami do rejestracji
- indeks komponentu w tablicy
I tak na przykład wywołanie funkcji:
| 1 | RegisterComponents ("Samples", KlasyDoRejestracji, 0); |
Spowoduje rejestrację pierwszego (indeks 0) komponentu z tablicy KlasyDoRejestracji i umieszczenie go na karcie Samples palety komponentów.
Zastosowanie generatora komponentów
Teraz, kiedy już znamy proces tworzenia komponentu, użyjmy generatora. Z głównego menu BCB wybieramy File->New, powoduje to wyświetlenie okna New Item. W oknie tym wybieramy pozycję Component. Zostanie wówczas otwarty generator.
W oknie generatora musimy podać następujące informacje:
- nazwa klasy tworzonego komponentu (Class Name)
- nazwę klasy, z której komponent, będzie dziedziczył (Ancesor type)
- kartę palety komponentów, w której komponent zostanie umieszczony (Palette Page)
Po podaniu wszystkich informacji, wybieramy przycisk OK i opisane powyżej kroki są wykonywane automatycznie.
Udostępnianie komponentu w palecie komponentów
Żeby można było udostępnić komponent w trakcie tworzenia programu, po jego utworzeniu musimy jeszcze wykonać następujące kroki:
- utworzenie ikony, która będzie reprezentowała komponent na palecie komponentów (jeżeli tego nie zrobimy, BCB zastosuje ikonę komponentu rodzica)
- instalacje nowego komponentu.
Ikona komponentu
W celu utworzenia ikony posłużymy się narzędziem Image Editor dostępnym w menu Tools menu głównego. Ikonę zapisujemy w pliku *.dcr. Nazwa pliku musi być taka sama jak nazwa modułu z definicją komponentu (na przykład NowyKomponent). Natomiast nazwa mapu bitowej (w jednym pliku może być ich wiele) taka jak nazwa komponentu (na przykład TNowyPanel).
Instalacje nowego komponentu
Uwaga instalacja komponentu wiąże się z przebudową istniejącej biblioteki i dlatego dobrym zwyczajem jest wykonanie kopii bezpieczeństwa pliku biblioteki (domyślnie cmplib32.ccl). Przed instalacją pliki źródłowe komponentu (*.cpp, *.h, *.dcr) należy przenieść do katalogu CbuilderLibObj, gdzie będą poszukiwane. W celu instalacji nowego komponentu wybieramy Component->Instal z menu głównego. Zostanie wyświetlone okno intalatora.
W oknie instalatora wybieramy przycisk Add. Zostanie wyświetlone kolejne okno, w którym wskazujemy moduł zawierający komponent (lub komponenty) do instalacji.
Po wskazaniu właściwego modułu, naciskamy przycisk OK, który uruchomi proces instalacji. Ponieważ instalacja nowego komponentu wiąże się z przebudową całej biblioteki, w trakcie instalacji żaden projekt nie może być edytowany (jeżeli jakiś projekt będzie otwarty zostanie automatycznie zamnknięty). Po instalacje nowy komponent jest widoczny na palecie komponentów i może zostać wykorzystany w programie.