-
DalÜφ komponentou, kterou se budeme zab²vat je komponenta TChart
(na Palet∞ komponent najdeme dalÜφ dv∞ verze tΘto komponenty TDBChart
a TQRChart; tyto verze se pou₧φvajφ obdobn∞, ale zatφm je nebudeme
pou₧φvat). Komponenta op∞t umo₧≥uje vytvß°et grafy. Po umφst∞nφ tΘto komponenty
na formulß° m∙₧eme zahßjit vytvß°enφ grafu. V mφstnφ nabφdce komponenty
TChart
zvolφme Edit Chart. Je zobrazen Editor grafu. Nynφ ji₧ m∙₧eme editovat
graf, definovat a zapl≥ovat jeho datovΘ sΘrie.
Editor grafu vypadß takto:
Strßnka Chart (z vn∞jÜφch strßnek) Editoru grafu obsahuje definujφcφ
informace pro graf. Jsou r∙znΘ mo₧nosti definovßnφ obecn²ch a specifick²ch
parametr∙ grafu. N∞kterΘ parametry nem∙₧eme zadßvat dokud nejsou definovanΘ
sΘrie dat v grafu. Nap°. se pokuste modifikovat parametr Title a
uvidφte, ₧e se ihned zm∞nφ v grafu. Ne ale vÜechny zm∞ny vidφme v grafu
ihned.
Nejprve se tedy budeme zab²vat p°idßvßnφm sΘriφ. Stiskneme tlaΦφtko
Add
na strßnce Series (na vn∞jÜφ strßnce Chart). Je zobrazena
galerie typ∙ graf∙. Vybereme jeden pro p°idßnφ do naÜeho grafu (pozd∞ji
jej budeme moci zm∞nit, pokud budeme po₧adovat jin² zp∙sob zobrazenφ dat)
a stiskneme OK. Typ sΘrie je automaticky p°idßn k naÜemu grafu.
V Editoru grafu vidφme p°idanou novou konfiguraci pro novou sΘrii.
Po p°idßnφ sΘrie do grafu jsou takΘ p°idßny n∞kterΘ nßhodnΘ hodnoty,
kterΘ jsou zobrazeny v grafu (jsou viditelnΘ pouze p°i nßvrhu). Pokud nynφ
p°elo₧φme naÜi aplikaci, pak uvidφme prßzdn² graf.
Je tedy zapot°ebφ p°idat data k sΘrii. Tato Φinnost se liÜφ pro TDBChart
a nebudeme se jφ zatφm zab²vat. P°edpoklßdejme, ₧e na formulß°i mßme komponentu
TChart
s p°idanou sΘriφ. Nynφ se pokusφme zaplnit sΘrii programov∞. Budeme p°edpoklßdat,
₧e mßme sΘrii Pie (s implicitnφm jmΘnem Series1). Na formulß°
umφstφme tlaΦφtko a vytvo°φme obsluhu jeho stisknutφ s k≤dem:
Series1->Add(40, "Pencil", clRed);
Series1->Add(60, "Paper", clBlue);
Series1->Add(30, "Ribbon", clGreen);
Popis metody Add a dalÜφch pot°ebn²ch metod a vlastnostφ je
dostupn² v nßpov∞d∞. NaÜi aplikaci se pokusφme spustit a po stisknutφ tlaΦφtka
uvidφme zobrazenφ grafu, k≤d tedy pracuje.
B∞hem nßvrhu jsou vÜechny vlastnosti grafu a sΘriφ dostupnΘ v Inspektoru
objekt∙ nebo v Editoru grafu. Editace sΘrii nejsnadn∞ji provedeme v Editoru
grafu na strßnce Series. Pokuste se provΘst n∞kterΘ zm∞ny a uvidφte,
₧e se provedenΘ zm∞ny automaticky projevujφ v grafu. P°i nßvrhu nenφ dostupn²
nßÜ k≤d a pou₧φvajφ se tedy nßhodnß data. Abychom zjistili, jak se naÜe
zm∞ny projevφ za b∞hu, musφme aplikaci spustit.
Mnoho v∞cφ m∙₧eme vy°eÜit vizußln∞ v Editoru nebo m∙₧eme n∞kterΘ parametry
modifikovat v Inspektoru objekt∙. M∙₧eme je takΘ °eÜit k≤dem.
Pokuste se modifikovat aplikaci ze 4. a 5. zadßnφ p°edchozφ kapitoly
tak, aby se mφsto komponenty ChartFX pou₧φvala komponenta TChart.
Vφce se touto komponentou nebudeme zab²vat.
-
Pro zadßvßnφ datum∙ a Φas∙ lze pou₧φt komponentu TDateTimePicker.
Vlastnost DateMode urΦuje re₧im zobrazenφ ovladaΦe a vlastnost Kind
urΦuje zda ovladaΦ bude po₧φvßn pro datum nebo Φas. Umφst∞te tuto komponentu
na formulß° a vyzkouÜejte si jejφ pou₧itφ.
-
Komponenta TAnimate slou₧φ k p°ehrßvßnφ klip∙ AVI. Pracuje s nekomprimovan²mi
soubory AVI nebo klipy komprimovanΘ k≤dovßnφm RLE. Tato komponenta nepodporuje
zvuky u klip∙. Nßsledujφ n∞kterΘ vlastnosti tΘto komponenty:
-
ResHandle je madlo Windows modulu, kter² obsahuje klip AVI jako
zdroj. Vlastnost nastavujeme za b∞hu na madlo instance nebo modulu, kter²
obsahuje animaΦnφ zdroj. Po nastavenφ ResHandle nastavφme vlastnost
ResID
nebo ResName k indikaci, kter² zdroj v urΦenΘm modulu je po₧adovan²
klip.
-
Nastavφme AutoSize na true, pokud velikost ovladaΦe mß b²t
urΦovßna p°ehrßvan²m klipem.
-
StartFrame a StopFrame specifikujφ rßmce, kterΘ zahajujφ
a konΦφ klip.
-
CommonAVI m∙₧eme nastavit k zobrazovßnφ n∞kterΘho obecnΘho klipu
Windows poskytnutΘho v Shell32.DLL.
-
To zda animace b∞₧φ je urΦeno vlastnostφ Active a poΦet opakovßnφ
lze nastavit vlastnostφ Repetitions.
-
Vlastnost Timers umo₧≥uje zobrazovat rßmce pomocφ ΦasovaΦe. Je to
u₧iteΦnΘ pro synchronizaci animaΦnφ sekvence s ostatnφmi akcemi, jako je
p°ehrßvßnφ zvukovΘ stopy.
Pokuste se tuto komponentu pou₧φt v n∞kterΘ aplikaci.
-
Komponenta TSplitter rozd∞luje klientskou oblast formulß°e na Φßsti,
kterΘ mohou m∞nit velikost. Tuto komponentu p°idßvßme na formulß° mezi
dva zarovnanΘ ovladaΦe. Spliter je umφst∞n mezi ovladaΦem kter²
je zarovnßn s jednφm okrajem formulß°e a ovladaΦem, kter² zapl≥uje zbytek
klientskΘ oblasti. Pou₧itφ si ukß₧eme v nßsledujφcφ aplikaci.
ZaΦneme v²voj novΘ aplikace. Na formulß° umφstφme Panel, kter²
zarovnßme se spodnφm okrajem formulß°e. Dßle na formulß° p°idßme komponentu
TSplitter
u kterΘ musφme takΘ nastavit vlastnost Align na
alBottom.
Na formulß° p°idßme komponentu TDirectoryListBox, u kterΘ
vlastnost
Align nastavφme na alLeft, dalÜφ
komponentu
TSplitter (vlastnost
Align je zde ji₧ nastavena
na alLeft). Zb²vajφcφ plochu formulß°e zaplnφme komponentou TFileListBox
(Align nastavφme na alClient). Nynφ ji₧ aplikaci m∙₧eme vyzkouÜet.
Spustφme ji a pokusφme se m∞nit velikosti jednotliv²ch oblastφ formulß°e.
-
DalÜφ zajφmavou oblastφ C++ Builderu je podpora souborov²ch proud∙. Knihovna
VCL obsahuje abstraktnφ t°φdu TStream a jejφ t°i potomky: TFileStream,
THandleStream
a TMemoryStream. Pro nahrßvßnφ dat ze souboru a uklßdßnφ do souboru
m∙₧eme pou₧φt dva souborov∞ orientovanΘ proudy. THandleStream se
pou₧φvß v p°φpad∞, kdy ji₧ mßme madlo souboru. TFileStream pou₧ijeme,
kdy₧ mßme jen jmΘno souboru. T°etφ proudovou t°φdou je TMemoryStream,
kterß pracuje s pam∞tφ a nikoli se skuteΦn²m souborem. Tato t°φda vÜak
obsahuje specißlnφ metody pro kopφrovßnφ svΘho obsahu do nebo z jinΘho
proudu, kter² m∙₧e b²t souborov²m proudem. Proudy mohou nahradit tradiΦnφ
soubory. Jejich velkou v²hodou je nap°. to, ₧e m∙₧eme pracovat s pam∞¥ov²mi
proudy, a potom je ulo₧it do souboru. Tφmto zp∙sobem lze zv²Üit rychlost
programu intenzivn∞ pracujφcφho se soubory.
ZvlßÜt∞ d∙le₧itou vlastnostφ proud∙ je jejich schopnost p°enßÜet komponenty.
VÜechny t°φdy knihovny VCL jsou potomci TPersistent, specißlnφ t°φdy
umo₧≥ujφcφ uklßdßnφ objekt∙ do proud∙ a obsahujφ metody pro uklßdßnφ a
nahrßvßnφ vÜech vlastnostφ a ve°ejn²ch polo₧ek. Proto mohou vÜichni potomci
t°φdy
TComponent uklßdat sami sebe do proudu nebo mohou b²t nahrßnφm
z proudu automaticky vytvo°eni. Program k tomu m∙₧e vyu₧φvat metod proudu
WriteComponent
a ReadComponent. Proudy v zßsad∞ nev∞dφ nic o Φtenφ nebo zßpisu
komponent. Metody t°φd TStream jednoduÜe pou₧φvajφ dv∞ jinΘ t°φdy:
TReader
a TWriter, ob∞ potomky t°φdy TFiler. Objekty
TReader
a TWriter pou₧φvajφ proud, ke kterΘmu se vztahujφ a jsou schopnΘ
mu p°id∞lit specißlnφ znaΦky pro provedenφ kontroly datovΘho formßtu. Objekt
TWriter
m∙₧e ulo₧it znaΦku komponenty, potom ulo₧it komponentu, vÜechny jejφ vlastnosti
a vÜechny komponenty, kterΘ obsahuje. Obsahuje metodu WriteRootComponent,
kterß ulo₧φ komponentu p°edanou jako parametr a takΘ vÜechny komponenty,
kterΘ obsahuje. Podobn∞ t°φda
TReader obsahuje metodu ReadRootComponent,
kterß je schopnß vytvo°it novΘ objekty s vyu₧itφm informace o t°φdßch ulo₧en²ch
v proudu. To je mo₧nΘ pod jednou podmφnkou: nßzev komponenty musφ b²t aplikacφ
registrovßn (funkcφ
RegisterClasses).
Vra¥me se ale ke konkrΘtnφ aplikaci. ZaΦneme v²vojem novΘ aplikace.
Formulß° tΘto aplikace je jednoduch². Na hornφ okraj formulß°e vlo₧φme
komponentu Panel (zruÜφme jeho titulek) a na nφ vlo₧φme t°i voliΦe
s texty Label, Edit a Button (prvnφ z nich nastavφme).
P°i kliknutφ myÜφ na formulß°i, vytvo°φme komponentu urΦenou vybran²m voliΦem.
P°ed deklaraci typu formulß°e vlo₧φme deklaraci v²ΦtovΘho typu
enum Typ {Label,
Edit, ButtonX};
popisujφcφ vybran² voliΦ a do soukromΘ Φßsti deklarace formulß°e umφstφme:
int Citac;
Typ Odkaz;
Vytvo°te obsluhy kliknutφ na voliΦφch tak, aby v polo₧ce Odkaz
byla ulo₧ena informace o vybranΘm voliΦi. Dßle vytvo°φme obsluhu OnCreate
formulß°e s t∞mito p°φkazy:
Odkaz = Label;
Citac = 0;
Po vytvo°enφ obsluhy OnMouseDown formulß°e ji₧ m∙₧eme aplikaci
vyzkouÜet. Tuto obsluhu tvo°φ p°φkazy:
TControl *Objekt;
AnsiString Nazev;
switch (Odkaz) {
case Label:
Objekt = new TLabel(this); break;
case Edit:
Objekt = new TEdit(this); break;
case ButtonX:
Objekt = new TButton(this); break;
}
Objekt->Parent =
this;
Objekt->Left = X;
Objekt->Top = Y;
Citac++;
Nazev = String(Objekt->ClassName())
+ IntToStr(Citac);
Nazev.Delete(1, 1);
Objekt->Name = Nazev;
Objekt->Visible =
true;
Klikßnφm myÜi na formulß°i vytvß°φme komponenty urΦenΘ vybran²m voliΦem.
VyzkouÜejte.
-
TΘto aplikaci dßle umo₧nφme uklßdßnφ vlo₧en²ch komponent do souboru a jejich
op∞tovnΘmu nahrßnφ ze souboru. K aplikaci p°idßme nabφdku Soubor
s volbami: ZruÜit, Otev°φt, Ulo₧it jako a Konec.
P°idßme takΘ komponenty OpenDialog a SaveDialog (kde nastavφme
vhodnΘ vlastnosti; u naÜich soubor∙ budeme pou₧φvat p°φponu CMP).
Tyto komponenty musφme vlo₧it na ji₧ pou₧itou komponentu Panel.
Obsluhu volby ZruÜit tvo°φ p°φkazy (zruÜφme vÜechny komponenty mimo
komponent vlo₧en²ch na panel):
for (int I = ControlCount-1;
I >= 0; I--)
if (String(Controls[I]->ClassName())
!= "TPanel") Controls[I]->Free();
Citac = 0;
Komponenty uklßdanΘ do proudu musφme registrovat a tedy do obsluhy
OnCreate
formulß°e p°idßme p°φkazy:
TComponentClass classes[3]
=
{__classid(TEdit), __classid(TLabel), __classid(TButton)};
RegisterClasses(classes,
2);
Vytvo°φme jeÜt∞ obsluhu volby Ulo₧it jako. Tvo°φ ji p°φkazy:
if (SaveDialog1->Execute()){
TFileStream
*S;
S = new TFileStream(SaveDialog1->FileName,
fmOpenWrite | fmCreate);
for (int I
= 0; I < ControlCount; I++)
if (String(Controls[I]->ClassName()) != "TPanel")
S->WriteComponent(Controls[I]);
delete S;
}
Obsluhu volby Otev°φt tvo°φ:
if (OpenDialog1->Execute())
{
TFileStream
*S;
TComponent
*Novy;
Zruit1Click(this);
S = new TFileStream(OpenDialog1->FileName,
fmOpenRead);
while (S->Position
< S->Size){
Novy = S->ReadComponent(NULL);
InsertControl(dynamic_cast<TControl *> (Novy));
Citac++;
}
delete S;
}
Zb²vajφcφ obsluhy vytvo°te sami. Aplikaci vyzkouÜejte.
-
JeÜt∞ se seznßmφme s klφΦov²mi slovy C++ p°idan²mi do C++
Builderu pro podporu VCL.
Operßtor __classid je pou₧φvßn p°ekladaΦem pro
generovßnφ ukazatele na vtable (tabulka virtußlnφch metod) pro specifikovanou
t°φdu. Tento operßtor byl takΘ pou₧it v p°edchozφm p°φklad∞. Syntaxe:
__classid(classname)
Nap°. __classid pou₧φvßme p°i registraci editoru
vlastnosti, komponenty nebo t°φdy a s metodou InheritsFrom t°φdy
TObject.
KlφΦovΘ slovo __closure je pou₧φvßno k deklarovßnφ
specißlnφho typu ukazatele na metodu. Na rozdφl od normßlnφho ukazatele
na funkci, tento ukazatel obsahuje i ukazatel na objekt. Ve standardnφm
C++ m∙₧eme p°i°adit instanci odvozenΘ t°φdy ukazateli na zßkladnφ t°φdu,
ale nem∙₧eme p°i°adit metodu odvozenΘ t°φdy ukazateli na metodu zßkladnφ
t°φdy. Ukazuje to nßsledujφcφ p°φklad:
class
base
{
public:
void
func(int x);
};
class
derived: public base
{
public:
void
new_func(int i);
};
void
(base::*bptr)(int);
bptr
= &derived::new_func; // nedovoleno
JazykovΘ rozÜφ°enφ __closure umo₧≥uje toto v C++
Builderu provΘst. Closure p°i°azuje ukazatel na metodu k ukazateli na instanci
t°φdy. Ukazatel na instanci t°φdy je pou₧it jako ukazatel this,
kdy₧ volßme p°i°azenou metodu. Deklarace Closure je stejnß jako deklarace
ukazatele na funkci, ale p°ed identifikßtorem funkce je uvedeno klφΦovΘ
slovo __closure. Nap°.
struct
MyObject
{
double MemFunc(int);
};
double
func1(MyObject *obj)
{
double ( __closure *myClosure )(int);
// Inicializace Closure.
myClosure = obj -> MemFunc;
// Pou₧itφ Closure k volßnφ metody.
return myClosure(1);
}
V C++ Builderu jsou Closure pou₧φvßny s udßlostmi.
KlφΦovΘ slovo __property deklaruje v deklaraci
t°φdy vlastnost. Vlastnosti mohou b²t deklarovßny pouze ve t°φdßch. Pro
pole vlastnostφ, index pole m∙₧e b²t libovolnΘho typu. Syntaxe:
<property
declaration> ::=
__property <type> <id> [ <prop dim list> ]="{" <prop attrib
list> "}"
<prop dim list> ::= "[" <type> [ <id> ] "]" [ <prop dim list>
]
<prop attrib list> ::= <prop attrib> [ , <prop attrib list> ]
<prop attrib> ::= read = <data/function id>
<prop attrib> ::= write = <data/function
id>
<prop attrib> ::= stored = <data/function
id>
<prop attrib> ::= stored = <boolean constant>
<prop attrib> ::= default = <constant>
<prop attrib> ::= nodefault
<prop attrib> ::= index = <const int expression>
Vlastnosti majφ n∞kolik slu₧eb, Φφm₧ se odliÜujφ od datov²ch
slo₧ek. Vlastnosti mohou mφt:
-
P°i°azeny Φtecφ a zßpisovΘ metody.
-
Nastavenu implicitnφ hodnotu.
-
B²t ulo₧eny v souboru formulß°e.
-
RozÜi°ovat vlastnost definovanou v zßkladnφ t°φd∞.
KlφΦovΘ slovo __published specifikuje, ₧e vlastnosti
v tΘto sekci jsou zobrazeny v Inspektoru objekt∙. Sekci __published
mohou mφt pouze t°φdy odvozenΘ od TObject. Pravidla viditelnosti
pro zve°ej≥ovanΘ slo₧ky jsou stejnΘ jako pro ve°ejnΘ slo₧ky. Jedin² rozdφl
mezi zve°ej≥ovan²mi a ve°ejn²mi slo₧kami je ten, ₧e u zve°ej≥ovan²ch slo₧ek
jsou generovßny informace RTTI. To umo₧≥uje aplikacφm dynamickΘ dotazy
na slo₧ky, metody a vlastnosti.
-
N∞kolik parametr∙ klφΦovΘho slova __declspec poskytuje
jazykovou podporu pro VCL. Nßsleduje popis t∞chto parametr∙.
Parametr delphiclass je pou₧it pro deklarovßnφ
t°φd odvozen²ch od TObject. Tyto t°φdy jsou vytvo°eny tak, aby byly
kompatibilnφ s VCL.
Parametr delphireturn je pou₧it pro deklarovßnφ
t°φd, kterΘ vytvß°φme v C++ Builderu pro podporu zabudovan²ch datov²ch
typ∙ a jazykov²ch konstrukcφ Object Pascalu, kterΘ nejsou p°irozenΘ v C++.
To zahrnuje Currency,
AnsiString,
Variant,
TDateTime
a Set. Parametr
delphireturn oznaΦuje t°φdy C++ pro VCL kompatibilnφ
zpracovßnφ volßnφ funkcφ (parametry a nßvratovΘ hodnoty). Tento modifikßtor
je zapot°ebφ, kdy₧ p°edßvßme strukturu funkci hodnotou mezi Object Pascalem
a C++.
Parametr dynamic je pou₧φvßn pro deklarovßnφ dynamick²ch
funkcφ. DynamickΘ funkce se podobajφ virtußlnφm, ale jsou jinak ulo₧enΘ.
Parametr hidebase chrßnφ sΘmantiku programu Object
Pascalu p°i p°edßvßnφ virtußlnφch a p°ekryt²ch funkcφ C++ Builderu. V Object
Pascalu, virtußlnφ funkce v zßkladnφ t°φd∞ mohou b²t zobrazeny v odvozenΘ
t°φd∞ jako funkce se stejn²m jmΘnem, ale mohou b²t chßpßny jako kompletn∞
novΘ funkce bez explicitnφho vztahu k p°edchozφ funkci. P°ekladaΦ pou₧φvß
makro HIDESBASE, k specifikaci, ₧e tyto typy deklaracφ funkcφ jsou kompletn∞
samostatnΘ. Nap°. jestli₧e zßkladnφ t°φda T1 deklaruje virtußlnφ bezparametrickou
funkci func a odvozenß t°φda T2 deklaruje funkci se stejn²m jmΘnem
a signaturou, pak DCC32 vytvß°φ hlaviΦkov² soubor s nßsledujφcφm prototypem:
virtual
void T1::func(void);
HIDESBASE
void T2::func(void);
Bez HIDESBASE, sΘmantika C++ indikuje, ₧e virtußlnφ funkce
T1::func
bude p°epsßna T2::func.
Parametr package indikuje, ₧e k≤d definice t°φdy
bude p°elo₧en do balφΦku. Parametr pascalimplementation indikuje,
₧e k≤d definice t°φdy bude implementovßn v Object Pascalu.