14. DatabßzovΘ aplikace II
  1. 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:
  2. 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φ.
  3. 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.

  4. 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.
  5. 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:

  6. 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.
  7. 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:

  8. 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.
  9. 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.

  10. 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φ.
  11. 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∞.

  12. 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.
  13. 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.

  14. 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Θ.
  15. 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:

  16. Session1->GetDatabaseNames(ComboBox1->Items);
    Obdobn∞ lze pou₧φt i metody GetTableNames a GetStoredProcNames.
  17. 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φ.

  18. 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.
  19. 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:

  20. 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φ.
  21. 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.

  22. 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.
  23. 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.
  24. 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.

  25. 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 API nalezneme 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.
  26. 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.

  27. 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.
  28. 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.

  29. 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);
  30. 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.

  31. 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));
  32. 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∞.
14. DatabßzovΘ aplikace II