Delphi __ Kompendium __ Roz15.pdf
(
1000 KB
)
Pobierz
Delphi :: Kompendium :: Roz...
Delphi :: Kompendium :: Rozdział 15 - 4programmers.net http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_15
Logowanie | Rejestracja | Forum | Pomoc | Reklama | Szukaj
Strona główna :: Delphi :: Kompendium
Rozdział 15
Edytuj Historia
Delphi
Artykuły
Kompendium
Gotowce
FAQ
.NET
Turbo Pascal
FAQ
PHP
FAQ
Java
FAQ
C/C++
Artykuły
FAQ
C#
Wprowadzenie
Assembler
FAQ
(X)HTML
CSS
JavaScript
Z pogranicza
Algorytmy
WIĘCEJ
»
Tworzenie komponentów
Poprzedni rozdział stanowił wprowadzenie do technik tworzenia komponentów. Omówiłem w nim rolę VCL i CLX
w programowaniu w Delphi oraz hierarchię klas. Przyznam, mogło to być nieco nudne ze względu na dużą
dawkę wiedzy teoretycznej. Tym razem zajmiemy się już programowaniem własnych projektów i
zastosowaniem ich w praktyce.
Spis treści
1 Tworzenie nowego komponentu
2 Edycja kodu
3 Konstruktory i destruktory
4 Właściwości
4.1 Klauzula default
4.2 Klauzula stored
4.3 Klauzula nodefault
4.4 Właściwość wyliczeniowa
4.5 Właściwość zbiorowa
5 Zdarzenia
5.1 Definiowanie własnych zdarzeń
6 Ikona dla komponentów
7 Przykładowy komponent
7.1 Ogólny zarys klasy
7.2 Komunikaty
7.3 Kod źródłowy komponentu
8 Instalacja komponentów
9 Demonstracja możliwości komponentu TURLabel
10 Zachowanie komponentu
11 Komponenty graficzne
11.1 Ogólny zarys klasy komponentu
11.2 Kod źródłowy komponentu
12 Pakiety komponentów
13 Podsumowanie
Delphi
C/C++
Turbo Pascal
Assembler
PHP
Programy
Dokumentacja
Kursy
Komponenty
WIĘCEJ
»
W tym rozdziale:
wykorzystasz w sposób praktyczny wiedzę na temat komponentów;
zaprojektujesz swój pierwszy komponent ? TURLabel;
nauczysz się instalować komponenty;
zaprojektujesz komponent graficzny.
Tworzenie nowego komponentu
Już dłuższy czas pracujesz z Delphi, powinieneś więc zauważyć istnienie menu
Component
. Nas na tym etapie
zainteresują jedynie dwie pozycje tego menu ?
New Component
i
Install Component
. Pierwsze polecenie służy
do stworzenia nowego projektu komponentu, natomiast za pomocą drugiego możemy zainstalować już
istniejący komponent. Po wybraniu tej opcji na palecie komponentów zostanie utworzona nowa ikonka ?
wówczas komponent będzie działał jak zwykły komponent VCL.
Zajmijmy się jednak tworzeniem nowego komponentu. Z menu
Component
wybierz
New Component
. Na
ekranie zobaczysz wówczas takie okienko, jakie zostało przedstawione na rysunku 15.1.
Rysunek 15.1. Tworzenie nowego komponentu
W pierwszym polu z listy rozwijalnej należy wybrać komponent, który będzie stanowił klasę bazową dla
naszego nowego obiektu. Ja z tej listy wybrałem klase
TLabel
. Jeżeli chcesz tworzyć komponent od początku,
wybierz pozycję
TComponent
. Jest to bazowa klasa dla wszystkich komponentów, zawierająca parę potrzebnych
czasem procedur i funkcji.
1 z 14
2009-03-14 15:49
Delphi :: Kompendium :: Rozdział 15 - 4programmers.net http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_15
W kolejnym polu ?
Class Name
? musisz wpisać nazwę nowego komponentu. Pamiętaj, że wedle obowiązującej
zasady należy poprzedzić nazwę literą T. Pole
Palette Page
określa, na jakiej palecie zostanie zainstalowany
komponent.
Unit file name
to ścieżka do katalogu, w którym zostaną zapisane nowe pliki z komponentem.
Zawartość tego pola pozostawiłem niezmienioną. I wreszcie ostatnie pole określa ścieżkę do katalogu, gdzie
znajdować się będą potrzebne do kompilacji pliki komponentu. ${DELPHI} oznacza domyślną ścieżkę do pliku
programu Delphi.
Po naciśnięciu przycisku
Install
komponent zostanie zainstalowany na wybranej palecie, natomiast po
naciśnięciu przycisku OK w edytorze kodu zostanie jedynie wyświetlona zawartość kodu komponentu.
Edycja kodu
Copyright © 2000-2006 by Coyote Group 0.9.3-pre3
Czas generowania strony: 1.5802 sek. (zapytań SQL:
11)
Po wykonaniu operacji opisanych w poprzednim punkcie w edytorze kodu powinien zostać wyświetlony taki
kod, jak w listingu 15.1.
Listing 15.1. Podstawowy kod komponentu TURLabel
unit
URLabel;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, StdCtrls;
type
TURLabel =
class
(
TLabel
)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
published
{ Published declarations }
end
;
procedure
Register
;
implementation
procedure
Register
;
begin
RegisterComponents
(
'Samples'
,
[
TURLabel
])
;
end
;
end
.
Kluczowe znaczenie ma procedura
Register
. Następuje w niej zarejestrowanie komponentu realizowane przez
polecenie
RegisterComponents
. Pierwszy parametr oznacza nazwę palety. Drugi parametr to nazwy
komponentów do zainstalowania. Muszą one być wpisane w nawiasie kwadratowym, gdyż w tym wypadku
występują jako elementy tablicy. Taki zapis jest konieczny, gdyż jeden moduł ? w tym wypadku
URLabel
?
może zawierać kilka klas (komponentów).
Podczas wpisywania zakładki dla tworzonego komponentu nie musisz podawać nazwy
zakładki już istniejącej ? jeżeli wpiszesz nazwę nieistniejącej zakładki, zostanie ona
utworzona przez Delphi.
Zwróć uwagę, że w klasie możesz używać nowej sekcji ?
published
. Ta sekcja może zawierać metody, które
będą wyświetlone w Inspektorze Obiektów.
Konstruktory i destruktory
Komponenty, podobnie jak zwykłe klasy, posiadają konstruktory oraz destruktory. Nie są to co prawda
obowiązkowe elementy klasy, gdyż nawet jeśli ich nie zadeklarujemy, to i tak komponent będzie posiadał
domyślny konstruktor z klasy bazowej (najwyżej ?
TObject
). W przypadku komponentu konstruktor winien
mieć parametr
AOwner
(typu
TComponent
), który zawierałby wskazanie komponentu (lub formularza) rodzica:
public
constructor
Create
(
AOwner : TComponent
)
;
override
;
destructor
Destroy;
override
;
Jak widzisz, zarówno konstruktor, jak i destruktor są opatrzone klauzulą
override
, co znaczy, że są
przedefiniowane (była o tym mowa w 3. rozdziale książki) ? możemy dla nich wpisać kod:
constructor
TURLabel.
Create
(
AOwner : TComponent
)
;
begin
inherited
Create
(
AOwner
)
;
{ podczas wywoływania konstruktora dla właściwości przypisz domyślny tekst }
FURL :=
'http://4programmers.net'
;
end
;
destructor
TURLabel.
Destroy
;
begin
inherited
;
end
;
W tym miejscu oprócz typowego utworzenia obiektu (działanie konstruktora) następuje również przydzielenie
wartości dla właściwości FURL.
Właściwości
Właściwości komponentów służą do przechowywania wartości różnych typów. Jednak jeśli chcemy, aby
właściwości były widoczne w Inspektorze Obiektów, należy użyć kolejnej sekcji w klasie ? sekcji
published
:
property
URL :
String
read
FURL
write
FURL;
2 z 14
2009-03-14 15:49
RSS
|
Forum
|
Pastebin
|
Regulamin
|
Pomoc
|
Usuń
cookies
|
Prawa autorskie
|
Kontakt
|
Reklama
Delphi :: Kompendium :: Rozdział 15 - 4programmers.net http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_15
Właściwość należy oznaczyć słowem kluczowym
property
. W tym wypadku właściwość URL będzie typu
String
.
Zwykło się także definiować zmienne pomocnicze, których deklaracje umieszcza się w sekcji
private
. Nazwy
owych zmiennych umieszczane są po słowach kluczowych
read i write
. W ten sposób łatwo utworzyć jakąś
właściwość tylko do odczytu (pozostawiając jedynie klauzulę
read
) lub tylko do zapisu (klauzula
write
), albo
też zarówno do zapisu, jak i do odczytu (zarówno
read
, jak i
write
).
Regułą stało się już specjalne nazewnictwo zmiennych pomocniczych, polegające na
dodawaniu przed nazwą litery F.
Klauzula default
Podczas pisania samego komponentu istnieje możliwość określania domyślnej wartości za pomocą klauzuli
default
.
property
Count :
Integer
read
FCount
write
FCount
default
1
;
W takim wypadku domyślna wartość właściwości
Count
to 1.
Klauzula default obejmuje jedynie typy liczbowe i zbiory (
set
) ? nie obsługuje natomiast łańcuchów
String
.
Klauzula stored
W przypadku typów typu
Boolean
używa się klauzuli
stored
, a nie
default
? np.:
property
DoIt :
Boolean
read
FDoIt
write
FDoIt
stored
False
;
Jeśli nie skorzystamy z klauzuli
stored
, program za domyślną wartość dla właściwości przyjmie
True
.
Klauzula nodefault
Klauzula
nodefault
jest przeciwieństwem
defulat
? oznacza, że właściwość nie będzie miała wartości
domyślnej. Stosowana jest jedynie w niektórych przypadkach, gdy klasa bazowa, z której korzysta nasz
komponent, posiada właściwość domyślną.
TBaseClass =
class
private
FProp :
Integer
;
published
property
Prop :
Integer
read
FProp
write
FProp
default
1
;
end
;
TMyClass =
class
(
TBaseClass
)
private
FProp :
Integer
;
published
property
Prop :
Integer
read
FProp
write
FProp
nodefault
;
end
;
W takim wypadku klasa
TMyClass
także będzie posiadać właściwość
Prop
, tyle że nie będzie już ona zawierała
wartości domyślnej.
Właściwość wyliczeniowa
O właściwościach wyliczeniowych wspominałem w poprzednim rozdziale, lecz tym razem zajmiemy się ich
deklaracją. Przypominam, że właściwość wyliczeniowa to lista rozwijalna z możliwymi wartościami (rysunek
15.2).
Rysunek 15.2. Właściwość wyliczeniowa
W języku Object Pascal właściwości wyliczeniowe to w rzeczywistości deklaracje typu
set of
.
type
TSetCarOption =
(
coFiat, coOpel, coPorshe
)
;
TSetCarOptions =
set
of
TSetCarOption;
TMyClass =
class
(
TComponent
)
private
FCar : TSetCarOptions;
protected
{ Protected declarations }
public
{ Public declarations }
3 z 14
2009-03-14 15:49
Delphi :: Kompendium :: Rozdział 15 - 4programmers.net http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_15
published
property
Car : TSetCarOptions
read
FCar
write
FCar
default
[
coFiat
]
;
end
;
Zadeklarowaliśmy właśnie właściwość wyliczeniową typu
TSetCarOptions
. W tym wypadku właściwość
Car
będzie posiadała domyślną wartość ?
coFiat
.
Właściwość zbiorowa
Przykład właściwości zbiorowej przedstawiony został na rysunku 15.3.
Rysunek 15.3. Właściwość zbiorowa
Deklarowanie właściwości zbiorowej w rzeczywistości wiąże się z zadeklarowaniem nowego typu danych (klasy).
type
TCarClass =
class
(
TPersistent
)
private
FFuel :
Integer
;
FCarName :
String
;
published
property
CarName :
String
read
FCarName
write
FCarName;
property
Fuel :
Integer
read
FFuel
write
FFuel;
end
;
TMyClass =
class
(
TComponent
)
private
FCar : TCarClass;
protected
{ Protected declarations }
public
constructor
Create
(
AOwner : TComponent
)
;
override
;
destructor
Destroy;
override
;
published
property
Car : TCarClass
read
FCar
write
FCar;
end
;
Nasz komponent będzie posiadał właściwość zbiorową
Car
. Po jej rozwinięciu w Inspektorze Obiektów pojawią
się właściwości z klasy
TCarClass
. Mamy do czynienia z nową klasą
TCarClass
i przed skorzystaniem z jej
właściwości należy ją utworzyć (wywołać konstruktor):
constructor
TMyClass.
Create
(
AOwner: TComponent
)
;
begin
inherited
Create
(
AOwner
)
;
FCar := TCarClass.
Create
;
// utworzenie klasy
end
;
destructor
TMyClass.
Destroy
;
begin
FCar.
Free
;
// zwolnienie
inherited
;
end
;
Zdarzenia
Zdarzenia, podobnie jak właściwości naszego komponentu, muszą być deklarowane w sekcji
published
? tak,
aby były widoczne w Inspektorze Obiektów ? np. w ten sposób:
property
OnMouseEnter : TNotifyEvent
read
FOnMouseEnter
write
FOnMouseEnter;
property
OnMouseLeave : TNotifyEvent
read
FOnMouseLeave
write
FOnMouseLeave;
Zapis ten jest dość dziwny, gdyż sprawia wrażenie, jakbyśmy deklarowali zwykłe właściwości, tyle że typu
TNotifyEvent
. Typ
TNotifyEvent
jest zadeklarowany w module
Classes
:
type
TNotifyEvent =
procedure
(
Sender:
TObject
)
of
object
;
Można powiedzieć, że określa on procedurę zdarzeniową, która miałaby tylko jeden parametr ?
Sender
. Już
nieraz podczas lektury tej książki miałeś okazję zapoznać się z moją opinią o tym, że dana procedura
zdarzeniowa musi mieć parametr
Sender
. Teraz już wiesz, że zdarzenie
OnClick
jest typu
TNotifyEvent
i stąd
musi posiadać parametr
Sender
.
Definiowanie własnych zdarzeń
Czasem może przytrafić się sytuacja, gdy w naszym komponencie będzie wymagane zdarzenie zawierające
więcej niż jeden parametr ? po prostu będzie umożliwiało użytkownikowi przekazanie jakiś funkcji. W takim
wypadku konieczne stanie się zadeklarowanie nowego typu zdarzenia:
4 z 14
2009-03-14 15:49
Delphi :: Kompendium :: Rozdział 15 - 4programmers.net http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_15
type
TMyEvent =
procedure
(
Sender:
TObject
; X :
Integer
)
of
object
;
Taka składnia ? tj. umieszczenie frazy
of object
na końcu ? jest obowiązkowa. Teraz oprócz zwykłego
parametru
Sender
zdarzenie będzie posiadać także parametr
X
. Co z nim zrobimy? To już zależy od
programisty.
Gdy chcesz, aby jakieś działanie komponentu spowodowało wystąpienie zdarzenia, możesz zastosować po
prostu taki kod:
OnURLClick
(
Self
,
1
)
;
A zatem pierwszym parametrem
Self
zastępujemy wymagany parametr typu
TObject
, natomiast drugi
parametr przekazany wraz ze zdarzeniem to cyfra 1.
Ikona dla komponentów
Po zainstalowaniu komponentu Delphi przydzieli dla niego swoją własną ikonę. W każdym wypadku można to
zmienić, przypisując temu komponentowi osobną ikonę. Wystarczy skorzystać z programu do tworzenia bitmap.
Możesz użyć np. programu Image Editor, którego już wcześniej używaliśmy przy okazji tworzenia różnych
zasobów.
W przypadku, gdy tworzysz zasoby dla komponentu, tworzysz plik .DCR, a nie .RES! Uważaj
na to! Także słowo ikona komponentu jest tylko terminem umownym, gdyż w zasobie
musisz stworzyć NIE ikonę, ale BITMAPĘ o rozmiarach 24×24 piksele.
Stwórz więc nowy plik .DCR, a w nim bitmapę 24´24 piksele, na której narysuj jakiś obrazek. Cały zasób
następnie włącz do kodu komponentu za pomocą dyrektywy
{$R ZASOBY.DCR}
.
Należy pamiętać o jeszcze jednej kwestii związanej z nazewnictwem bitmapy ? musi się ona
nazywać tak samo, jak klasa (komponent), która wykorzystuje tę ikonę. A zatem jeżeli
komponent nazywa się
TURLabel
, bitmapa musi również nosić nazwę
TURLABEL
.
Przykładowy komponent
Właściwie możesz już przystąpić do napisania swojego pierwszego komponentu. Nie będzie to nic
nadzwyczajnego ? po prostu etykieta, która jest w rzeczywistości odnośnikiem do strony WWW. Jej kliknięcie
spowoduje otwarcie żądanego adresu.
Ogólny zarys klasy
W przypadku, gdy masz już otwarty nowy projekt, powinieneś mieć w edytorze ?czysty? kod tworzonego
właśnie komponentu. Kod naszej nowej klasy
TURLabel
powinien przedstawiać się w następujący sposób:
TURLabel =
class
(
TLabel
)
private
FURL :
String
;
FParametr :
String
;
FOnMouseEnter, FOnMouseLeave : TNotifyEvent;
FOnURLClick : TClickEvent;
FDefaultFontColor : TColor;
FDefaultFontStyle : TFontStyles;
protected
procedure
CmMouseEnter
(
var
Msg : TMessage
)
;
message
CM_MOUSEENTER;
procedure
CmMouseLeave
(
var
Msg : TMessage
)
;
message
CM_MOUSELEAVE;
procedure
WMLButtonDown
(
var
Msg : TMessage
)
;
message
WM_LBUTTONDOWN;
public
constructor
Create
(
AOwner : TComponent
)
;
override
;
destructor
Destroy;
override
;
published
property
URL :
String
read
FURL
write
FURL;
// URL do otwarcia
property
Parametr :
String
read
FParametr
write
FParametr;
// dodatkowy parametr
property
OnMouseEnter : TNotifyEvent
read
FOnMouseEnter
write
FOnMouseEnter;
property
OnMouseLeave : TNotifyEvent
read
FOnMouseLeave
write
FOnMouseLeave;
property
OnURLClick : TClickEvent
read
FOnURLClick
write
FOnURLClick;
end
;
Komponent będzie posiadał standardową właściwość URL, określającą adres strony, która ma zostać otwarta.
Zdarzenia
OnMouseEnter
oraz
OnMouseLeave
będą występowały w momencie umieszczenia kursora myszy nad
obiektem lub przemieszczenia kursora znad obiektu. Dodatkowe zdarzenie
OnURLClick
wystąpi, gdy użytkownik
kliknie odnośnik. Będzie ono przekazywało do programu współrzędne pozycji kursora X i Y, pobrane w
momencie naciśnięcia przycisku myszy.
Komunikaty
Do przechwycenia momentu umieszczenia kursora nad obiektem niezbędne będzie skorzystanie z
komunikatów, a ściślej mówiąc z
CM_MOUSEENTER
oraz
CM_MOUSELEAVE
.
procedure
TURLabel.
CMMouseEnter
(
var
Msg : TMessage
)
;
begin
{ jeżeli wykorzystane jest zdarzenie FOnMouseEnter ? wywołaj je }
if
Assigned
(
FOnMouseEnter
)
then
OnMouseEnter
(
Self
)
;
FDefaultFontColor := Font.
Color
;
// pobierz do zmiennej kolor czcionki
FDefaultFontStyle := Font.
Style
;
// pobierz styl czcionki (pogrubiony, podkreślony)
Cursor := crHandPoint;
// zmień kursor
Font.
Color
:= clBlue;
// zmień kolor czcionki
Font.
Style
:= Font.
Style
+
[
fsUnderline
]
;
// dodaj podkreślenie
end
;
procedure
TURLabel.
CmMouseLeave
(
var
Msg : TMessage
)
;
5 z 14
2009-03-14 15:49
Plik z chomika:
Wiewioor
Inne pliki z tego folderu:
Delphi __ Kompendium __ Roz1.pdf
(1299 KB)
Delphi __ Kompendium __ Roz10.pdf
(777 KB)
Delphi __ Kompendium __ Roz11.pdf
(1764 KB)
Delphi __ Kompendium __ Roz12.pdf
(834 KB)
Delphi __ Kompendium __ Roz13.pdf
(1951 KB)
Inne foldery tego chomika:
■ePub
A.B Strugaccy
Ann Rice - Śpiąca królewna
Ćwiek Jakub
Ebooki-EPUB-PL-MegaPack
Zgłoś jeśli
naruszono regulamin