Registrovanou komponentu instalujeme na Paletu komponent
a potom ji m∙╛eme vybφrat, umis╗ovat ji na formulß° a manipulovat s nφ
p°i nßvrhu. Ud∞lßnφ na╣φ komponenty dostupnΘ b∞hem nßvrhu vy╛aduje n∞kolik
krok∙:
Ne v╣echny tyto kroky vy╛aduje ka╛dß komponenta. Nap°. jestli╛e
nedefinujeme ╛ßdnou novou vlastnost nebo udßlost, pak nenφ nutnΘ poskytnout
pro nφ nßpov∞du. V╛dy je pouze zapot°ebφ provΘst registraci a p°eklad.
Kdy╛ ji╛ komponenty mßme registrovanΘ a p°elo╛enΘ do
balφΦk∙, pak je m∙╛eme distribuovat ostatnφm v²vojß°∙m a instalovat v IDE.
Registrace komponenty
Registrace pracuje na zßklad∞ jednotky a tedy, pokud vytvß°φme
n∞kolik komponent v jednΘ jednotce, pak je registrujeme v╣echny najednou.
Kdy╛ ji╛ mßme komponenty v jednotce registrovßny, m∙╛eme p°elo╛it jednotku
do nßvrhovΘho balφΦku, kter² m∙╛eme instalovat v IDE.
Pro registraci komponenty, p°idßme funkci Register
do CPP souboru jednotky. V tΘto funkci registrujeme komponenty a urΦφme,
kde na Palet∞ komponent budou instalovßny.
Kroky pro ruΦnφ registraci komponenty jsou:
Deklarovßnφ funkce Register
Funkce Register musφ existovat ve jmennΘm prostoru.
Jmenn² prostor je jmΘno souboru komponent, kde s v²jimkou prvnφho pφsmena
jsou v╣echna pφsmena malß.
Nßsledujφcφ kostra k≤du ukazuje jak funkce Register
je implementovßna ve jmennΘm prostoru. Jmenn² prostor je nazvßn Novakomp,
zatφmco soubor se jmenuje NovaKomp.CPP.
namespace Novakomp
{
void __fastcall PACKAGE Register()
{
}
}
Poznßmka: Pokud
vytvß°φme na╣φ komponentu volbou Component | New Component z hlavnφ
nabφdky IDE, pak k≤d registrujφcφ na╣φ komponentu je p°idßn automaticky.
Uvnit° funkce Register volßme RegisterComponents
pro v╣echny komponenty, kterΘ chceme p°idat na Paletu komponent. Makro
PACKAGE je roz╣φ°eno na p°φkazy, kterΘ umo╛≥ujφ importovßnφ a exportovßnφ
t°φd.
Zßpis funkce Register
Uvnit° funkce Register pro jednotku komponent, musφme
registrovat v╣echny komponenty, kterΘ chceme p°idat na Paletu komponent.
Pokud jednotka obsahuje vφce komponent, pak je registrujeme v╣echny najednou.
K registraci komponent volßme funkci RegisterComponents
a
to jednou pro ka╛dou strßnku Palety komponent, na kterou chceme p°idßvat
komponenty. Funkce RegisterComponents provßdφ dv∞ d∙le╛itΘ v∞ci:
specifikuje jmΘna komponent a specifikuje strßnku palety na kterou komponenty
instalujeme.
Uvnit° funkce Register deklarujeme otev°enΘ pole
typu TComponentClass, kterΘ obsahuje informace o registrovan²ch
komponentßch. Pou╛φvßme tuto syntaxi:
TComponentClass classes[1] = {__classid(TNovaKomponenta)};
V tomto p°φpad∞ pole t°φd obsahuje prßv∞ jednu komponentu,
ale do jednoho pole m∙╛eme vlo╛it v╣echny komponenty, kterΘ chceme registrovat.
Nap°. nßsledujφcφ k≤d do pole umis╗uje dv∞ komponenty:
TComponentClass classes[2] =
{__classid(TNovaKomponenta),
__classid(TJinaKomponenta)};
Jin²m zp∙sobem p°idßvßnφ komponent do pole je p°i°azovßnφ
komponent do pole v samostatn²ch p°φkazech. Nap°. nßsledujφcφ p°φkazy p°idßvajφ
do pole stejnΘ dv∞ komponenty jako v p°edchozφm p°φklad∞:
TComponentClass classes[2];
classes[0] = __classid(TNovaKomponenta);
classes[1] = __classid(TJinaKomponenta);
JmΘno strßnky palety je typu AnsiString. Jestli╛e
strßnka palety zadanΘho jmΘna zatφm neexistuje, pak C++ Builder vytvß°φ
novou strßnku s tφmto jmΘnem. C++ Builder hledß jmΘna standardnφch strßnek
ve zdroji seznamu °et∞zc∙, co╛ umo╛≥uje, aby internacionalizovanß verze
C++ Builderu mohla mφt jmΘna strßnek ve svΘm p°irozenΘm jazyku. Pokud chceme
instalovat komponentu na n∞kterou ze standardnφch strßnek, pak musφme zφskat
°et∞zec pro jmΘno strßnky volßnφm funkce LoadStr a p°edßme konstantu
reprezentujφcφ zdroj °et∞zce pro tuto strßnku, nap°. srSystem pro
strßnku System.
Uvnit° funkce Register volßme RegisterComponents
k registraci komponent v poli t°φd. RegisterComponents je funkce
p°ebφrajφcφ t°i parametry: jmΘno strßnky Palety komponent, pole t°φd komponent
a index poslednφho prvku v poli. Nßsledujφcφ funkce Register obsa╛enß
v souboru NOVAKOMP.CPP, registruje komponentu nazvanou TMojeKomponenta
a umis╗uje ji na strßnku Palety komponent nazvanou "R∙znΘ".
namespace Novakomp
{
void __fastcall PACKAGE Register()
{
TComponentClass
classes[1] = {__classid(TMojeKomponenta)};
RegisterComponents("R∙znΘ",
classes, 0);
}
}
Pov╣imn∞te si, ╛e t°etφ parametr ve volßnφ RegisterComponents
je 0, co╛ je index poslednφho prvku v poli t°φd (velikost pole minus 1).
M∙╛eme takΘ registrovat n∞kolik komponent na stejnΘ strßnce
najednou nebo registrovat komponenty na r∙zn²ch strßnkßch.
V nßsledujφcφm p°φklad∞ jsou deklarovanΘ dv∞ pole: classes1
a classes2. V prvnφm volßnφ RegisterComponents, classes1
mß dva prvky a t°etφ parametr je index druhΘho prvku, co╛ je 1. V druhΘm
volßnφ RegisterComponents, classes2 mß jeden prvek a t°etφ
parametr je 0.
namespace Mojekomp
{
void __fastcall PACKAGE Register()
{
// deklarace pole pro
dv∞ komponenty
TComponentClass classes1[2]
= {__classid(TPrvni), __classid(TDruha)};
// p°idßnφ novΘ palety
se dv∞mi komponentami
RegisterComponents("R∙znΘ",
classes1, 1);
// deklarace druhΘho pole
TComponentClass classes2[1];
// p°i°azenφ komponenty
prvnφmu prvku v poli
classes2[0] = __classid(TTreti);
// p°idßnφ komponenty
na strßnku Samples
RegisterComponents("Samples",
classes2, 0);
}
}
P°idßnφ bitovΘ mapy zobrazenΘ na palet∞
Ka╛dß komponenta vy╛aduje bitovou mapu reprezentujφcφ komponentu
na Palet∞ komponent. Jestli╛e nespecifikujeme svou vlastnφ bitovou mapu,
pak C++ Builder pou╛ije implicitnφ. Jeliko╛ bitovΘ mapy palety jsou pot°ebnΘ
pouze b∞hem nßvrhu, nejsou p°elo╛eny v jednotce komponenty. Jsou v souboru
zdroj∙ Windows se stejn²m jmΘnem jako mß jednotka, ale s p°φponou DCR (Design-time
Component Resource). Tento soubor zdroj∙ m∙╛eme vytvo°it pomocφ Editoru
obrßzk∙ v C++ Builderu. Ka╛dß bitovß mapa je Φtverec o stran∞ 24 bod∙.
Pro ka╛dou jednotku, kterou chceme instalovat, pot°ebujeme
soubor DCR a v ka╛dΘm souboru DCR pot°ebujeme bitovou mapu pro ka╛dou registrovanou
komponentu. Obraz bitovΘ mapy mß stejnΘ jmΘno jako komponenta. Soubor DCR
musφ b²t ve stejnΘm adresß°i jako jednotka komponenty, C++ Builder zde
tento soubor hledß, kdy╛ instaluje komponenty na paletu.
Nap°. jestli╛e vytvo°φme komponentu nazvanou TMujOvladac
v jednotce nazvanΘ ToolBox, musφme vytvo°it soubor zdroj∙ nazvan²
TOOLBOX.DCR,
kter² obsahuje bitovou mapu nazvanou TMUJOVLADAC. Ve jmΘnech zdroj∙
nezßle╛φ na velikostφ pφsmen, ale podle konvence je obvykle zapisujeme
velk²mi pφsmeny.
Poskytnutφ nßpov∞dy
pro na╣i komponentu
Kdy╛ vybereme komponentu na formulß°i, p°φpadn∞ vlastnost
nebo udßlost v Inspektoru objekt∙, pak m∙╛eme stisknutφm F1 zφskat informaci
o tomto prvku. U╛ivatelΘ na╣ich komponent mohou zφskat informace o na╣φ
komponent∞, jestli╛e vytvo°φme p°φslu╣nΘ soubory nßpov∞dy.
M∙╛eme poskytnout mal² soubor nßpov∞dy s informacemi
o na╣ich komponentßch a u╛ivatelΘ mohou nalΘzt na╣i dokumentaci bez nutnosti
n∞jakΘho specißlnφho kroku. Na╣e nßpov∞da se stane Φßstφ nßpov∞dnΘho systΘmu
C++ Builderu.
Pro poskytnutφ kontextovΘ nßpov∞dy pro na╣i komponentu
provedeme nßsledujφcφ kroky: Vytvo°φme polo╛ky nßpov∞dy, ud∞lßme polo╛ky
kontextov∞ senzitivnφ a p°idßme nßpov∞du k nßpov∞d∞ C++ Builderu.
K vytvo°enφ souboru nßpov∞dy m∙╛eme pou╛φt libovoln²
nßstroj. C++ Builder obsahuje Microsoft Help Workshop, kter² m∙╛eme pou╛φt
k vytvo°enφ na╣eho nßpov∞dnΘho souboru.
Aby nß╣ soubor nßpov∞dy byl integrovateln² do nßpov∞dy
knihovny komponent, je nutno dodr╛ovat nßsledujφcφ konvence:
-
Ka╛dß komponenta musφ mφt prvek nßpov∞dy. Prvek nßpov∞dy
komponenty obsahuje struΦn² popis komponenty. Prvek nßpov∞dy komponenty
musφ obsahovat vazby na sekundßrnφ okna, kterΘ popisujφ pozici komponenty
v objektovΘ hierarchii a kterΘ obsahujφ seznamy v╣ech vlastnostφ, udßlostφ
a metod dostupn²ch pro u╛ivatele komponenty. V²vojß° aplikace zp°φstup≥uje
tento prvek nßpov∞dy v²b∞rem komponenty na formulß°i a stiskem klßvesy
F1. Prvek nßpov∞dy musφ mφt poznßmku pod Φarou # s unikßtnφ hodnotou pro
prvek. Poznßmka pod Φarou # jednoznaΦn∞ identifikuje ka╛d² prvek v nßpov∞dnΘm
systΘmu.
Prvek nßpov∞dy komponenty musφ mφt poznßmku pod Φarou
"K"
pro vyhledßvßnφ klφΦov²ch slov, kterß obsahuje jmΘno t°φdy komponenty.
Nap°. poznßmka pod Φarou klφΦovΘho slova pro komponentu TMemo je
"TMemo".
Prvek nßpov∞dy komponenty musφ mφt takΘ poznßmku pod Φarou
"$",
kterß poskytuje titulek prvku. Titulek se zobrazuje v dialogovΘm okn∞ Topics
Found, dialogovΘm okn∞ Bookmark a okn∞ History.
-
Ka╛dß komponenta musφ mφt sekundßrnφ navigaΦnφ prvky nßpov∞dy.
Jednß se o:
-
Prvek hierarchie s vazbami na ka╛dΘho p°edka komponenty v
hierarchii komponent.
-
Seznam v╣ech vlastnostφ dostupn²ch v komponent∞, s vazbami
na prvky popisujφcφ tyto vlastnosti.
-
Seznam v╣ech udßlostφ dostupn²ch v komponent∞, s vazbami
na prvky popisujφcφ tyto udßlosti.
-
Seznam metod dostupn²ch v komponent∞, s vazbami na prvky
popisujφcφ tyto metody.
Vazby na objekty t°φd, vlastnostφ, metod nebo udßlostφ v
nßpov∞dnΘm systΘmu C++ Builderu mohou b²t provedeny pomocφ Alink.
Kdy╛ se odkazujeme na objekt t°φdy, pak Alink pou╛φvß jmΘno objektu
t°φdy, nßsledovanΘ podtr╛enφm a °et∞zcem "object". Nap°. k vazb∞
na objekt TCustomPanel pou╛ijeme:
!AL(TCustomPanel_object,1)
U vazeb na vlastnost, metodu nebo udßlost, p°edchßzφ
jmΘno vlastnosti, metody nebo udßlosti jmΘno t°φdy, kterß ji implementuje
a podtr╛enφ. Nap°. k vazb∞ na vlastnost Text, kterß je implementovanß
TControl
pou╛ijeme:
!AL(TControl_Text,1)
Abychom vid∞li p°φklad sekundßrnφch navigaΦnφch prvk∙,
zobrazφme prvek nßpov∞dy n∞jakΘ komponenty a klikneme na vazbu popsanou
?hierarchy?,
?properties?,
?methods?
nebo ?events?.
-
Ka╛dß vlastnost, udßlost a metoda, kterß je deklarovßna
v komponent∞ musφ mφt nßpov∞dn² prvek. Prvek nßpov∞dy vlastnosti, udßlosti
nebo metody zobrazuje deklaraci prvku a popisuje jeho pou╛φvßnφ. V²vojß°
aplikace vidφ tyto prvky po jejich v²b∞ru v Inspektoru objekt∙ a stisku
F1 nebo umφst∞nφm textovΘho kurzoru v Editoru k≤du na jmΘno prvku a stiskem
F1.
Prvek nßpov∞dy pro vlastnost, udßlost nebo metodu musφ
obsahovat poznßmku pod Φarou "K" se jmΘnem vlastnosti, metody nebo
udßlosti a toto jmΘno v kombinaci se jmΘnem komponenty. Tedy vlastnost
TextTControl
mß nßsledujφcφ "K" poznßmku pod Φarou:
Text,TControl;TControl,Text;Text,
Prvek nßpov∞dy vlastnosti, metody a udßlosti musφ mφt
takΘ poznßmku pod Φarou "$", kterß urΦuje titulek prvku, nap°. ?TControl::Text?.
V╣echny tyto prvky nßpov∞dy musφ mφt unikßtnφ ID prvku,
zadanΘ jako poznßmka pod Φarou #.
Ka╛d² prvek nßpov∞dy komponenty, vlastnosti, metody a udßlosti
musφ mφt poznßmku pod Φarou "A". Tato poznßmka je pou╛ita k zobrazenφ
prvku, kdy╛ u╛ivatel vybere komponentu a stiskne F1 nebo kdy╛ vlastnost
nebo udßlost je vybrßna v Inspektoru objekt∙ a u╛ivatel stiskne F1. Poznßmka
pod Φarou "A" musφ spl≥ovat tyto konvence.
Pokud prvek nßpov∞dy je pro t°φdu komponenty, pak poznßmka
pod Φarou obsahuje dv∞ polo╛ky odd∞lenΘ st°ednφkem p°i pou╛itφ tΘto syntaxe:
ComponentClass_Object;ComponentClass
kde ComponentClass je jmΘno t°φdy komponenty.
Pokud prvek nßpov∞dy je pro vlastnost nebo udßlost, pak
poznßmka pod Φarou "A" obsahuje t°i polo╛ky odd∞lenΘ st°ednφky p°i
pou╛itφ tΘto syntaxe:
ComponentClass_Element;Element_Type;Element
kde ComponentClass je jmΘno t°φdy komponenty,
Element
je jmΘno vlastnosti, metody nebo udßlosti a Type je Property,
Method
nebo Event.
Nap°. pro vlastnost nazvanou BackgroundColor komponenty
nazvanΘ
TMyGrid tato poznßmka pod Φarou je:
TMyGrid_BackgroundColor;BackgroundColor_Property;BackgroundColor
Pro p°idßnφ na╣eho nßpov∞dnΘho souboru k nßpov∞dnΘmu
souboru C++ Builderu pou╛ijeme utilitu OpenHelp, kterou zp°φstupnφme
volbou Help | Customize.
P°idßnφ editor∙ vlastnostφ
Inspektor objekt∙ poskytuje mo╛nost editace pro v╣echny typy
vlastnostφ. NicmΘn∞ m∙╛eme poskytnout alternativnφ editor pro konkrΘtnφ
vlastnost zßpisem a registracφ editoru vlastnosti. M∙╛eme registrovat editor
vlastnosti, kter² lze pou╛φt pouze na vlastnosti ve vytvß°enΘ komponent∞,
ale m∙╛eme takΘ vytvo°it editor, kter² lze pou╛φt na v╣echny vlastnosti
jistΘho typu.
V nejjednodu╣╣φ ·rovni editor vlastnosti m∙╛e operovat
jednφm nebo ob∞ma z t∞chto zp∙sob∙: zobrazovat a zp°φstupnit k editovßnφ
u╛ivateli souΦasnou hodnotu jako textov² °et∞zec a zobrazit dialogovΘ okno
provßd∞jφcφ n∞kterΘ typy editace. V zßvislosti na editovanΘ vlastnosti
je u╛iteΦnΘ poskytnout jeden nebo oba zp∙soby.
Zßpis editoru vlastnosti vy╛aduje p∞t krok∙:
-
Odvozenφ t°φdy
editoru vlastnosti
-
Editace vlastnosti
jako text
-
Editace vlastnosti
jako celek
-
Specifikaci atribut∙
editoru
-
Registrace editoru
vlastnosti.
Odvozenφ t°φdy editoru vlastnosti
Soubor DSGNINTF.HPP definuje n∞kolik typ∙ editor∙ vlastnosti,
v╣echny jsou odvozeny od TPropetryEditor. Kdy╛ vytvß°φme editor
vlastnosti, m∙╛eme t°φdu editoru vlastnosti odvodit p°φmo od TPropertyEditor
nebo nep°φmo od jednoho z typ∙ editor∙ vlastnosti popsan²ch v dal╣φ tabulce
(odvozujeme nov² objekt od jednoho z existujφcφho typu editoru vlastnosti).
Soubor DSGNINTF.HPP takΘ definuje n∞kterΘ velmi specializovanΘ editory
vlastnostφ pou╛φvanΘ pro unikßtnφ vlastnosti jako je nap°. jmΘno komponenty.
Typ |
Edituje vlastnosti |
TOrdinalProperty |
Zßklad pro v╣echny editory vlastnostφ ordinßlnφch typ∙
(celoΦφselnΘ, znakovΘ a v²ΦtovΘ vlastnosti). |
TIntegerProperty |
V╣echny celoΦφselnΘ typy vΦetn∞ p°eddefinovan²ch a u╛ivatelem
definovan²ch interval∙. |
TCharPropetry |
Typ Char a intervaly Char, jako ?A?..?Z?. |
TEnumProperty |
Libovoln² v²Φtov² typ. |
TFloatProperty |
LibovolnΘ reßlnΘ Φφslo. |
TStringPropetry |
╪et∞zce. |
TSetElementProperty |
Individußlnφ prvek v mno╛in∞, zobrazovan² jako logickß
hodnota. |
TSetPropetry |
V╣echny mno╛iny. Mno╛iny nejsou p°φmo editovatelnΘ, ale
m∙╛eme ji roz╣φ°it na seznam prvk∙ mno╛iny. |
TClassPropetry |
Objekty. Zobrazφ jmΘno typu objektu a umo╛≥uje expandovat
vlastnosti objektu. |
TMethodProperty |
UkazatelΘ metod. |
TComponentProperty |
Komponenty na formulß°i. U╛ivatel nem∙╛e editovat vlastnosti
komponent, ale m∙╛e ukazovat na specifickΘ komponenty kompatibilnφho typu. |
TColorPropetry |
Komponenta barev. Roletov² seznam obsahuje konstanty
barev. DvojitΘ kliknutφ otevφrß dialogovΘ okno v²b∞ru barvy. |
TFontNamePropetry |
JmΘna pφsma. Roletov² seznam obsahuje v╣echna aktußln∞
instalovanß pφsma. |
TFontProperty |
Pφsma. Umo╛≥uje roz╣φ°it na individußlnφ vlastnosti pφsma
stejn∞ jako p°φstup k dialogovΘmu oknu pφsma. |
Nßsleduje deklarace t°φdy jednoduchΘho editoru vlastnosti
nazvanΘho
TMujEditorVlastnosti:
class PACKAGE TMujEditorVlastnosti : public
TPropertyEditor
{
typedef TPropertyEditor inherited;
public:
virtual bool __fastcall AllEqual(void);
virtual System::AnsiString __fastcall
GetValue(void);
virtual void __fastcall SetValue(const
System::AnsiString Value);
__fastcall virtual ~TMujEditorVlastnosti(void)
{ }
__fastcall TMujEditorVlastnosti(void)
: Dsgnintf::TPropertyEditor() { }
};
Editovßnφ vlastnosti jako
text
V╣echny vlastnosti musφ poskytovat °et∞zcovou reprezentaci
sv²ch hodnot pro zobrazenφ v Inspektoru objekt∙. Mnoho vlastnostφ takΘ
zp°φstup≥uje u╛ivateli typ v novΘ hodnot∞ pro vlastnost. T°φda editoru
vlastnostφ poskytuje virtußlnφ metody, kterΘ m∙╛eme p°epsat pro p°evod
mezi textovou reprezentacφ a aktußlnφ hodnotou. Tyto metody jsou nazvanΘ
GetValue
a SetValue. Nß╣ editor vlastnosti takΘ d∞dφ mno╛inu metod pou╛φvan²ch
pro p°i°azenφ a Φtenφ jin²ch typ∙ hodnot (viz nßsledujφcφ tabulka):
Typ vlastnosti |
Metoda "Get" |
Metoda "Set" |
reßln² |
GetFloatValue |
SetFloatValue |
zßv∞r (udßlost) |
GetMethodValue |
SetMethodValue |
ordinßlnφ typ |
GetOrdValue |
SetOrdValue |
°et∞zec |
GetStrValue |
SetStrValue |
Kdy╛ p°edefinujeme metodu GetValue, m∙╛eme stßle
volat jednu z metod "Get" a kdy╛ p°edefinujeme metodu SetValue,
m∙╛eme stßle volat jednu z metod "Set".
Metoda GetValue editoru vlastnosti vracφ °et∞zec,
kter² reprezentuje souΦasnou hodnotu vlastnosti. Inspektor objekt∙ pou╛φvß
tento °et∞zec ve sloupci hodnot pro vlastnost. Implicitn∞ GetValue
vracφ "unknown".
K poskytnutφ °et∞zcovΘ reprezentace pro na╣i vlastnost,
p°edefinujeme metodu GetValue editoru vlastnosti. Jestli╛e vlastnost
nemß °et∞zcovou hodnotu, na╣e GetValue musφ p°evΘst hodnotu na jejφ
°et∞zcovou reprezentaci.
Metoda SetValue editoru vlastnosti p°ebφrß °et∞zec
zapsan² u╛ivatelem v Inspektoru objekt∙, p°evßdφ jej na p°φslu╣n² typ a
nastavuje hodnotu vlastnosti. Jestli╛e °et∞zec nemß reprezentaci p°φslu╣nΘ
hodnoty pro vlastnost,
SetValue generuje v²jimku a nevhodnou hodnotu
nepou╛ije. Pro p°eΦtenφ °et∞zcovΘ hodnoty z vlastnosti, p°edefinujeme metodu
SetValue
editoru vlastnosti.
SetValue musφ p°evßd∞t °et∞zec a ov∞°ovat hodnotu
p°ed volßnφm jednΘ z metod "Set".
Editovßnφ vlastnosti jako
celek
Voliteln∞ m∙╛eme poskytnout dialogovΘ okno, ve kterΘm m∙╛e
u╛ivatel viditeln∞ editovat vlastnost. Toto je u╛iteΦnΘ pro editory vlastnosti
jejich╛ vlastnosti jsou t°φdy. P°φkladem je vlastnost Font, pro
kterou u╛ivatel m∙╛e otev°φt dialogovΘ okno k volb∞ v╣ech atribut∙ pφsma.
K poskytnutφ dialogovΘho okna celkovΘho editoru vlastnosti, p°edefinujeme
metodu Edit t°φdy editoru vlastnosti.
Metoda Edit pou╛φvß stejnΘ metody "Get" a
"Set"
jako jsou pou╛ity v metodßch GetValue a SetValue (metoda
Edit
volß ob∞ tyto metody). Jeliko╛ editor je specifickΘho typu, obvykle nenφ
pot°eba p°evßd∞t hodnotu vlastnosti na °et∞zec. Kdy╛ u╛ivatel klikne na
tlaΦφtko '...' vedle vlastnosti nebo dvojit∞ klikne ve sloupci hodnot,
Inspektor objekt∙ volß metodu Edit editoru vlastnosti. V implementaci
metody Edit provedeme tyto kroky: Vytvo°φme nß╣ editor, p°eΦteme
souΦasnΘ hodnoty a p°i°adφme je metodou "Get", kdy╛ u╛ivatel zm∞nφ
n∞kterou hodnotu, p°i°adφme tuto hodnotu pomocφ metody
"Set" a zru╣φme
editor.
Specifikovßnφ atribut∙ editoru
Editor vlastnosti musφ poskytovat informace, kterΘ Inspektor
objekt∙ m∙╛e pou╛φt k urΦenφ zobrazenΘho nßstroje. Nap°. Inspektor objekt∙
musφ znßt, zda vlastnost mß podvlastnosti nebo zda m∙╛e zobrazit seznam
mo╛n²ch hodnot. Pro specifikaci atribut∙ editoru, p°edefinujeme metodu
GetAttributes
t°φdy editoru. GetAttributes je metoda vracejφcφ mno╛inu hodnot
typu TPropertyAttributes, kterß m∙╛e obsahovat n∞kterΘ nebo v╣echny
nßsledujφcφ hodnoty:
P°φznak |
V²znam, je-li vlo╛en |
Ovliv≥uje metodu |
paValueList |
Editor m∙╛e zobrazit seznam v²Φtov²ch hodnot. |
GetValues |
paSubProperties |
Vlastnost mß podvlastnosti, kterΘ m∙╛e zobrazit. |
GetProperties |
paDialog |
Editor m∙╛e pro editaci zobrazit dialogovΘ okno. |
Edit |
paMultiSelect |
U╛ivatel m∙╛e vybrat vφce ne╛ jeden prvek. |
|
paAutoUpdate |
Aktualizuje komponentu po ka╛dΘ zm∞n∞, namφsto Φekßnφ
na schvßlenφ hodnoty. |
SetValue |
paSortList |
Inspektor objekt∙ se°adφ seznam hodnot. |
|
paReadOnly |
U╛ivatel nem∙╛e modifikovat hodnotu vlastnosti. |
|
paRevertable |
Povoluje volbu Revert to Inherited v mφstnφ nabφdce Inspektora
objekt∙ (nßvrat k p°edchozφ nebo implicitnφ hodnot∞). |
|
Vlastnost Color mß n∞kolik mo╛nostφ, jak ji u╛ivatel
zadß v Inspektoru objekt∙: zßpisem, v²b∞rem ze seznamu a editorem. Metoda
GetAttributes
TColorProperty, tedy obsahuje n∞kolik atribut∙ ve svΘ nßvratovΘ hodnot∞:
virtual __fastcall TPropertyAttributes TColorProperty::GetAttributes()
{
return TPropertyAttributes()<<paMultiSelect<<paDialog<<paValueList;
}
Registrace editoru vlastnosti
Vytvo°en² editor vlastnosti se musφ v C++ Builderu registrovat.
Registracφ editoru vlastnosti p°i°adφme typ vlastnosti k editoru vlastnosti.
M∙╛eme registrovat editor se v╣emi vlastnostmi danΘho typu nebo s jistou
vlastnostφ jistΘho typu komponenty. K registraci editoru vlastnosti volßme
funkci
RegisterPropetryEditor.
Tato funkce mß Φty°i parametry: Prvnφm je ukazatel na
informace o typu pro editovanou vlastnost. To je v╛dy volßnφ funkce __typeinfo,
nap°.
__typeinfo(TMojeKomponenta). Druh²m je typ komponenty, na
kter² je tento editor aplikovßn. Jestli╛e tento parametr je NULL, editor
je pou╛iteln² na v╣echny vlastnosti danΘho typu. T°etφm parametrem je jmΘno
vlastnosti. Tento parametr mß v²znam pouze, jestli╛e p°edchozφ parametr
specifikuje konkrΘtnφ typ komponenty. V tomto p°φpad∞, m∙╛eme specifikovat
jmΘno konkrΘtnφ vlastnosti v typu komponenty, se kterou tento editor pracuje.
Poslednφm parametrem je typ editoru vlastnosti pou╛it² pro editovßnφ specifikovanΘ
vlastnosti.
Nßsleduje ukßzka funkce, kterß registruje editory pro
n∞kterΘ standardnφ komponenty na Palet∞ komponent:
namespace Newcomp
{
void __fastcall PACKAGE Register()
{
RegisterPropertyEditor(__typeinfo(TComponent),
0L, "",
__classid(TComponentProperty));
RegisterPropertyEditor(__typeinfo(TComponentName),
TComponent,
"Name", __classid(TComponentNameProperty));
RegisterPropertyEditor(__typeinfo(TMenuItem),
TMenu, "",
__classid(TMenuItemProperty));
}
}
T°i p°φkazy v tΘto funkci ukazujφ r∙znΘ pou╛itφ RegisterPropertyEditor:
Prvnφ p°φkaz je nejtypiΦt∞j╣φ. Registruje editor vlastnosti TComponentProperty
pro v╣echny vlastnosti typu TComponent (nebo potomk∙ TComponent,
kterΘ nemajφ registrovßn vlastnφ editor). Obecn∞, kdy╛ registrujeme editor
vlastnosti, vytvo°φme editor pro jist² typ a chceme jej pou╛φt pro v╣echny
vlastnosti tohoto typu, pak jako druh² parametr pou╛ijeme NULL a jako t°etφ
parametr prßzdn² °et∞zec. Druh² p°φkaz je nejspecifiΦt∞j╣φm typem registrace.
Registruje editor pro jistou vlastnost v jistΘm typu komponenty. V tomto
p°φpad∞ je to editor pro vlastnost Name (typ TComponentName)
v╣ech komponent. T°etφ p°φklad je specifiΦt∞j╣φ ne╛ prvnφ, ale nenφ limitovßn
jako druh². Registruje editor pro v╣echny vlastnosti typu TMenuItem
v komponentßch typu TMenu.
P°idßvßnφ editoru komponenty
Editory komponent urΦujφ co nastane, kdy╛ dvojit∞ klikneme
na komponentu na NßvrhovΘm formulß°i a p°idßvß p°φkazy do mφstnφ nabφdky,
kterß je zobrazena p°i kliknutφ prav²m tlaΦφtkem my╣i na komponent∞. Umo╛≥uje
takΘ kopφrovat na╣i komponentu do schrßnky Windows v p°izp∙sobenΘm formßtu.
Pokud na╣φ komponent∞ nedßme editor komponenty, pak C++
Builder pou╛ije implicitnφ editor komponenty. Implicitnφ editor komponenty
je implementovßn t°φdou TDefaultEditor. TDefaultEditor nep°idßvß
╛ßdnΘ novΘ prvky v mφstnφ nabφdce. Kdy╛ na komponent∞ dvojit∞ klikneme,
pak TDefaultEditor hledß vlastnosti komponenty a generuje (nebo
p°echßzφ na) prvnφ obsluhu udßlosti.
K vytvo°enφ editoru komponenty pro na╣φ komponentu, musφme
odvodit novou t°φdu od TComponentEditor a potom provΘst jednu nebo
vφce v∞cφ z:
Z p°edchozφho seznamu je po╛adovßna pouze registrace Editoru
komponenty.
P°idßvßnφ prvku k mφstnφ
nabφdce
Kdy╛ u╛ivatel klikne na komponent∞ prav²m tlaΦφtkem my╣i,
pak jsou volßny metody GetVerbCount a GetVerb Editoru komponenty
k vytvo°enφ mφstnφ nabφdky. Tyto metody m∙╛eme p°epsat pro p°idßnφ p°φkazu
k mφstnφ nabφdce.
Metodu GetVerbCount p°epφ╣eme, aby vracela poΦet
p°φkaz∙ p°idan²ch do mφstnφ nabφdky. Metodu GetVerb p°epφ╣eme, aby
vracela °et∞zce, kterΘ chceme p°idat pro ka╛d² z t∞chto p°φkaz∙. Znak &
v °et∞zci, zp∙sobφ, ╛e nßsledujφcφ znak bude podtr╛en a bude pracovat jako
zkracovacφ klßvesa pro tento prvek nabφdky. Na konec p°φkaz∙, kterΘ zobrazujφ
dialogovΘ okno zapφ╣eme .... GetVerb mß jeden parametr, kter²
specifikuje index p°φkazu.
Nßsledujφcφ k≤d p°episuje metody GetVerbCount
a GetVerb pro p°idßnφ dvou p°φkaz∙ k mφstnφ nabφdce:
int __fastcall TMujEditor::GetVerbCount(void)
{
return 2;
}
System::AnsiString __fastcall TMujEditor::GetVerb(int
Index)
{
switch (Index)
{
case 0: return "&DoThis
... "; break;
case 1: return "Do&That";
break;
}
}
Poznßmka: Ujistφme se, ╛e metoda GetVerb
vracφ hodnotu pro ka╛d² mo╛n² index specifikovan² GetVerbCount.
Kdy╛ p°φkaz poskytnut² GetVerb je vybrßn v NßvrhovΘm
formulß°i, pak je volßna metoda ExecuteVerb. Pro ka╛d² p°φkaz poskytnut²
v metod∞ GetVerb, implementujeme akci v metod∞ ExecuteVerb.
M∙╛eme p°istupovat ke komponent∞, kterß bude editovßna pomocφ vlastnosti
Component
editoru.
Nßsledujφcφ metoda ExecuteVerb implementuje p°φkazy
pro p°edchozφ metodu GetVerb:
void __fastcall TMujEditor::ExecuteVerb(int
Index)
{
switch (Index)
{
case 0:
TMujDialog
*MySpecialDialog = new TMujDialog();
MySpecialDialog->Execute();
// pou╛φvßme
vlastnost Component pro p°φstup k instanci TMojeComponenta
((TMojeComponenta
*)Component)->ThisProperty = MySpecialDialog->ReturnValue;
delete MySpecialDialog;
break;
case 1:
That();
// volßnφ metody "That"
break;
}
}
Zm∞na chovßnφ dvojitΘho
kliknutφ
Kdy╛ na komponentu dvojit∞ klikneme, pak je volßna metoda
Edit
Editoru komponenty. Implicitn∞ metoda Edit provßdφ prvnφ p°φkaz
p°idan² do mφstnφ nabφdky. I kdy╛ provßd∞nφ prvnφho p°φkazu je obvykle
vhodnß my╣lenka, n∞kdy toto implicitnφ chovßnφ m∙╛eme pot°ebovat zm∞nit.
Nap°. m∙╛eme po╛adovat alternativnφ chovßnφ pokud do mφstnφ nabφdky nep°idßme
╛ßdn² p°φkaz nebo m∙╛eme po╛adovat zobrazenφ dialogovΘho okna, kterΘ spojuje
n∞kolik p°φkaz∙, kdy╛ na komponent∞ dvojit∞ klikneme.
P°epsßnφm metody Edit specifikujeme novΘ chovßnφ
pro dvojitΘ kliknutφ na komponent∞. Nap°. nßsledujφcφ metoda Edit
zp∙sobφ zobrazenφ dialogovΘho okna pφsma p°i dvojitΘm kliknutφ na komponent∞:
void __fastcall TMujEditor::Edit(void)
{
TFontDialog *pFontDlg = new TFontDialog(NULL);
pFontDlg->Execute();
// vlastnost Component pou╛φvßme pro
p°φstup k instanci TMojeComponenta
((TMokeKomponenta *)Component)->Font
= pFontDlg->Font;
delete pFontDlg;
}
Pokud chceme p°ejφt do Editoru k≤du na obsluhu udßlosti
p°i dvojitΘm kliknutφ na komponent∞, pak pou╛ijeme jako t°φdu p°edka TDefaultEditor
namφsto TComponentEditor. Potom mφsto p°epsßnφ metody Edit
p°epφ╣eme chrßn∞nou metodu TDefaultEditor::EditProperty. EditProperty
prochßzφ obsluhami udßlostφ komponenty a pou╛ije prvnφ nalezenou. Toto
hledßnφ m∙╛eme zm∞nit. Nap°.
void __fastcall TMujEditor::EditProperty(TPropertyEditor*
PropertyEditor, bool &Continue,
bool &FreeEditor)
{
if (PropertyEditor->ClassNameis("TMethodProperty")
&&
CompareText(PropertyEditor->GetName,
"OnSpecialEvent") == 0)
{
TDefaultEditor::EditProperty(PropertyEditor,
Continue, FreeEditor);
}
}
P°φdßvßnφ formßtu schrßnky
Implicitn∞, kdy╛ u╛ivatel zvolφ Copy p°i vybranΘ komponent∞,
pak komponenta je kopφrovßna do schrßnky v internφm formßtu C++ Builderu.
Potom ji m∙╛eme vlo╛it na jin² formulß° nebo datov² modul. Na╣i komponentu
m∙╛eme kopφrovat v dal╣φch formßtech do schrßnky p°epsßnφm metody Copy.
Nap°. nßsledujφcφ metoda Copy umo╛≥uje komponent∞
TImage
kopφrovat sv∙j obrßzek do schrßnky. Tento obrßzek je ignorovßn IDE C++
Builderu, ale m∙╛e b²t vklßdßn do jin²ch aplikacφ.
void __fastcall TMujEditor::Copy(void)
{
WORD AFormat;
int AData;
HPALETTE APalette;
((TImage*)Component)->Picture->SaveToClipboardFormat(AFormat,AData,
APalette);
TClipboard *pClip = Clipboard(); //
nevyprazd≥uje schrßnku
pClip->SetAsHandle(AFormat, AData);
}
Registrace editoru komponenty
Kdy╛ ji╛ mßme definovßn editor komponenty, m∙╛eme jej registrovat
pro prßci s jistou t°φdou komponenty. Registrovan² editor komponenty je
vytvo°en pro ka╛dou komponentu, kdy╛ je vybrßna na nßvrhovΘm formulß°i.
K vytvo°enφ asociace mezi Editorem komponenty a t°φdou
komponenty volßme RegisterComponentEditor. Tato funkce p°ebφrß jmΘno
t°φdy komponenty, kterß pou╛φvß editor a jmΘno t°φdy Editoru komponenty,
kterou mßme definovanou. Nap°. nßsledujφcφ p°φkaz registruje t°φdu Editoru
komponenty nazvanou TMujEditor pro prßci se v╣emi komponentami typu
TMojeKomponenta:
RegisterComponentEditor(__classid( TMojeKomponenta),
__classid(TMujEditor));
Volßnφ RegisterComponentEditor umφstφme do jmennΘho
prostoru kde registrujeme na╣i komponentu.
Pokud novß komponenta nazvanß TMojeKomponenta
a jejφ editor
TMujEditor jsou implementovßny v NovaKomp.cpp,
pak nßsledujφcφ k≤d (v NovaKomp.cpp) registruje komponentu a spojuje
ji s Editorem komponenty:
namespace Novakomp
{
void __fastcall PACKAGE Register()
{
TComponentClass
classes[1] = {__classid(TMojeKComponenta)};
RegisterComponents("R∙znΘ",
classes, 0);
RegisterComponentEditor(classes[0],
__classid(TMujEditor));
}
}
P°eklad komponent do balφΦk∙
Kdy╛ ji╛ komponenty jsou registrovanΘ, pak je musφme p°elo╛it
jako balφΦky a to d°φve ne╛ je m∙╛eme instalovat v IDE. BalφΦek m∙╛e obsahovat
jednu nebo n∞kolik komponent a takΘ u╛ivatelsk²ch editor∙ vlastnostφ.
K vytvo°enφ a p°ekladu balφΦku, umφstφme zdrojovΘ k≤dy
jednotek na╣ich komponent do seznamu obsahu balφΦku. Pokud na╣e komponenty
zßvisφ na dal╣φch balφΦcφch, vlo╛φme tyto balφΦky do seznamu po╛adavk∙.
P°elo╛en² balφΦek s komponentami ji╛ m∙╛eme instalovat na Paletu komponent.
Obecn²m problΘmem p°i registraci a instalovßnφ u╛ivatelskΘ
komponenty je to, ╛e komponenta se nezobrazuje v seznamu komponent po ·sp∞╣n∞
instalovanΘm balφΦku. Nßsleduje p°ehled obecn²ch p°φΦin nezobrazovßnφ komponenty
v seznamu nebo na palet∞:
-
Chyb∞jφcφ modifikßtor PACKAGE u funkce Register.
-
Chyb∞jφcφ modifikßtor PACKAGE u t°φdy.
-
Chyb∞jφcφ #pragma package(smart_init) ve zdrojovΘm
k≤du C++.
-
Funkce Register nenφ nalezena ve jmennΘm prostoru
se stejn²m jmΘnem jako je jmΘno modulu zdrojovΘho k≤du.
-
Register nenφ ·sp∞╣n∞ exportovßn. Pou╛ijte tdump
na soubor BPL k prohlΘdnutφ exportovan²ch funkcφ:
tdump -ebpl mypack.bpl mypack.dmp
V sekci exports vidφme zda funkce Register
(ve jmennΘm prostoru) byla exportovßna
-
Kdy╛ pracujeme s p°ipojenou databßzφ, je Φasto u╛iteΦnΘ mφt ovladaΦ spojen
s n∞jakou polo╛kou databßze. Aplikace tedy m∙╛e zalo╛it propojenφ mezi
ovladaΦem a n∞jakou Φßstφ databßze. C++ Builder obsahuje datovΘ ovladaΦe
typ∙ editaΦnφch oken, seznam∙, kombinovan²ch oken a m°φ╛ek. M∙╛eme takΘ
vytvo°it sv∙j vlastnφ datov² ovladaΦ. Je n∞kolik stup≥∙ zßvislosti dat
datov²ch ovladaΦ∙. Nejjednodu╣╣φ je datovß zßvislost pouze pro Φtenφ, nebo
prohlφ╛enφ dat, a umo╛n∞nφ reakce na aktußlnφ stav databßze. Slo╛it∞j╣φ
je editovatelnß datovß zßvislost, kde u╛ivatel m∙╛e editovat hodnoty v
databßzi manipulacφ s ovladaΦem.
Nynφ se pokusφme vytvo°it ovladaΦ urΦen² pouze pro Φtenφ, kter² je
spojen s jednou polo╛kou v databßzi. OvladaΦ bude pou╛φvat kalendß° vytvo°en²
v p°edchozφ kapitole.
Vytvo°enφ datovΘho ovladaΦe kalendß°e provedeme v nßsledujφcφch krocφch:
vytvo°φme a registrujeme komponentu, ud∞lßme ovladaΦ urΦeny pouze pro Φtenφ,
p°idßme datovΘ propojenφ a reakce na zm∞ny dat.
Pou╛ijeme obecn² postup s t∞mito specifikami: jednotku komponenty nazveme
DBCal,
odvodφme nov² typ komponenty nazvan² TDBCalendar od
TSampleCalendar
a registrujeme TDBCalendar na strßnce Samples Palety komponent.
V²sledek na╣φ prßce je (nejprve je uveden v²pis hlaviΦkovΘho souboru
jednotky):
#ifndef DBCalH
#define DBCalH
#include <vcl\sysutils.hpp>
#include <vcl\controls.hpp>
#include <vcl\classes.hpp>
#include <vcl\forms.hpp>
#include <vcl\grids.hpp>
#include "CALSAMP.h"
class PACKAGE TDBCalendar : public TSampleCalendar
{
private:
protected:
public:
__published:
};
#endif
CPP soubor vypadß takto:
#pragma link "Calsamp" // vazba na
TSampleCalendar
#include <vcl\vcl.h>
#pragma hdrstop
#include "DBCal.h"
#pragma package(smart_init);
static inline TDBCalendar *ValidCtrCheck()
{
return new TDBCalendar(NULL);
}
namespace Dbcal
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1]
= {__classid(TDBCalendar)};
RegisterComponents("Samples",
classes, 0);
}
}
-
Jeliko╛ tento kalendß° bude urΦen pouze pro Φtenφ, je vhodnΘ znemo╛nit
u╛ivateli provßd∞nφ zm∞n v ovladaΦi. Provedeme to ve dvou krocφch: p°idßme
vlastnost ReadOnly a dovolφme pot°ebnΘ aktualizace. Kdy╛ tato vlastnost
je nastavena na true, jsou v╣echny bu≥ky v ovladaΦi nevybφratelnΘ.
P°idßme deklaraci vlastnosti a soukromou polo╛ku k ulo╛enφ hodnoty:
class PACKAGE TDBCalendar : public TSampleCalendar
{
private:
bool FReadOnly;
protected:
public:
__fastcall TDBCalendar(TComponent*
Owner);
__published:
__property bool ReadOnly={read=FReadOnly,write=FReadOnly,default=true};
};
Zapφ╣eme definici konstruktoru:
__fastcall TDBCalendar::TDBCalendar(TComponent*
Owner)
: TSampleCalendar(Owner)
{
FReadOnly = true;
}
a p°edefinujeme metodu SelectCell k zßkazu v²b∞ru, jestli╛e
ovladaΦ je pouze pro Φtenφ.
bool __fastcall TDBCalendar::SelectCell(long
ACol, long ARow)
{
if (FReadOnly) return false;
return TSampleCalendar::SelectCell(ACol,
ARow);
}
Nesmφme zapomenout p°idat deklaraci SelectCell k deklaraci t°φdy
TDBCalendar.
Jestli╛e nynφ p°idßme kalendß° na formulß°, zjistφme, ╛e komponenta ignoruje
kliknutφ a stisky kurzorov²ch klßves.
Kalendß° pouze pro Φtenφ pou╛φvß metodu SelectCell pro v╣echny
typy zm∞n, vΦetn∞ nastavovßnφ vlastnostφ
Row a Col. Metoda
UdpateCalendar
nastavuje Row a Col poka╛dΘ, kdy╛ se zm∞nφ datum, ale jeliko╛
SelectCell
nepovolφ zm∞ny, v²b∞r se nem∞nφ, i kdy╛ se zm∞nφ datum. K omezenφ tohoto
absolutnφho zßkazu zm∞n, m∙╛eme p°idat internφ logickou polo╛ku ke kalendß°i
a povolit zm∞ny, kdy╛ je tato polo╛ka nastavena na
true:
class PACKAGE TDBCalendar : public TSampleCalendar
{
private:
bool FUpdating;
public:
virtual void __fastcall UpdateCalendar();
};
bool __fastcall TDBCalendar::SelectCell(long
ACol, long ARow)
{
if (!FUpdating && FReadOnly)
return false;
return TSampleCalendar::SelectCell(ACol,
ARow);
}
void __fastcall TDBCalendar::UpdateCalendar()
{
FUpdating = true;
try
{
TSampleCalendar::UpdateCalendar();
}
catch(...)
{
FUpdating = false;
throw;
}
FUpdating = false;
}
Kalendß° stßle neumo╛≥uje u╛ivateli provßd∞t zm∞ny datumu, ale ji╛
sprßvn∞ reaguje na zm∞ny datumu provedenΘ zm∞nou vlastnostφ datumu. Dßle
pot°ebujeme ke kalendß°i p°idat schopnost prohlφ╛et datumy.
-
Propojenφ mezi ovladaΦem a databßzφ je obsluhovßno objektem nazvan²m datov²
spoj. C++ Builder poskytuje n∞kolik typ∙ datov²ch spoj∙. Objekt datovΘho
spoje, kter² propojuje ovladaΦ s jednou polo╛kou v databßzi je TFieldDataLink.
Jsou takΘ datovΘ spoje pro celΘ tabulky. Objekt datovΘho ovladaΦe vlastnφ
sv∙j objekt datovΘho spoje. Tj. ovladaΦ mß odpov∞dnost za vytvo°enφ i uvoln∞nφ
datovΘho spoje. K vytvo°enφ datovΘho spoje jako vlastn∞nΘho objektu provedeme
t°i kroky: deklarujeme objektovou polo╛ku, deklarujeme p°φstupovΘ vlastnosti
a inicializujeme datov² spoj.
Komponenta vy╛aduje polo╛ku pro ka╛d² sv∙j vlastn∞n² objekt. V na╣em
p°φpad∞ kalendß° pot°ebuje polo╛ku typu TFieldDataLink pro sv∙j
datov² spoj:
class PACKAGE TDBCalendar : public TSampleCalendar
{
private:
TFieldDataLink *FDataLink;
};
D°φve ne╛ m∙╛eme p°elo╛it aplikaci, musφme vlo╛it hlaviΦkovΘ soubory
DB.HPP
a DBTables.HPP do hlaviΦkovΘho souboru na╣φ jednotky.
Ka╛d² datov² ovladaΦ mß vlastnost DataSource, kterß specifikuje
kter² objekt datovΘho zdroje v aplikaci poskytuje data ovladaΦi. Dßle ovladaΦ,
kter² p°istupuje k samostatnΘ polo╛ce vy╛aduje vlastnost DataField
ke specifikaci polo╛ky datovΘho zdroje. Tyto p°φstupovΘ vlastnosti neposkytujφ
p°φstup k vlastn∞nΘmu objektu sami, ale odpovφdajφcφmi vlastnostmi ve vlastn∞nΘm
objektu. Deklarujeme vlastnosti DataSource a DataField a
jejich implementaΦnφ metody a zapφ╣eme metody jako ?p°edßvajφcφ? metody
k odpovφdajφcφm vlastnostem objektu datovΘho spoje.
class PACKAGE TDBCalendar : public TSampleCalendar
{
private:
AnsiString __fastcall GetDataField();
TDataSource *__fastcall GetDataSource();
void __fastcall SetDataField(const
AnsiString Value);
void __fastcall SetDataSource(TDataSource
*Value);
__published:
__property AnsiString DataField =
{read=GetDataField,
write=SetDataField, nodefault};
__property TDataSource *DataSource
= {read=GetDataSource,
write=SetDataSource, nodefault};
};
AnsiString __fastcall TDBCalendar::GetDataField()
{
return FDataLink->FieldName;
}
TDataSource *__fastcall TDBCalendar::GetDataSource()
{
return FDataLink->DataSource;
}
void __fastcall TDBCalendar::SetDataField(const
AnsiString Value)
{
FDataLink->FieldName = Value;
}
void __fastcall TDBCalendar::SetDataSource(TDataSource
*Value)
{
if(Value != NULL)
Value->FreeNotification(this);
FDataLink->DataSource = Value;
}
Nynφ, kdy╛ mßme vytvo°eno spojenφ mezi kalendß°em a jeho datov²m spojem,
je jeden velmi d∙le╛it² krok. Musφme p°i vytvß°enφ ovladaΦe kalendß°e vytvo°it
objekt datovΘho spoje a datov² spoj zru╣it p°ed zru╣enφm kalendß°e.
Datov² ovladaΦ vy╛aduje p°φstup k svΘmu datovΘmu spoji prost°ednictvφm
svΘ existence, a musφme tedy vytvo°it objekt datovΘho spoje v jeho vlastnφm
konstruktoru a zru╣it objekt datovΘho spoje p°ed sv²m samotn²m zru╣enφm.
P°epφ╣eme tedy konstruktor a destruktor kalendß°e k vytvß°enφ a ru╣enφ
objektu datovΘho spoje.
class PACKAGE TDBCalendar : public TSampleCalendar
{
public:
__fastcall TDBCalendar(TComponent*
Owner);
__fastcall ~TDBCalendar();
};
__fastcall TDBCalendar::TDBCalendar(TComponent*
Owner)
: TSampleCalendar(Owner)
{
FReadOnly = true;
FDataLink = new TFieldDataLink();
FDataLink->Control = this;
}
__fastcall TDBCalendar::~TDBCalendar()
{
FDataLink->Control = NULL;
FDataLink-OnUpdateData = NULL;
delete FDataLink;
}
Nynφ mßme kompletnφ datov² spoj, ale nemßme mo╛nost °φdit, kterß data
budou Φtena z p°ipojenΘ polo╛ky.
-
Nß╣ ovladaΦ mß datov² spoj a vlastnosti specifikujφcφ datov² zdroj a datovou
polo╛ku a musφme je╣t∞ vytvo°it reakce na zm∞ny v datech tΘto datovΘ polo╛ky,
nebo╗ se m∙╛eme p°esunout na jin² zßznam. V╣echny objekty datov²ch spoj∙
majφ udßlosti nazvanΘ OnDataChange. Kdy╛ datov² zdroj indikuje zm∞nu
ve sv²ch datech, objekt datovΘho spoje volß obsluhu udßlostφ p°ipojenou
k tΘto udßlosti. K aktualizaci ovladaΦe v reakci na datovΘ zm∞ny, p°ipojφme
obsluhu k udßlosti OnDataChange datovΘho spoje.
V na╣em p°φpad∞, p°idßme metodu DataChange ke kalendß°i a urΦφme
ji jako obsluhu pro OnDataChange datovΘho spoje v konstruktoru.
V destruktoru musφme obsluhu odpojit a to p°ed zru╣enφm objektu.
class PACKAGE TDBCalendar : public TSampleCalendar
{
private:
void __fastcall DataChange(TObject
*Sender);
};
__fastcall TDBCalendar::TDBCalendar(TComponent*
Owner)
: TSampleCalendar(Owner)
{
FReadOnly = true;
FDataLink = new TFieldDataLink();
FDataLink->Control = this;
FDataLink->OnDataChange = DataChange;
}
__fastcall TDBCalendar::~TDBCalendar()
{
FDataLink->Control = NULL;
FDataLink-OnUpdateData = NULL;
FDataLink->OnDataChange = NULL;
delete FDataLink;
}
void __fastcall TDBCalendar::DataChange(TObject
*Sender)
{
if (FDataLink->Field == NULL) CalendarDate
= 0;
else CalendarDate = FDataLink->Field->AsDateTime;
}
Tφm je zobrazovacφ databßzov² ovladaΦ kalendß°e hotov.
-
Pokuste se u prßv∞ vytvo°enΘ komponenty zadat bitovou mapu zobrazenou na
palet∞ a vytvo°it nßpov∞du, kterou zapojφte do nßpov∞dnΘho systΘmu C++
Builderu.
![](/file/23411/Chip_2002-05_cd1.bin/chplus/cpp/5/PreviousArrow.gif) ![](/file/23411/Chip_2002-05_cd1.bin/chplus/cpp/5/NextArrow.gif) ![](/file/23411/Chip_2002-05_cd1.bin/chplus/cpp/5/WayUpArrow.gif) |
8. Ud∞lßnφ komponenty dostupnΘ
p°i nßvrhu
|