6. Textov² editor I 
  1. V tΘto kapitole se budeme zab²vat vytvß°enφm slo₧it∞jÜφ aplikace. Bude to MDI aplikace textovΘho editoru. Zopakujeme si takΘ n∞kterΘ v∞ci, se kter²mi jsme se ji₧ seznßmili v p°edchozφch kapitolßch. Aplikaci budeme vytvß°et v t∞chto krocφch:
  2. V²voj naÜφ aplikace zaΦneme volbou File | New Application, a zm∞nφme tyto vlastnosti vytvo°enΘho formulß°e: Name na FrameForm, Caption na Text Editor C++ a FormStyle na fsMDIForm. K vytvo°enφ pod°φzenΘho formulß°e p°idßme nov² prßzdn² formulß° do projektu a u tohoto formulß°e nastavφme vlastnosti: Name na EditForm, Caption na Untitled a FormStyle na fsMDIChild. Soubory projektu je vhodnΘ nynφ ulo₧it. Soubor formulß°e rßmu ulo₧φme pod jmΘnem MDIFrame.CPP, soubor pod°φzenΘho okna pod jmΘnem MDIEdit.CPP a projektov² soubor pod jmΘnem TEXTEDIT.BPR (pro projekt vytvo°φme specißlnφ adresß°).
    Ve formulß°i rßmu vytvo°φme tuto nabφdku (Φφsla v zßvorkßch jsou hodnoty vlastnosti GroupIndex; aplikace bude mφt anglickou nabφdku):
     
    &File (0) &Window (9)
    &New &Tile
    &Open ... &Cascade
    -----------  &Arrange icons
    E&xit

    Dßle vytvo°φme nabφdku pod°φzenΘho formulß°e (pro prvky nabφdky Edit zadßme takΘ hodnoty vlastnosti ShortCut; jsou uvedeny ve t°etφm sloupci):
     

    &File (0) &Edit (1)  &Character (1)
    &New  Cu&t  Ctrl+X &Left
    &Open ...  &Copy Ctrl+C &Right
    &Save  &Paste  Ctrl+V &Center
    Save &as ...  De&lete Ctrl+D  ---------
    &Close  -------- &Word Wrap
    -----------  Select &all Ctrl+A  --------
    &Print ...  &Font ...
    Printer setup ...
    -----------
    E&xit

    Pro prvky Left a Word Wrap z nabφdky Character nastavφme vlastnost Checked na true (zajiÜt∞nφ implicitnφho chovßnφ editoru).
    NaÜe aplikace provßdφ p°i otev°enφ pod°φzenΘho okna nßhradu nabφdky Soubor rßmu stejnojmennou nabφdkou pod°φzenΘho okna. Ke sdφlenφ obsluh udßlostφ mezi t∞mito nabφdkami, vytvo°φme obsluhu udßlosti k prvku nabφdky formulß°e rßmu a v obsluze udßlosti odpovφdajφcφho prvku nabφdky pod°φzenΘho formulß°e volßme tuto obsluhu formulß°e rßmu. Obsluhu udßlosti OnClick prvku nabφdky File | Exit formulß°e rßmu tvo°φ p°φkaz:
    Close();
    a obsluha v pod°φzenΘm formulß°i bude tvo°ena p°φkazem:
    FrameForm->Exit1Click(Sender);
    Nynφ, kdy₧ se pokusφme spustit vytvß°enou aplikaci, p°ekladaΦ se zastavφ na tΘto novΘ obsluze a vypφÜe signalizaci oznamujφcφ, ₧e FrameForm je nedefinovan². Musφme tedy vlo₧it hlaviΦkov² soubor pro jednotku FrameForm do souboru MDIEdit.CPP.
    Pod°φzen² formulß° musφme vy°adit ze seznamu automatickΘho vytvß°enφ formulß°∙. Pod°φzen² formulß° budeme vytvß°et v obsluze udßlosti volby File | New. V hlavnφm formulß°i bude tato obsluha tvo°ena p°φkazem:
    EditForm = new TEditForm(this);
    a v pod°φzenΘm formulß°i:
    FrameForm->New1Click(Sender);
    Jestli₧e nynφ p°eklßdßme naÜi aplikaci, pak Builder generuje chybovΘ hlßÜenφ, nebo¥ v jednotce hlavnφho formulß°e neznß TEditForm. Tento problΘm vy°eÜte sami.
    Pod°φzenΘ okno budeme pot°ebovat takΘ uzav°φt. Vytvo°φme tedy obsluhu volby File | Close (v pod°φzenΘm formulß°i). Je tvo°ena p°φkazem:
    Close();
    a dßle je nutno vytvo°it obsluhu OnClose pod°φzenΘho formulß°e s p°φkazem:
    Action = caFree;
    Vytvo°φme takΘ obsluhy voleb v nabφdce Window. Obsluha volby Tile je tvo°ena p°φkazem:
    Tile();
    obsluhu volby Cascade tvo°φ p°φkaz:
    Cascade();
    a obsluhu Arrange icons tvo°φ:
    ArrangeIcons();
    Vlastnost WindowMenu formulß°e rßmu nastavφme na Window1. Tφm dosßhneme p°idßvßnφ seznamu otev°en²ch oken do nabφdky Window. Titulek pod°φzenΘho okna by mohl obsahovat jmΘno otev°enΘho souboru. Pro ulo₧enφ tΘto informace p°idßme do soukromΘ Φßsti deklarace EditForm (do souboru MdiEdit.h):
    AnsiString PathName;
    a na zaΦßtek jednotky pod°φzenΘho okna vlo₧φme konstantu s implicitnφm jmΘnem okna:
    const AnsiString DefaultFileName = AnsiString("Untitled");
    Tuto konstantu pou₧ijeme v obsluze OnCreate pod°φzenΘho okna takto:
    PathName = DefaultFileName;
    Pozd∞ji, kdy₧ do editoru zavedeme soubor, p°i°adφme PathName aktußlnφ jmΘno souboru. To indikuje, ₧e editor obsahuje ulo₧en² soubor. Tφm mßme prvnφ krok vytvß°enφ aplikace hotov. Je zajiÜt∞no standardnφ MDI chovßnφ.

  3. Nynφ se budeme zab²vat vytvß°enφm textovΘho editoru v pod°φzenΘm okn∞. U komponenty RichEdit, kterou vlo₧φme do pod°φzenΘho okna,  nastavφme tyto vlastnosti: Align na alClient, BorderStyle na bsNone, ScrollBars na ssVertical, Name na Editor a vlastnost Lines vyprßzdnφme.

  4. V aplikaci textovΘho editoru u₧ivatel nastavuje zarovnßvßnφ textu pomocφ voleb v nabφdce Character. Vytvo°φme tedy obsluhu udßlosti OnClick pro prvek nabφdky Character | Left a p°ipojφme tuto obsluhu i k dalÜφm dv∞ma prvk∙m tΘto nabφdky. Obsluha bude tvo°ena p°φkazy (pracujeme zde s vlastnostφ Paragraph editoru; m∙₧eme m∞nit zarovnßvßnφ i Φßsti textu):
    Left1->Checked   = false;
    Right1->Checked  = false;
    Center1->Checked = false;
    if( dynamic_cast<TMenuItem *>(Sender) !=0)
      dynamic_cast <TMenuItem *>(Sender) ->Checked = true;
    if (Left1->Checked )
      Editor->Paragraph->Alignment = taLeftJustify;
    else if (Right1->Checked)
      Editor->Paragraph->Alignment= taRightJustify;
    else if (Center1->Checked)
      Editor->Paragraph->Alignment = taCenter;
    Komponenta editoru m∙₧e obsahovat vodorovn², svisl² nebo oba posuvnφky. P°i nßvrhu nastavφme poΦßteΦnφ hodnotu vlastnosti ScrollBars pro komponentu editoru na ssVertical. Kdy₧ aplikaci spustφme, editor obsahuje pouze svisl² posuvnφk (lßmßnφ °ßdk∙ je povoleno a text nenφ ÜirÜφ ne₧ aktußlnφ Üφ°ka editoru). Zakß₧eme-li lßmßnφ °ßdk∙, pak pot°ebujeme i vodorovn² posuvnφk. V obsluze volby Character | Word Wrap musφme tedy mimo nastavenφ vlastnosti WordWrap nastavovat i vlastnost ScrollBars. Provedeme to takto:
    Editor->WordWrap = !Editor->WordWrap;
    if (Editor->WordWrap)
      Editor->ScrollBars = ssVertical;
    else
      Editor->ScrollBars = ssBoth;
    Wordwrap1->Checked = Editor->WordWrap;
    TextovΘ editory umo₧≥ujφ p°enßÜet vybran² text mezi dokumenty. Objekt Clipboard zaobaluje schrßnku Windows a poskytuje metody pro prßci se schrßnkou. Objekt schrßnky je deklarovßn v jednotce Clipbrd. V naÜφ aplikaci (p°esn∞ji °eΦeno v souboru MDIEdit.h) p°idßme na zaΦßtek (za ostatnφ direktivy include) direktivu:
    #include <Clipbrd.hpp>
    D°φve ne₧ m∙₧eme vlo₧it text do schrßnky, musφme jej vybrat. Zv²razn∞nφ vybranΘho textu je zabudovßno v editaΦnφ komponent∞. Komponenta editoru mß n∞kolik vlastnostφ a metod pro prßci s vybran²m textem. SelText je vlastnost pou₧itelnß pouze p°i b∞hu aplikace a obsahuje °et∞zec reprezentujφcφ text vybran² v komponent∞. Metoda SelectAll vybφrß vÜechen text komponenty. Vlastnosti SelLength a SelStart obsahujφ dΘlku a poΦßteΦnφ pozici vybranΘho textu. Vytvo°φme obsluhu volby Edit | Select All (jinak se v²b∞rem textu nemusφme zab²vat). Obsluhu tvo°φ p°φkaz:
    Editor->SelectAll();
    Obsluhy voleb prßce se schrßnkou a volba Edit | Delete jsou v₧dy tvo°eny jednφm p°φkazem. Vytvo°te tyto obsluhy sami (ka₧dou obsluhu tvo°φ jeden z nßsledujφcφch p°φkaz∙):
    Editor->CutToClipboard();
    Editor->CopyToClipboard();
    Editor->PasteFromClipboard();
    Editor->ClearSelection();
    Nynφ ji₧ naÜe aplikace m∙₧e pracovat se schrßnkou. K editoru p°idßme i mφstnφ nabφdku s prvky Cut, Copy a Paste a p°ipojφme k nim ji₧ existujφcφ obsluhy udßlostφ. Bylo by ale vhodnΘ, aby v p°φpad∞, kdy nemßme vybrßn ₧ßdn² text, aby nebyly p°φstupnΘ prvky nabφdky Cut, Copy a Delete a v p°φpad∞, kdy nenφ nic ulo₧eno ve schrßnce, aby byl nep°φstupn² prvek Paste. T²kß se to obou nabφdek. Toto zakazovßnφ voleb v nabφdce provedeme v obsluze udßlosti OnClick pro prvek nabφdky Edit a pou₧ijeme ji i pro obsluhu OnPopup mφstnφ nabφdky. Obsluha bude tvo°ena p°φkazy:
    bool HasSelection;
    Paste1->Enabled = Clipboard()->HasFormat(CF_TEXT);
    Paste2->Enabled = Paste1->Enabled;
    HasSelection = Editor->SelLength > 0;
    Cut1->Enabled = HasSelection;
    Cut2->Enabled = HasSelection;
    Copy1->Enabled = HasSelection;
    Copy2->Enabled = HasSelection;
    Delete1->Enabled = HasSelection;
    Tφm jsme dokonΦili vytvß°enφ vlastnφho editoru.
  5. V dalÜφm kroku v²voje aplikace se budeme zab²vat pou₧itφm r∙zn²ch dialogov²ch oken Windows. Vyu₧ijeme je p°i otevφrßnφ soubor∙, zm∞n∞ pφsma a uklßdßnφ soubor∙. Pro zm∞nu pφsma vyu₧ijeme komponentu FontDialog (umφstφme ji na EditForm). Obsluha volby Character | Font bude tvo°ena p°φkazy:

  6. FontDialog1->Font= Editor->Font;
    if (FontDialog1->Execute())
      Editor->SelAttributes->Assign(FontDialog1->Font);
    Nem∞nφme zde vlastnost Font ale SelAttributes. Tφm dosßhneme zm∞nu pφsma pouze vybranΘho textu. Dßle se budeme zab²vat otevφrßnφm soubor∙. Vyu₧ijeme komponentu OpenDialog (tentokrßt ji musφme p°idat na formulß° rßmu) a nazveme ji OpenFileDialog. Nastavφme u nφ filtr soubor∙ a to takto: Rich text files (*.rtf), Plain text files (*.txt) a All files (*.*). Vytvo°φme obsluhu volby File | Open pro formulß° rßmu:
    if(OpenFileDialog->Execute()){
      EditForm=new TEditForm(this);
      EditForm->Open(OpenFileDialog->FileName);
    }
    a volßme tuto obsluhu v obsluze stejnΘ volby pod°φzenΘho formulß°e:
    FrameForm->Open1Click(Sender);
    V p°edchozφ obsluze volßme metodu Open. Tuto metodu musφme takΘ vytvo°it. Do ve°ejnΘ Φßsti deklarace TEditForm p°idßme:
    void __fastcall Open(const AnsiString AFileName);
    a do jednotky pod°φzenΘho formulß°e tuto metodu zapφÜeme:
    void __fastcall TEditForm::Open(const AnsiString AFileName)
    {
       PathName = AFileName;
       Caption = ExtractFileName(AFileName);
       Editor->Lines->LoadFromFile(PathName);
       Editor->SelStart = 0;
       Editor->Modified = false;
    }
    Kdy₧ editor zavede soubor, nastavφme hodnotu vlastnosti SelStart editoru na nulu. Toto urΦuje aktußlnφ pozici kurzoru. Dßle se budeme zab²vat uklßdßnφm souboru. NejjednoduÜÜφ p°φpad je op∞tovnΘ ulo₧enφ existujφcφho souboru. Kdy₧ u₧ivatel zvolφ File | Save, aplikace zapφÜe soubor pod stejn²m jmΘnem. Pouze pokud se takto sna₧φme ulo₧it nepojmenovan² soubor, jsme dotßzßni na jeho jmΘno. Obsluha volby File | Save (v pod°φzenΘm formulß°i) tedy bude tvo°ena p°φkazy:
    if(Caption == DefaultFileName){
      Saveas1Click(Sender);
    }
    else{
      Editor->Lines->SaveToFile(PathName);
      Editor->Modified = false;
    }
    Testujeme, zda soubor mß p°i°azenΘ jmΘno a pokud nemß, pak volßme obsluhu volby Save As. Pro zadßvßnφ jmΘna uklßdanΘho souboru p°idßme na pod°φzen² formulß° komponentu SaveDialog a zm∞nφme jejφ jmΘno na SaveFileDialog. Obsluha volby File | Save As bude tvo°ena p°φkazy:
    SaveFileDialog->FileName = PathName;
    if (SaveFileDialog->Execute() ){
      PathName= SaveFileDialog->FileName;
      Caption = ExtractFileName(PathName);
      Save1Click(Sender);
    }
    Tφm jsme dokonΦili dalÜφ etapu vytvß°enφ naÜφ aplikace, tj. pou₧φvßnφ dialogov²ch oken Windows.
  7. V dalÜφm kroku v²voje aplikace se budeme zab²vat tiskem. Builder poskytuje objekt Printer, kter² zapouzd°uje v∞tÜinu chovßnφ tiskßrny a zjednoduÜuje tak spoluprßci s tiskßrnou. Pro pou₧itφ tohoto objektu musφme p°idat hlaviΦkov² soubor Printers.hpp do hlaviΦkovΘho souboru pod°φzenΘho formulß°e. TiskovΘ funkce v naÜφ aplikaci budeme pou₧φvat pouze ΦßsteΦn∞. Umo₧nφme tisknout pouze obsah celΘho souboru nebo vybran² text. Pro nastavenφ tiskßrny vlo₧φme komponentu PrinterSetupDialog na pod°φzen² formulß°. Tato komponenta pracuje p°φmo s konfiguraΦnφmi soubory Windows a my nemusφme d∞lat prakticky nic. Obsluha volby File | Printer setup bude tvo°ena p°φkazem:

  8. PrinterSetupDialog1->Execute();
    Na pod°φzen² formulß° dßle vlo₧φme komponentu PrintDialog a vytvo°φme obsluhu volby File | Print s t∞mito p°φkazy:
    if (PrintDialog1->Execute()){
      try {
          Editor->Print(PathName);
      }
      catch(...){
          Printer()->EndDoc();
          throw;
      }
    }
    Nynφ naÜe aplikace mß schopnost tisknout textovΘ soubory.
  9. V poslednφm kroku v²voje naÜφ aplikace se budeme zab²vat ulo₧enφm zatφm neulo₧en²ch modifikovan²ch soubor∙ p°i ukonΦenφ aplikace. Pro zabrßn∞nφ uzav°enφ formulß°e vytvo°φme obsluhu udßlosti OnCloseQuery formulß°e. P°ed uzav°enφm formulß°e metoda Close generuje udßlost OnCloseQuery. Tato udßlost mß parametr CanClose, kter² urΦuje zda formulß° m∙₧e b²t uzav°en. Vytvo°φme tedy obsluhu udßlosti OnCloseQuery s t∞mito p°φkazy:

  10. if (Editor->Modified) {
      TMsgDlgButtons temp_set;
      temp_set<< mbYes<<mbNo <<mbCancel;
      String buffer = "Save changes to " + PathName;
      switch(MessageDlg(buffer, mtConfirmation,temp_set,0)) {
        case mrYes:
          Save1Click(this);
          break;
        case mrCancel:
          CanClose=false;
          break;
      }
    }
    V obsluze nenφ nutno testovat stisknutφ tlaΦφtka No, proto₧e implicitnφ hodnota CanClose je true. Aplikace textovΘho editoru je nynφ hotova.
  11. Pokuste se n∞jak²m zp∙soben vylepÜit naÜi aplikaci textovΘho editoru. Nap°. p°idejte k aplikaci paletu nßstroj∙, kterou budete moci zadßvat zarovnßvßnφ textu a dalÜφ b∞₧nΘ Φinnosti.
  12. DalÜφ aplikace je velmi jednoduchß. Ukß₧eme si v nφ, jakΘ standardnφ kurzory m∙₧eme pou₧φvat. Na formulß° umφstφme pouze komponentu Label s textem Zvol kurzor a komponentu kombinovanΘho ovladaΦe. U kombinovanΘho ovladaΦe nastavφme tyto vlastnosti: Text na crDefault a do vlastnosti Items vlo₧φme 21 °et∞zc∙ s nßzvy jednotliv²ch kurzor∙ (z nßsledujφcφ deklarace). Vytvo°φme jeÜt∞ obsluhu udßlosti OnChange kombinovanΘho ovladaΦe. Bude tvo°ena p°φkazem:

  13. static int Kurzory[] = {
            crDefault, crNone, crArrow, crCross, crIBeam,
            crSize, crSizeNESW, crSizeNS, crSizeNWSE,
            crSizeWE, crUpArrow, crHourGlass, crDrag,
            crNoDrop, crHSplit, crVSplit, crMultiDrag,
            crSQLWait, crNo, crAppStart, crHelp};
    Cursor = TCursor(Kurzory[ComboBox1->ItemIndex]);
    Aplikace je hotova a m∙₧eme si prohlΘdnout tvary jednotliv²ch kurzor∙. V kombinovanΘm ovladaΦi vybereme nßzev kurzoru a p°i p°esunu ukazatele myÜi nad prßzdnou Φßst formulß°e se zvolen² kurzor zobrazφ.
  14. Dßle se pokusφme vytvo°it aplikaci, kterß umo₧nφ m∞°it poΦet zapsan²ch znak∙ (za minutu) do editaΦnφho okna. V tΘto aplikaci se seznßmφme s dalÜφ komponentou. ZaΦneme s v²vojem novΘ aplikace. Formulß° zv∞tÜφme na rozm∞ry asi 480 x 350 a nastavφme u n∞j vlastnosti BorderStyle na bsSingle, BorderIcons na [biSystemMenu, biMinimize] a Caption na PoΦet znak∙ za minutu. Do hornφho levΘho rohu formulß°e vlo₧φme komponentu Label s textem Pro zahßjenφ testu zaΦn∞te psßt. a zv∞tÜφme jejφ pφsmo na 10. Ke spodnφmu okraji formulß°e umφstφme komponentu ProgressBar (umφstφme ji asi 5 mm od okraj∙ formulß°e) a nastavφme jejφ vlastnosti takto: Min na 0, Max na 60 a Step na 1. Nad tuto komponentu umφstφme dalÜφ Label, jeho text vyprßzdnφme a pφsmo zv∞tÜφme na 14. Vedle hornφ komponenty Label umφstφme jeÜt∞ dv∞ tlaΦφtka (s texty Vyprßzdnit a Konec). Prost°edek formulß°e vyplnφme komponentou RichEdit, kterou vybavφme svisl²m posuvnφkem (komponentu vyprßzdnφme). Vlastnost ActiveControl formulß°e nastavφme na EditRich. Na formulß° umφstφme jeÜt∞ komponentu Timer a nastavφme u nφ vlastnost Enabled na false. Obsluha stisku tlaΦφtka Konec je tvo°ena p°φkazem:

  15. Application->Terminate();
    a obsluhu stisku tlaΦφtka Vyprßzdnit tvo°φ p°φkazy:
    Timer1->Enabled = false;
    Label1->Caption = "Pro zahßjenφ testu zaΦn∞te psßt.";
    Label1->Font->Color = clBlack;
    Label2->Caption = "";
    RichEdit1->SetTextBuf("");
    RichEdit1->ReadOnly = false;
    ProgressBar1->Position = 0;
    Pro komponentu RichEdit vytvo°φme obsluhu udßlosti OnKeyDown (spustφ m∞°enφ Φasu testu). Tato obsluha je tvo°ena p°φkazy:
    if (RichEdit1->ReadOnly == false) {
      Timer1->Enabled = true;
      Label1->Caption = "Test spuÜt∞n";
      Label1->Font->Color = clGreen;
    }
    Dßle vytvo°φme pomocnou funkci, kterß nßm spoΦφtß poΦet zapsan²ch znak∙ (vytvo°φme z nφ soukromou metodu formulß°e):
    int __fastcall TForm1::PocetZnaku(void) {
      int I, Pocet=0;
      for (I = 0; I < RichEdit1->Lines->Count; I++)
        Pocet += RichEdit1->Lines->Strings[I]->Length();
      return Pocet;
    }
    Zb²vß jeÜt∞ vytvo°it obsluhu OnTimer ΦasovaΦe. Tuto obsluhu tvo°φ p°φkazy:
    if (ProgressBar1->Position == 59) {
      Timer1->Enabled = false;
      Label1->Caption = "Test dokonΦen";
      Label1->Font->Color = clRed;
      RichEdit1->ReadOnly = true;
      Label2->Caption = IntToStr(PocetZnaku()) + " znak∙ za minutu";
    }
    ProgressBar1->StepIt();
    Aplikace je hotova. Pokuste se zjistit jak pracuje. Zßpis prvnφho znaku do RichEdit spustφ m∞°enφ Φasu. VyzkouÜejte.
  16. Dßle si ukß₧eme jeÜt∞ n∞kterΘ mo₧nosti pou₧φvßnφ m°φ₧ky. Velikost ka₧dΘho sloupce nebo °ßdku m∙₧eme nastavit nezßvisle na ostatnφch, proto₧e vlastnosti RowSize, ColWidth a RowHeight jsou pole. U₧ivateli m∙₧eme takΘ umo₧nit zm∞nu velikosti °ßdk∙ a sloupc∙ (volby goColSizing a goRowSizing), p°etahovßnφ cel²ch sloupc∙ a °ßdk∙ na novΘ pozice (goColMoving a goRowMoving), volbu automatickΘ editace a rozsßhlejÜφ v²b∞ry. Existuje takΘ mnoho udßlostφ vztahujφcφ se k m°φ₧kßm. Nejd∙le₧it∞jÜφ je pravd∞podobn∞ OnDrawCell. V obsluze tΘto udßlosti musφme nakreslit urΦitΘ polφΦko m°φ₧ky (pokud se obsah m°φ₧ky nezobrazuje automaticky).

  17. V tΘto aplikaci pou₧ijeme komponentu StringGrid (je to jedinß komponenta vlo₧enß na formulß°). Nastavφme zde vlastnosti Align na alClient, DefaultDrawing na false (umo₧nφ u₧ivatelskΘ zobrazovßnφ obsahu bun∞k) a Options na [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goDrawFocusSelected, goColSizing, goColMoving, goEditing]. V naÜφ m°φ₧ce budeme zobrazovat pφsma systΘmu v r∙zn²ch velikostech. V obsluze OnCreate formulß°e spoΦφtßme poΦet sloupc∙ a °ßdk∙ a jejich velikosti. Tato obsluha tedy bude obsahovat p°φkazy:
    int I, J;
    StringGrid1->ColCount = Screen->Fonts->Count + 1;
    StringGrid1->ColWidths[0] = 50;
    for (I = 1; I <= Screen->Fonts->Count; I++) {
      StringGrid1->Cells[I] [0] = Screen->Fonts->Strings[I-1];
      StringGrid1->Canvas->Font->Name = StringGrid1->Cells[I] [0];
      StringGrid1->Canvas->Font->Size = 32;
      StringGrid1->ColWidths[I]=StringGrid1->Canvas->TextWidth("AaBbYyZz");
    };
    StringGrid1->RowCount = 26;
    for (I = 1; I <= 25; I++) {
      StringGrid1->Cells [0] [I] = IntToStr(I+7);
      StringGrid1->RowHeights[I] = 15 + I*2;
      for (J = 1; J <= StringGrid1->ColCount; J++)
        StringGrid1->Cells [J] [I] = "AaBbYyZz";
    }
    StringGrid1->RowHeights[0] = 25;
    Pro vlastnφ zobrazovßnφ obsahu m°φ₧ky musφme dßle vytvo°it obsluhu OnDrawCell m°φ₧ky. Tato obsluha obsahuje p°φkazy:
    if (Col == 0) StringGrid1->Canvas->Font->Name = "Arial";
    else StringGrid1->Canvas->Font->Name = StringGrid1->Cells[Col] [0];
    if (Row == 0) StringGrid1->Canvas->Font->Size = 14;
    else StringGrid1->Canvas->Font->Size = Row + 7;
    if (State.Contains(gdSelected)) StringGrid1->Canvas->Brush->Color=clHighlight;
    else if (State.Contains(gdFixed)) StringGrid1->Canvas->Brush->Color=clBtnFace;
         else StringGrid1->Canvas->Brush->Color = clWindow;
    StringGrid1->Canvas->TextRect(Rect,Rect.Left,Rect.Top,
                                StringGrid1->Cells[Col] [Row]);
    if (State.Contains(gdFocused)) StringGrid1->Canvas->DrawFocusRect(Rect);
    Tφm je naÜe aplikace hotova. Pokuste se zjistit v²znam jednotliv²ch p°φkaz∙ v obou obsluhßch udßlostφ. Aplikaci vyzkouÜejte. Je vhodnΘ formulß° zv∞tÜit.
  18. V²znamnou slu₧bou IDE C++ Builderu je integrovan² ladφcφ prost°edek. Umo₧≥uje snadnΘ nastavovßnφ bod∙ p°eruÜenφ, zjiÜ¥ovßnφ hodnot prom∞nn²ch apod. Tento ladφcφ prost°edek nßm pomßhß v hledßnφ chyb v programu. Lad∞nφ automaticky zaΦφnß volbou Run | Run nebo stiskem klßvesy F9.

  19. D°φve ne₧ se ladφcφm prost°edkem budeme zab²vat podrobn∞ji se seznßmφme s jeho nabφdkou. Nabφdka integrovanΘho ladφcφho prost°edku je obsa₧ena takΘ v mφstnφ nabφdce Editoru k≤du. Zde jsou tyto volby:
     
    Volba Popis
    Toggle Breakpoint Nastavuje nebo ruÜφ bod p°eruÜenφ pro souΦasn² °ßdek Editoru k≤du.
    Run to Cursor SpouÜtφ program a₧ do °ßdku, na kterΘm v Editoru k≤du stojφ kurzor.
    Inspect Otevφrß okno Inspektora lad∞nφ pro objekt s kurzorem.
    Goto Address Umo₧≥uje specifikovat adresu v programu, na kterΘ provßd∞nφ programu skonΦφ.
    Evaluate/Modify Umo₧≥uje zobrazit nebo modifikovat prom∞nnou za b∞hu.
    Add Watch at Cursor P°idßvß prom∞nnou pod kurzorem do Sledovacφho okna.
    View CPU Zobrazφ okno CPU.

    DalÜφ volby t²kajφcφ se ladφcφho prost°edku jsou uvedeny v nabφdce Run (n∞kterΘ z t∞chto voleb se shodujφ s volbami v mφstnφ nabφdce Editoru k≤du). V nabφdce Run najdeme volby:
     

    Volba Popis
    Run P°eklßdß program (je-li to zapot°ebφ) a spouÜtφ jej pod kontrolou ladφcφho prost°edku.
    Parameters Umo₧≥uje zadat parametry p°φkazovΘho °ßdku pro nßÜ program a pro p°i°azenφ hostitelskΘ aplikace (p°i lad∞nφ DLL).
    Step Over Provede °ßdek zdrojovΘho k≤du urΦen² provßd∞n²m °ßdkem a p°esune jej na dalÜφ °ßdek.
    Trace Into Trasuje ve funkcφch na provßd∞nΘm °ßdku.
    Trace to Next Source Line Zp∙sobφ p°esun provßd∞nΘho °ßdku na nßsledujφcφ °ßdek ve zdrojovΘm k≤du.
    Run to Cursor SpouÜtφ program a₧ do °ßdku, na kterΘm v Editoru k≤du stojφ kurzor.
    Show Execution Point Zobrazφ provßd∞n² °ßdek v Editoru k≤du (pokud je nutno, pak obsah okna roluje). Pou₧itelnΘ pouze pokud provßd∞nφ programu je p°eruÜeno.
    Program Pause P°eruÜuje provßd∞nφ programu.
    Program Reset Uzavφrß lad∞nφ a vracφ se do IDE C++ Builderu.
    Inspect Zobrazuje okno Inspektora lad∞nφ (a m∙₧eme zadat jmΘno prohlφ₧enΘho objektu).
    Inspect Local Variables Zobrazuje okno Inspektora lad∞nφ se vÜemi lokßlnφmi prom∞nn²mi souΦasnΘ funkce.
    Add Watch Zobrazuje sledovacφ okno a p°idßvß do n∞j sledovan² objekt.
    Add Breakpoint Zobrazuje dialogovΘ okno Editace bodu p°eruÜenφ a umo₧≥uje p°idat bod p°eruÜenφ.
    Evaluate/Modify Zobrazuje dialogovΘ okno Evaluate/Modify.
  20. Po spuÜt∞nφ programu v IDE C++ Builderu, program b∞₧φ plnou rychlostφ a je zastaven pouze p°i dosa₧enφ bodu p°eruÜenφ. Bod p°eruÜenφ je znaΦka, kterß °φkß ladφcφmu prost°edku, kde p°eruÜit provßd∞nφ programu. K nastavenφ bodu p°eruÜenφ, klikneme na levΘm okraji okna Editoru k≤du na °ßdku, kde chceme p°eruÜit provßd∞nφ programu. Na okraji je zobrazena ikona bodu p°eruÜenφ a cel² °ßdek je zobrazen Φerven∞. K odstran∞nφ bodu p°eruÜenφ klikneme na jeho ikon∞. Body p°eruÜenφ lze nastavovat pouze na °ßdcφch programu, kterΘ generujφ k≤d. Nenφ mo₧no je nastavit na prßzdn² °ßdek, °ßdek komentß°e nebo °ßdek s deklaracemi. Pokud bod p°eruÜenφ nastavφme na nevhodnΘm °ßdku, pak je zobrazen zelen∞ a jeho ikona je nev²raznß.

  21. Provßd∞n² °ßdek urΦuje °ßdek ve zdrojovΘm k≤du, kter² bude proveden. Je zobrazovßn mod°e a na levΘm okraji okna editoru je oznaΦovßn zelenou Üipkou.
    Kdy₧ provßd∞nφ programu se zastavφ na bodu p°eruÜenφ pak m∙₧eme prohlφ₧et prom∞nnΘ, prohlφ₧et zßsobnφk volßnφ, krokovat nebo trasovat nßÜ k≤d. Po zjiÜt∞nφ pot°ebn²ch informacφ lze pokraΦovat v provßd∞nφ programu stiskem tlaΦφtka Run (aplikace se zastavφ na dalÜφm bodu p°eruÜenφ). Jestli₧e provedeme n∞jakou zm∞nu ve zdrojovΘm k≤du, pak jsme dotßzßni, zda pokraΦovat v lad∞nφ nebo zda op∞tovn∞ provΘst p°eklad).
    Seznam bod∙ p°eruÜenφ, kterΘ jsou nastaveny nalezneme v okn∞ Bod∙ p°eruÜenφ. Toto okno zobrazφme volbou View | Breakpoint. Seznam bod∙ p°eruÜenφ mß Φty°i sloupce. Prvnφ sloupec Filename/Address obsahuje jmΘno souboru jednotky zdrojovΘho k≤du. Druh² sloupec nazvan² Line/Length uvßdφ Φφslo °ßdku s nastaven²m bodem p°eruÜenφ. Sloupec Condition zobrazuje podmφnku nastavenou pro bod p°eruÜenφ. Poslednφ sloupec nazvan² Pass uvßdφ poΦet povolen²ch pr∙chod∙ bodem p°eruÜenφ pro spln∞nou podmφnku ne₧ dojde k p°eruÜenφ programu. Okno seznamu Bod∙ p°eruÜenφ mß dv∞ mφstnφ nabφdky. Prvnφ z nich se zobrazφ p°i stisku pravΘho tlaΦφtka myÜi nad n∞kter²m bodem p°eruÜenφ. Popis voleb v tΘto nabφdce je uveden v nßsledujφcφ tabulce:
     
    Volba Popis
    Enable Povoluje nebo zakazuje bod p°eruÜenφ (zakßzanΘ body p°eruÜenφ jsou ladφcφm prost°edkem ignorovßny).
    Delete RuÜφ bod p°eruÜenφ.
    View Source Roluje zdrojov²m souborem v Editoru k≤du k zobrazenφ zdrojovΘho °ßdku s bodem p°eruÜenφ.
    Edit Source Umis¥uje kurzor editoru na °ßdek s bodem p°eruÜenφ (takΘ lze provΘst dvojit²m kliknutφm na prvnφm sloupci v seznamu bod∙ p°eruÜenφ).
    Properties Zobrazuje dialogovΘ okno Editace bod∙ p°eruÜenφ.

    Druhß mφstnφ nabφdka se zobrazφ p°i kliknutφ prav²m tlaΦφtkem myÜi mimo body p°eruÜenφ. Zde jsou volby Delete All, Disable All a Enable All.
    Hlavnφ d∙vod pro modifikaci bodu p°eruÜenφ je p°idßnφ podmφnky. TlaΦφtko New v okn∞ Editace bodu p°eruÜenφ vytvo°φ nov² bod p°eruÜenφ na stejnΘm °ßdku jako je vybran² bod p°eruÜenφ (m∙₧e mφt jinou podmφnku).
    JednoduchΘ body p°eruÜenφ zp∙sobφ p°eruÜenφ po₧adovanΘho programu p°i dosa₧enφ °ßdku s bodem p°eruÜenφ. Pokud vytvo°φme bod p°eruÜenφ, pak implicitn∞ se jednß o jednoduch² bod p°eruÜenφ.
    U podmφn∞n²ch bod∙ p°eruÜenφ k p°eruÜenφ dojde pouze tehdy, kdy₧ je spln∞na podmφnka bodu p°eruÜenφ. Vytvo°φme jej tak, ₧e vytvo°φme jednoduch² bod p°eruÜenφ a v okn∞ Editace zapφÜeme v²raz podmφnky a p°φpadn∞ poΦet pr∙chod∙ (nap°. p°i zadßnφ poΦtu pr∙chod∙ 3, p°eruÜenφ nastane a₧ p°i t°etφm pr∙chodu bodem p°eruÜenφ p°i spln∞nΘ podmφnce).

  22. Jin²m ladφcφm p°φkazem je p°φkaz Run to Cursor. Tento p°φkaz spouÜtφ nßÜ program a₧ po °ßdek s kurzorem. Po dosa₧enφ tohoto °ßdku je program p°eruÜen a m∙₧eme provßd∞t libovolnΘ ladφcφ Φinnosti. Volba se chovß jako doΦasn² bod p°eruÜenφ.

  23. DalÜφmi Φinnostmi integrovanΘho ladφcφho prost°edku se budeme zab²vat v nßsledujφcφ kapitole.
6. Textov² editor I