D°φve ne₧ se budeme zab²vat dalÜφmi databßzov²mi komponentami, seznßmφme
se s vytvß°enφm p°ezdφvek BDE. U naÜich p°φklad∙ jsme se zatφm p°ezdφvkßm
BDE vyhnuli. P°i dalÜφm seznamovßnφ s databßzov²mi aplikacemi je ale ji₧
budeme pot°ebovat. P°ezdφvku lze vytvo°it n∞kolika zp∙soby:
pomocφ Administrßtora BDE,
pomocφ programu Database Desktop,
pomocφ pr∙zkumnφka SQL (pouze ve verzi Client/Server C++ Builderu) a
pomocφ k≤du za b∞hu aplikace.
Nynφ se budeme zab²vat pouze prvnφ z t∞chto mo₧nostφ.
P°i v²voji aplikace je obvykle zapot°ebφ vytvo°it jednu nebo vφce p°ezdφvek
BDE. Administrßtora BDE spustφme volbou Programs | Borland C++ Builder
3 | BDE Administrator. V okn∞ administrßtora je uveden seznam nadefinovan²ch
p°ezdφvek. Je mo₧no zde m∞nit parametry p°ezdφvek a takΘ vytvß°et p°ezdφvky
novΘ. ProhlΘdn∞te si, jakΘ p°ezdφvky jsou nadefinovanΘ.
V dalÜφch zadßnφch se pokusφme p°ipojit ke cviΦnΘ databßzi Sybase SQL
Anywhere. Ukß₧eme si tedy jak vytvo°it pot°ebnou p°ezdφvku pro tuto databßzi.
Budeme ale postupovat jin²m zp∙sobem.
Nejd°φve je nutno p°ekopφrovat soubor tΘto cviΦnΘ databßze do adresß°e
C:\PRAC. Jednß se o soubor SADEMO.DB. Nalezn∞te jej a p°ekopφrujte.
Dßle je nutno nadefinovat datov² zdroj ODBC. V administrßtoru BDE zvolφme
Object
| ODBC Administrator, Φφm₧ zobrazφme dialogovΘ okno Administrßtora
datov²ch zdroj∙ ODBC. Na strßnce
User DSN stiskneme tlaΦφtko Add
a vybereme ovladaΦ, pro kter² chceme datov² zdroj vytvß°et. My vybereme
Sybase
SQL Anywhere 5.0 a stiskneme tlaΦφtko Finish. Je zobrazeno okno
konfigurace ODBC. Pomocφ tlaΦφtka
Browse do Φßsti Database File
zadßme C:\PRAC\SADEMO.DB, oznaΦφme voliΦ Custom a stiskneme
tlaΦφtko Options. Tφm zobrazφme dalÜφ okno, kde v Φßsti
Start
Command je nutno zadat ·plnou specifikaci souboru DBENG50.EXE
(nap°. C:\SQLAny50\Win32\DBENG50.EXE). Nalezn∞te tuto specifikaci a zadejte
ji. V tomto okn∞ ji₧ nenφ zapot°ebφ nic nastavovat a stiskem OK
jej uzav°eme. Okno konfigurace uzav°eme stiskem
OK. Na strßnce User
DSN Administrßtora datov²ch zdroj∙ ODBC si povÜimn∞te, ₧e v seznamu
datov²ch zdroj∙ je ji₧ nßmi vytvo°en² datov² zdroj (Sademo). Okno
Administrßtora ODBC takΘ uzav°eme stiskem OK. A₧ budete pou₧φvat
tuto databßzi, pak je nutno p°i p°ipojovßnφ k nφ zadat identifikaci u₧ivatele
a heslo. K databßzi se budeme hlßsit jako u₧ivatel
DBA a tento u₧ivatel
mß heslo SQL. Tyto informace si zapamatujte.
Seznam p°ezdφvek v Administrßtoru BDE se zatφm nezm∞nil (seznam se
naΦφtß v₧dy p°i spuÜt∞nφ administrßtora). Pokud ukonΦφme prßci Administrßtora
BDE a spustφme jej znova, pak v seznamu p°ezdφvek ji₧ uvidφme p°ezdφvku
Sademo
pro nßÜ nov∞ vytvo°en² datov² zdroj ODBC. P°ezdφvka tedy byla vytvo°ena
sama.
To co bylo uvedeno o Administrßtoru BDE platφ i o samotnΘm C++ Builderu.
P°ezdφvky jsou naΦφtßny pouze p°i jeho spuÜt∞nφ. Pokud provedeme n∞jakou
zm∞nu v p°ezdφvkßch BDE, pak tato zm∞na se v C++ Builderu projevφ a₧ po
jeho dalÜφm spuÜt∞nφ.
V p°edchozφm zadßnφ jsme si vytvo°ili p°ezdφvku BDE Sademo, kterou
nynφ budeme pou₧φvat p°i dalÜφm seznamovßnφ s databßzov²mi komponentami.
Komponenta Query slou₧φ pro zp°φstup≥ovßnφ dat v databßzφch typu
klient/server. Pokud bychom i pro tento typ databßzφ pou₧φvali komponentu
Table,
pak n∞kterΘ tabulky se nßm nepoda°φ otev°φt (nap°. ve cviΦnΘ databßzi Sademo
neotev°eme tabulku Customer - tabulky jsou provßzanΘ a databßze
obsahuje takΘ r∙znΘ p°φkazy). Nynφ se seznßmφme s komponentou
Query.
Tato komponenta nemß vlastnost TableName. Nelze tedy p°φmo zjistit,
ze kter²ch tabulek se databßze sklßdß. Pokud se pot°ebujeme dozv∞d∞t, kterΘ
tabulky jsou v databßzi, pak to lze provΘst dv∞ma zp∙soby. Jednak lze na
formulß° umφstit doΦasnou komponentu Table, nastavit u nφ DatabaseName
na sprßvnou p°ezdφvku a v rozbalovacφm seznamu vlastnosti TableName
si seznam tabulek m∙₧eme prohlΘdnout. Druhou mo₧nostφ je, vybrat komponentu
Query
na formulß°i a v jejφ mφstnφ nabφdce zvolit Explore. Tφm zobrazφme
Pr∙zkumnφka databßze, ve kterΘm si m∙₧eme zjistit r∙znΘ v∞ci o databßzi
(vΦetn∞ seznamu tabulek databßze).
Jednou z hlavnφch vlastnostφ komponenty Query je vlastnost SQL.
Je typu TStringList a obsahuje provßd∞nΘ p°φkazy SQL. Hodnotu tΘto
vlastnosti lze nastavit p°i nßvrhu v Inspektoru objekt∙ nebo za b∞hu aplikace
pomocφ k≤du. Vytvo°φme nynφ jednoduchou aplikaci, ve kterΘ nap°. zobrazφme
obsah tabulky Customer ze cviΦnΘ databßze Sademo. ZaΦneme
v²vojem novΘ aplikace, na formulß° umφstφme komponentu Query, vlastnost
DatabaseName
nastavφme na Sademo, vlastnost SQL na
SELECT * FROM Customer
a vlastnost Active na true. Na formulß° je jeÜt∞ nutno
vlo₧it komponenty DataSource a DBGrid. Vlastnosti u t∞chto
komponent nastavφme ji₧ znßm²m zp∙sobem (u DataSource vlastnost
DataSet
na Query1 a u DBGrid vlastnost DataSource na DataSource1).
Aplikace je hotova a vidφme, ₧e m°φ₧ka zobrazuje obsah tabulky Customer
(pokud bychom pou₧ili komponentu Table, pak se nßm to nepoda°φ).
Kdy₧ budeme vlastnost SQL nastavovat za b∞hu, pak nesmφme zapomenout
vyprßzdnit jejφ p°edchozφ obsah, tzn. je nutno pou₧φt nap°. p°φkazy:
Query1->SQL->Clear();
Query1->SQL->Add("SELECT
* FROM Customer");
Vlastnost je seznam °et∞zc∙ a ne samotn² °et∞zec.
P°φkazy ve vlastnosti SQL budou provedeny, p°i volßnφ metody
Open
nebo metody ExecSQL. Pokud vlastnost SQL obsahuje p°φkaz
SELECT,
pak k jeho pou₧itφ volßme metodu Open, pokud pou₧φvßme p°φkazy INSERT,
UPDATE
nebo DELETE, pak je nutno k provedenφ p°φkazu pou₧φt metodu ExecSQL.
Nastavenφ vlastnosti
Active na true mß stejn² efekt jako
volßnφ metody Open.
V dalÜφ aplikaci si ukß₧eme zm∞nu vlastnosti SQL za b∞hu aplikace.
ZaΦneme v²voj novΘ aplikace, na formulß° umφstφme komponentu Query
(zm∞nφme u nφ DatabaseName na Sademo), komponenty DataSource
a DBGrid (nastavφme u nich vlastnosti obvykl²m zp∙sobem) a dv∞ tlaΦφtka
(s texty Customer a Employee). Obsluha stisku tlaΦφtka
Customer
bude tvo°ena p°φkazy:
Query1->SQL->Clear();
Query1->SQL->Add("SELECT
* FROM Customer");
Query1->Open();
a obsluhu stisku druhΘho tlaΦφtka tvo°φ:
Query1->SQL->Clear();
Query1->SQL->Add("SELECT
* FROM Employee");
Query1->Open();
Nynφ p°i stisku n∞kterΘho z tlaΦφtek se zobrazφ p°φsluÜnß tabulka.
P°φkaz SQL SELECT zφskßvß data z databßze. M∙₧eme pou₧φvat i jeho slo₧it∞jÜφ
tvary. Nap°.
Query1->SQL->Clear();
Query1->SQL->Add("SELECT
id, lname, city FROM Customer");
Query1->SQL->Add("WHERE
city = 'Santa Fe'");
Query1->Open();
P°φkaz SQL DELETE ruÜφ zßznamy z datovΘ mno₧iny (m∙₧eme ruÜit pouze
zßznamy, jejich₧ zruÜenφ neporuÜφ integritu databßze). M∙₧eme pou₧φt nap°.
tento k≤d:
Query1->SQL->Clear();
Query1->SQL->Add("DELETE
FROM Contact WHERE first_name = 'Rose'");
Query1->ExecSQL();
V tomto p°φpad∞ je nutno volat metodu ExecSQL. TotΘ₧ platφ i
o dalÜφch p°φkladech. P°φkaz SQL INSERT vklßdß zßznam do datovΘ mno₧iny.
Nap°.
Query1->SQL->Clear();
Query1->SQL->Add("INSERT
INTO Department");
Query1->SQL->Add("(Dept_id,
Dept_name, Dept_head_id)");
Query1->SQL->Add("VALUES
(600, 'Nic', 501)");
Query1->ExecSQL();
Tento zßznam lze vlo₧it pouze jednou, p°i druhΘm vlo₧enφ ji₧ nastßvß
shoda hodnot primßrnφho klφΦe (je signalizovßna chyba). Obdobn∞ lze pou₧φt
i p°φkaz UPDATE. Nap°.
Query1->SQL->Clear();
Query1->SQL->Add("UPDATE
Department");
Query1->SQL->Add("SET
Dept_name = 'xxxxx'");
Query1->SQL->Add("WHERE
Dept_id = 500");
Query1->ExecSQL();
Vidφme, ₧e p°φkazy SQL m∙₧eme pou₧φvat jak pot°ebujeme.
P°φkazy SQL mohou takΘ pou₧φvat parametry. Parametry v p°φkazech SQL se
podobajφ prom∞nn²m v C++. Parametr v p°φkazu SQL p°edchßzφ dvojteΦka. Podφvejte
se na nßsledujφcφ p°φkaz SQL:
SELECT * FROM Contact
WHERE first_name = :Param1
Parametr se jmenuje Param1. P°i provßd∞nφ tohoto p°φkazu hodnota
Param1
ve vlastnosti Params je pou₧ita mφsto jmΘna parametru. Nap°.
Query1->SQL->Add("SELECT
* FROM Contact WHERE first_name = :Param1");
Query1->ParamByName("Param1")->AsString
= "John";
Query1->Open();
Hodnoty parametr∙ lze nastavovat b∞hem nßvrhu
ve vlastnosti Params pomocφ dialogovΘho okna parametr∙, ale v∞tÜφ
v²znam mß nastavovßnφ parametr∙ za b∞hu aplikace. V p°edchozφ ukßzce je
pou₧ita metoda ParamByName k nastavenφ hodnoty parametru Param1.
Parametr lze nastavit i p°φkazem:
Query1->Params->Items[0]->AsString
= "John";
Zde k nastavenφ hodnoty parametru je pou₧ita
vlastnost Items t°φdy TParams. V²hodn∞jÜφ je ale pou₧itφ
prvnφho zp∙sobu, proto₧e si nemusφme pamatovat po°adφ parametr∙.
Ne vÜechny prvky p°φkaz∙ SQL mohou b²t parametrizovatelnΘ.
Nap°. v∞tÜina server∙ SQL neumo₧≥uje pou₧φt parametr mφsto jmΘna tabulky.
Komponenta StoredProc reprezentuje ulo₧enou
proceduru na databßzovΘm serveru. Ulo₧enΘ procedury jsou mno₧iny p°φkaz∙
SQL, kterΘ jsou provßd∞ny jako jeden celek (zaobalujφ Φasto provßd∞nΘ databßzovΘ
·lohy). P°φkazy ulo₧enΘ procedury jsou provßd∞ny na serveru.
N∞kterΘ ulo₧enΘ procedury pou₧φvajφ parametry
a jinΘ ne. Pro ulo₧enou proceduru bez parametru, nastavφme jmΘno procedury
a provedeme ji:
StoredProc1->StoredProcName
= "sp_proc";
StoredProc1->Prepare();
StoredProc1->ExecProc();
Pro ulo₧enou proceduru s parametry je nutno nejprve
nastavit parametry a potom proceduru provΘst:
StoredProc1->StoredProcName
= "sp_proc1";
StoredProc1->ParamByName("cislo")->Value
= 6665;
StoredProc1->Prepare();
StoredProc1->ExecProc();
Jeliko₧ cviΦnß databßze SQL Anywhere neobsahuje
vhodnou ulo₧enou proceduru, neukß₧eme si jejich pou₧itφ.
Komponenta UpdateSQL poskytuje mo₧nost aplikovßnφ
zm∞n na datovou mno₧inu urΦenou pro Φtenφ p°i povolenΘ odlo₧enΘ aktualizaci.
Normßln∞ datovß mno₧ina urΦenß pouze pro Φtenφ dovoluje ·daje pouze Φφst.
Kdy₧ povolφme odlo₧enou aktualizaci, pak je mo₧no takovouto datovou mno₧inu
modifikovat a v²sledky t∞chto modifikacφ zapsat do databßze. V∞tÜina databßzφ
typu klient/server mß implicitnφ akce, kterΘ jsou provßd∞ny, kdy₧ jsou
aplikovßny zm∞ny v aktualizaΦnφ vyrovnßvacφ pam∞ti. Komponenta UpdateSQL
umo₧≥uje poskytnout naÜe vlastnφ p°φkazy SQL, pro p°φpad, kdy₧ mß b²t aktualizovßn,
vlo₧en nebo zruÜen zßznam v datovΘ mno₧in∞ urΦenΘ pouze pro Φtenφ. Nap°.
komponenta UpdateSQL umo₧≥uje specifikaci implicitnφch hodnot pro
jistΘ polo₧ky v datovΘ mno₧in∞.
Vlastnost DeleteSQL umo₧≥uje definovat
dotaz SQL, kter² bude proveden, kdy₧ odlo₧enΘ aktualizace jsou aplikovßny
a vyrovnßvacφ pam∞¥ aktualizacφ obsahuje ruÜenφ zßznam∙. Obdobn∞ je mo₧no
ve vlastnostech InsertSQL a ModifySQL nadefinovat dotaz SQL
pro vklßdßnφ a modifikaci.
Komponenta DataSource poskytuje mechanismus
k propojenφ komponent datov²ch mno₧in (Table, Query a StoredProc)
s vizußlnφmi komponentami, kterΘ zobrazujφ data (DBGrid, DBEdit,
DBListBox
atd.). Zßkladnφ funkcφ tΘto komponenty je usnadn∞nφ provßd∞nφ zm∞n v naÜφ
aplikaci. VÜechny datovΘ komponenty na formulß°i jsou propojeny s DataSource,
kter² je pak propojen s datov²mi mno₧inami. Proto₧e datovΘ komponenty nejsou
propojeny p°φmo s datovou mno₧inou, lze snadno zm∞nit datov² zdroj a nenφ
nutno se zab²vat vÜemi datov²mi komponentami. Umo₧≥uje to takΘ snadnou
zm∞nu nap°. z datovΘ mno₧iny Table na Query.
DataSource mß jen n∞kolik vlastnostφ.
Vlastnost DataSet je pou₧ita k urΦenφ p°ipojenΘ datovΘ mno₧iny.
Vlastnost Enabled urΦuje zda p°ipojenΘ datovΘ komponenty budou zobrazovat
data. Je-li tato vlastnost nastavena na true, pak data jsou zobrazovßna,
mß-li ale hodnotu false, pak datovΘ komponenty jsou prßzdnΘ.
Komponenta Session spravuje databßzovΘ sezenφ.
Poka₧dΘ, kdy₧ spouÜtφme databßzovou aplikaci, pak BDE vytvß°φ globßlnφ
objekt Session. M∙₧eme jej pou₧φt pro p°φstup k souΦasnΘmu databßzovΘmu
sezenφ. Pokud nevytvß°φme vφcevlßknovΘ aplikace, pak nenφ nutno vytvß°et
sv∙j vlastnφ objekt t°φdy TSession, ale vystaΦφ nßm objekt vytvo°en²
implicitn∞. TSession mß n∞kolik zajφmav²ch metod. Metody AddAlias
a AddStandardAlias lze pou₧φt k vytvo°enφ p°ezdφvky BDE za b∞hu
aplikace. Metody GetAliasNames a GetDatabaseNames mohou b²t
pou₧ity k zφskßnφ seznamu databßzφ. Pou₧ijeme je, kdy₧ chceme nabφdnout
u₧ivateli mo₧nost volit databßzi ze seznamu. Seznam lze nap°. vlo₧it do
kombinovanΘho okna:
Session1->GetDatabaseNames(ComboBox1->Items);
Obdobn∞ lze pou₧φt i metody GetTableNames
a GetStoredProcNames.
Komponenta Database umo₧≥uje provßd∞t n∞kterΘ
databßzovΘ operace. Pot°ebujeme ji pouze, kdy₧ chceme tyto specißlnφ operace
provßd∞t. Nßsleduje popis t∞chto situacφ.
Vlastnost KeepConnections je pou₧ita k
°φzenφ zpracovßnφ databßzovΘho p°ipojenφ p°i uzav°enφ datovΘ mno₧iny. Pokud
tato vlastnost mß hodnotu false, pak p°i uzav°enφ poslednφ datovΘ
mno₧iny, je p°ipojenφ k databßzi zruÜeno. To vy₧aduje op∞tovnΘ p°ipojenφ
k databßzi p°i dalÜφm otev°enφ datovΘ mno₧iny. Nastavφme-li tuto vlastnost
na true, pak p°ipojenφ k databßzi je stßle udr₧ovßno.
DalÜφ v²znam pou₧itφ komponenty Database
je °φzenφ operace p°ihlaÜovßnφ. Pokud vlastnost LoginPrompt mß hodnotu
false,
pak lze nastavovat p°ihlaÜovacφ parametry. Nap°.
Database1->Params->Values["user
name"] = "DBA";
Database1->Params->Values["password"]
= "SQL";
Tyto p°φkazy je mo₧no pou₧φt i jako obsluhu udßlosti
OnLogin.
DalÜφ d∙vod k pou₧itφ komponenty Database
je °φzenφ transakcφ. Normßln∞ jsou transakce °φzeny BDE. N∞kdy ale transakce
pot°ebujeme °φdit sami. Transakce je zahßjena volßnφm metody StartTransaction.
ProvedenΘ zm∞ny jsou do databßze zapsßny a₧ p°i volßnφ metody Commit.
Zatφm nezapsanΘ zm∞ny je mo₧no zruÜit metodou Rollback. ┌rove≥ izolace
transakcφ je °φzena hodnotou vlastnosti TransIsolation.
Komponenta BatchMove je pou₧φvßna ke kopφrovßnφ
zßznam∙ z jednΘ datovΘ mno₧iny do jinΘ. Vlastnost Source specifikuje
zdrojovou datovou mno₧inu a vlastnost Destination cφlovou datovou
mno₧inu. Vlastnost Mapping je vy₧adovßna, pokud datovΘ mno₧iny nemajφ
identickΘ sloupce. Tato vlastnost je seznam °et∞zc∙ tvaru:
FirstName = FName
LastName = LName
Notes = Comments
JmΘna sloupc∙ na levΘ stran∞ jsou cφlovΘ sloupce
a sloupce napravo jsou zdrojovΘ sloupce. Kopφrovßnφ je spouÜt∞no metodou
Execute.
Vlastnost Mode urΦuje re₧im kopφrovßnφ.
T°φda TField reprezentuje polo₧ky (sloupce)
v databßzi. Tato t°φda nßm umo₧nφ nastavit atributy polo₧ek. Tyto atributy
zahrnujφ datov² typ (string, integer, float, atd.), velikost polo₧ky, index
apod. Hodnotu polo₧ky m∙₧eme takΘ Φφst nebo nastavovat prost°ednictvφm
vlastnostφ typu AsString, AsVariant a AsInteger.
TField je p°edek vφce specializovan²ch
t°φd polo₧ek. Potomci TField zahrnujφ TStringField, TIntegerField,
TSmallIntField,
TWordField,
TFloatField,
TCurrencyField,
TBCDField,
TBooleanField,
TDataTimeField,
TTimeField,
TBlobField,
TBytesField,
TVarBytesField,
TMemoField
a TGraphicField. Tyto odvozenΘ t°φdy rozÜi°ujφ funkΦnost zßkladnφ
t°φdy jen nepatrn∞. Nap°. t°φdy Φφseln²ch polo₧ek majφ vlastnost DisplayFormat,
kterß urΦuje zp∙sob zobrazenφ Φφsla a vlastnost
EditFormat, urΦujφcφ
zp∙sob zobrazenφ Φφsla p°i editaci. Ka₧d² potomek
TField odpovφdß
specifickΘmu typu databßzovΘ polo₧ky. T°φda TIntegerField je pou₧ita,
kdy₧ typ polo₧ky je Integer, atd.
K vlastnostem TField m∙₧eme p°istupovat
b∞hem nßvrhu pomocφ Editoru polo₧ek. Vlastnosti vybranΘ polo₧ky v Editoru
polo₧ek jsou zobrazeny v Inspektoru objekt∙.
D°φve ne₧ m∙₧eme polo₧ku Φφst nebo nastavovat
musφme n∞jak²m zp∙sobem polo₧ku lokalizovat. To lze ud∞lat t°emi zp∙soby.
Zp°φstup≥ovßnφ polo₧ky pomocφ jejφho ukazatele je nejsnadn∞ji pou₧itelnß
metoda. Lze ji ale pou₧φt pouze tehdy, kdy₧ mßme p°idanΘ polo₧ky pomocφ
Editoru polo₧ek. P°i p°idßvßnφ polo₧ek pomocφ Editoru polo₧ek, C++ Builder
vytvß°φ ukazatel na ka₧dou polo₧ku spojenφm jmΘna tabulky a jmΘna polo₧ky.
Pro tabulku Table1 a °et∞zcovou polo₧ku FirstName,
C++ Builder vytvo°φ ukazatel typu TStringField nazvan² Table1FirstName.
Tento ukazatel lze pou₧φt pro p°φstup k polo₧ce:
Table1FirstName->Value
= "John";
Vlastnost Fields nabφzφ dalÜφ mo₧nost
p°φstupu k polo₧ce - podle pozice. Pokud vφme, ₧e polo₧ka LastName
je prvnφ polo₧kou v tabulce, pak k nφ lze p°istupovat takto:
Edit1->Text = Table1->Fields[0]->Value;
T°etφ zp∙sob zp°φstupn∞nφ polo₧ky pou₧φvß metodu
FieldByName.
Zde pot°ebujeme znßt pouze jmΘno polo₧ky:
Table1->FieldByName("LastName")->AsString
= Edit1->Text;
FieldByName vracφ ukazatel TField.
Kdy₧ ji₧ mßme ukazatel na jistou polo₧ku, pak
lze zm∞nit jejφ hodnotu pomocφ vlastnosti Value nebo n∞kterou z
vlastnostφ As (AsString, AsInteger, AsBoolean,
atd.). Tyto vlastnosti provßd∞jφ p°evod z jednoho datovΘho typu na jin².
Nastavenφ hodnoty polo₧ky je jednoduchΘ, nap°.
Table1->Edit();
Table1->FieldByName("LastName")->AsString
= Edit1->Text;
Table1->Post();
Metoda Edit uvede tabulku do editaΦnφho
re₧imu, tabulku je mo₧no editovat a metodou Post zapφÜeme zm∞ny
do databßze.
TField mß udßlosti OnChange a OnValidate.
Udßlost OnChange je generovßna v₧dy p°i zm∞n∞ hodnoty polo₧ky (po
zßpisu zm∞ny do databßze). Tuto udßlost lze pou₧φt k oznßmenφ zm∞ny polo₧ky.
Udßlost OnValidate vznikß p°ed odeslßnφm dat do databßze. V jejφ
obsluze je mo₧no kontrolovat p°φpustnost dat. Nap°.
void __fastcall TForm1::Table1ACCT_NBRValidate(TField
*Sender)
{
if (Sender->AsInteger
< 3000)
throw (EDBEditError("ChybnΘ Φφslo."));
}
Kdy₧ generujeme v²jimku, pak zßpis dat do databßze
je zruÜen.
Tφm je naÜe seznamovßnφ s databßzov²mi aplikacemi
zatφm dokonΦeno. Podrobn² popis vÜech databßzov²ch komponent bude uveden
pozd∞ji ve 4. Φßsti p°φruΦky.
Nynφ se budeme zab²vat v²vojem aplikacφ,
kterΘ chceme uvΘst na mezinßrodnφ trh. U t∞chto aplikacφ je zapot°ebφ se
zam∞°it na internacionalizaci a lokalizaci. Internacionalizace je proces
umo₧≥ujφcφ naÜφ aplikaci pracovat ve vφce zemφch (respektovßnφ kulturnφch
konvencφ cφlovΘho stßtu a takΘ jazyka). Lokalizace je proces transformace
aplikace na funkce ve specifickΘm stßt∞. Nap°. aplikaci je nutno modifikovat
k respektovßnφ jist²ch zßkon∙ v r∙zn²ch stßtech.
Vytvo°it internacionalizovanou aplikaci
nenφ obtφ₧nΘ. Musφme umo₧nit naÜemu k≤du zpracovßvat °et∞zce z mezinßrodnφ
znakovΘ mno₧iny, musφme navrhnout naÜe u₧ivatelskΘ rozhranφ, aby umo₧≥ovalo
zm∞nit lokalizaci a je takΘ nutno izolovat vÜechny zdroje, kterΘ musφ b²t
lokalizovßny.
Musφme se ujistit, ₧e k≤d naÜφ
aplikace m∙₧e zpracovßvat °et∞zce v r∙zn²ch jazycφch. Verze US Windows
95 a Windows NT pou₧φvß znakovou mno₧inu ANSI Latin-1 (1252). JinΘ verze
Windows pou₧φvajφ jinΘ znakovΘ mno₧iny. Nap°. Japonskß verze Windows pou₧φvß
znakovou mno₧inu Shift-Jis (k≤dovß strßnka 932), ve kterΘ japonskΘ znaky
jsou reprezentovßny jedno nebo dvou slabikov²mi k≤dy.
N∞kdy je zapot°ebφ provΘst p°evod
mezi znakovou mno₧inou Windows (ANSI) a znakovou mno₧inou specifikovanou
k≤dovou strßnkou u₧ivatelova poΦφtaΦe (nazvanou znakovß mno₧ina OEM). Nap°.
BDE oΦekßvß znakovou mno₧inu OEM ve volßnφch funkcφ API. Pokud pou₧ijeme
databßzovΘ komponenty VCL, pak nenφ nutno se zab²vat p°evodem mezi znakov²mi
mno₧inami OEM a ANSI. Tyto komponenty provedou vÜechny nutnΘ p°evody automaticky.
P°i p°φmΘm volßnφ API BDE ale musφme provΘst p°evod mezi znakovou mno₧inou
ANSI pou₧φvanou VCL a znakovou mno₧inou OEM pou₧φvanou BDE.
N∞kterΘ jazyky majφ vφce znak∙,
ne₧ je mo₧no ulo₧it do jednΘ slabiky. Tyto jazyky majφ znaky reprezentovanΘ
jednoslabikov²m k≤dem a jinΘ znaky reprezentovanΘ dvouslabikov²m k≤dem.
Kdy₧ zapisujeme k≤d pro tyto jazyky, pak musφme zajistit, zpracovßnφ vÜech
°et∞zc∙ pomocφ funkcφ, kterΘ poΦφtajφ s jedno i dvouslabikov²mi znaky.
V nßpov∞d∞ C++ Builderu pod heslem International APInalezneme
seznam vÜech funkcφ RTL, kterΘ umo₧≥ujφ pracovat s vφceslabikov²mi znaky.
Nesmφme zapomenout ani na to, ₧e dΘlka °et∞zce ve slabikßch neodpovφdß
dΘlce °et∞zce ve znacφch. Je takΘ nutno b²t opatrn² p°i p°edßvßnφ znaku
jako parametru funkci, nebo¥ velikost znaku obecn∞ nenφ znßma. V tomto
p°φpad∞ je vhodnΘ znaky p°edßvat jako ukazatel na znak nebo jako °et∞zec.
Jinou mo₧nostφ prßce s t∞mito znakov²mi
mno₧inami je p°evedenφ vÜech znak∙ na ÜirokΘ znaky (nap°. Unicode). èirokΘ
znaky jsou v₧dy dvouslabikovΘ. Pou₧itφ dek≤dovacφho schΘmatu Üirok²ch znak∙
mß °adu v²hod. Je zde p°φm² vztah mezi poΦtem slabik °et∞zce a poΦtem znak∙
°et∞zce. Nemusφme mφt takΘ obavu, ₧e znak budeme hledat od poloviny jinΘho
znaku. Velkou nev²hodou prßce s Üirok²mi znaky je to, ₧e Windows 95 nepodporuje
ÜirokΘ znaky ve volßnφch funkcφ API.
K aplikacφm m∙₧eme p°idßvat specißlnφ
slu₧by. Nap°. pro mnohoznakovΘ jazyky, m∙₧eme po₧adovat °φzenφ IME (Input
Method Editor), kterΘ je pou₧ito pro p°evod stisku klßves u₧ivatelem na
znakov² °et∞zec. Komponenty VCL Φasto nabφzejφ podporu pro programovßnφ
IME. V∞tÜina Windowsovsk²ch ovladaΦ∙, kterΘ p°φmo pracujφ se vstupem textu
majφ vlastnost
ImeName umo₧≥ujφcφ specifikaci pot°ebnΘho IME. Globßlnφ
prom∞nnß
Screen poskytuje informace o IME dostupn²ch na naÜem systΘmu.
Nynφ se budeme zab²vat nßvrhem u₧ivatelskΘho
rozhranφ internacionalizovan²ch aplikacφ. VÜechen text zobrazovan² u₧ivatelsk²m
rozhranφm musφ b²t p°elo₧en. Texty v jednom jazyku mohou b²t kratÜφ ne₧
jejich p°eklad. Musφme tedy poΦφtat s tφm, ₧e dΘlka text∙ se m∙₧e zv∞tÜit.
Dialogovß okna, stavovΘ °ßdky apod. musφ mφt dostatek mφsta pro zobrazenφ
delÜφch text∙. Pokud aplikace pou₧φvß obrßzky, pak je vhodnΘ pou₧φvat takovΘ,
kterΘ nevy₧adujφ p°eklad (nepou₧φvßme na obrßzcφch text). Je vhodnΘ takΘ
nepou₧φvat obrßzky, kterΘ jsou specifickΘ pro jistou kulturu.
Formßty datumu, Φasu, finanΦnφch
Φßstek jsou takΘ zßvislΘ na cφlovΘ zemi. Pokud pou₧φvßme pouze formßty
Windows, pak se jejich p°evodem nemusφme zab²vat. Po°adφ °azenφ °et∞zc∙
se takΘ v r∙zn²ch zemφch liÜφ. Mnoho evropsk²ch jazyk∙ pou₧φvß diakritickß
znamΘnka, kterß se v r∙zn²ch zemφch °adφ r∙zn∞. V n∞kter²ch zemφch existujφ
dvouznakovΘ kombinace, kterΘ jsou chßpßny jako jeden znak. N∞kdy jeden
znak je °azen jako dva znaky.
NejobvyklejÜφ ·loha lokalizace aplikace
je p°eklad °et∞zc∙, kterΘ se zobrazujφ v u₧ivatelskΘm rozhranφ. Je vhodnΘ
vÜechny °et∞zce u₧ivatelskΘho rozhranφ ulo₧it do samostatnΘho modulu. C++
Builder automaticky vytvß°φ DFM soubor obsahujφcφ zdroje pro naÜi nabφdku,
dialogovß okna a bitovΘ mapy. Mimo t∞chto prvk∙ u₧ivatelskΘho rozhranφ,
je takΘ vhodnΘ izolovat vÜechny °et∞zce (nap°. chybovΘ zprßvy). Zdroje
°et∞zc∙ nejsou vklßdßny do souboru DFM, ale m∙₧eme je ulo₧it do RD souboru.
IzolovanΘ zdroje zjednoduÜujφ proces
p°ekladu do jinΘho jazyka. Zdroje mohou b²t p°elo₧eny a vytvo°ena DLL zdroj∙.
DLL zdroj∙ umo₧≥uje vytvo°it program, kter² podporuje mnoho jazyk∙, a to
pouhou v²m∞nou DLL zdroj∙. Toto jsme vid∞li v aplikaci textovΘho editoru
v kapitole
Textov² editor II.
Pr∙vodce Resource DLL pou₧ijeme
k vytvo°enφ DLL zdroj∙ pro nßÜ program. P°i pou₧itφ tohoto pr∙vodce musφme
mφt otev°en² ulo₧en² projekt. M∙₧eme vytvo°it DLL zdroj∙ pro ka₧d² po₧adovan²
jazyk. P°φpony t∞chto DLL urΦujφ cφlovΘ mφsto (prvnφ dva znaky urΦujφ jazyk
a t°etφ znak zemi). Nßsledujφcφ k≤d m∙₧e b²t pou₧it k zφskßnφ k≤du mφsta
pro cφlov² p°eklad:
/*
Pln∞nφ ListBoxu °et∞zci a jejich p°i°azen²mi jazyky se zem∞mi */
BOOL
__stdcall EnumLocalesProc(char* lpLocaleString)
{
AnsiString LocaleName, LanguageName, CountryName;
LCID lcid;
lcid = StrToInt("$" + AnsiString(lpLocaleString));
LocaleName = GetLocaleStr(lcid, LOCALE_SABBREVLANGNAME, "");
LanguageName = GetLocaleStr(lcid, LOCALE_SNATIVELANGNAME, "");
CountryName = GetLocaleStr(lcid, LOCALE_SNATIVECTRYNAME, "");
if (lstrlen(LocaleName.c_str()) > 0)
Form1->ListBox1->Items->Add(LocaleName + ":" + LanguageName + "-" + CountryName);
return TRUE;
}
/*
Toto volßnφ zp∙sobφ provedenφ zp∞tnΘho volßnφ pro ka₧dΘ mφsto */
EnumSystemLocales((LOCALE_ENUMPROC)EnumLocalesProc,
LCID_SUPPORTED);
EXE soubory, DLL a balφΦky, kterΘ tvo°φ naÜφ aplikaci obsahujφ
vÜechny pot°ebnΘ zdroje. K nahrazenφ t∞chto zdroj∙ jejich lokalizovanou
verzφ, staΦφ pouze nabφdnout lokalizovanou DLL zdroj∙, kterß mß stejnΘ
jmΘno jako soubory EXE, DLL nebo BPL. P°i spuÜt∞nφ aplikace je testovßno
mφsto lokßlnφho systΘmu. Pokud je nalezena DLL zdroj∙ se stejn²m jmΘnem,
pak je testovßna jejφ p°φpona. Pokud p°φpona vyhovuje jazyku a zemi lokßlnφho
systΘmu, pak naÜe aplikace pou₧φvß zdroje z tΘto DLL a to mφsto zdroj∙
ze soubor∙ EXE, DLL nebo BPL. Nenφ-li nalezena vyhovujφcφ DLL zdroj∙, pak
jsou pou₧ity p∙vodnφ zdroje.
Kdy₧ naÜi aplikaci chceme pou₧φt s jinou DLL zdroj∙,
ne₧ je urΦeno lokßlnφm systΘmem, musφme nastavit polo₧ku v registrech Windows.
Pod klφΦ
HKEY_CURRENT_USER\Software\Borland\Locales p°idßme ·plnou
specifikaci naÜφ aplikace jako °et∞zcovou hodnotu a nastavφme datovou hodnotu
na p°φponu po₧adovanΘ DLL zdroj∙. Tφm je mo₧no dosßhnout zm∞ny jazyka aplikace
bez nutnosti m∞nit mφsto naÜeho systΘmu.
Nap°. nßsledujφcφ funkce m∙₧e b²t pou₧ita v instalaΦnφm
programu k nastavenφ hodnoty klφΦe registru, kterß urΦuje mφsto pou₧itΘ
p°i spuÜt∞nφ aplikace.
void
SetLocalOverrides(char* FileName, char* LocaleOverride)
{
HKEY Key;
const char* LocaleOverrideKey = "Software\\Borland\\Locales";
if (RegOpenKeyEx(HKEY_CURRENT_USER, LocaleOverrideKey, 0,
KEY_ALL_ACCESS, &Key) == ERROR_SUCCESS) {
if (lstrlen(LocaleOverride) == 3)
RegSetValueEx(Key, FileName, 0, REG_SZ, (const BYTE*)LocaleOverride, 4);
RegCloseKey(Key);
}
}
V naÜφ aplikaci pou₧ijeme globßlnφ funkci FindResourceHInstance
k zφskßnφ madla souΦasnΘho modulu zdroj∙. Nap°.
LoadString(FindResourceHInstance(HInstance),
IDS_AmountDueName,
szQuery, sizeof(szQuery));
Kdy₧ ji₧ mßme aplikaci internacializovanou, pak m∙₧eme vytvo°it
lokalizovanΘ verze pro r∙znΘ zem∞, do kter²ch ji chceme distribuovat. NaÜe
prvky rozhranφ jsou izolovßny v souborech DFM a RC. DFM soubor si zobrazφme
jako text (volbou View As Text v mφstnφ nabφdce nßvrhovΘho formulß°e)
a provedeme po₧adovan² p°eklad. Soubory RC jsou textovΘ soubory a m∙₧eme
je tedy snadno p°evΘst do cφlovΘho jazyka. Je takΘ nutno provΘst dalÜφ
·pravy, t²kajφcφ se r∙zn²ch specifik cφlovΘ zem∞.