7. Textov² editor II
  1. Nßsledujφcφ aplikace nßs seznßmφ s pou₧φvßnφm dialogov²ch oken hledßnφ a nahrazovßnφ textu. ZaΦneme v²vojem novΘ aplikace. Na formulß° umφstφme komponentu RichEdit a zapφÜeme do nφ n∞jak² text. Na tomto textu budeme demonstrovat funkce hledßnφ a nahrazovßnφ textu. Vlastnost HideSelection tΘto komponenty nastavφme na false. Na formulß° dßle vlo₧φme komponenty FindDialog a ReplaceDialog. Vlastnost Options obou komponent nastavφme na [frDown, frHideUpDown]. Formulß° jeÜt∞ vybavφme nabφdkou s volbami Edit | Find a Edit | Replace. Obsluha volby Edit | Find je tvo°ena p°φkazy:

  2. FindDialog1->FindText = RichEdit1->SelText;
    FindDialog1->Execute();
    a obsluha volby Edit | Replace:
    ReplaceDialog1->FindText = RichEdit1->SelText;
    ReplaceDialog1->Execute();
    Pro komponentu FindDialog vytvo°φme jeÜt∞ obsluhu udßlosti OnFind (nazveme ji Find). Tato obsluha bude tvo°ena p°φkazy:
    TSearchTypes st;
    TFindDialog *cd;
    int newpos;
    if ((cd = dynamic_cast<TFindDialog *> (Sender)) == 0)
      MessageBox(NULL, "Dynamic Cast Failed!", "Find/Rep", MB_OK);
    if (cd->Options.Contains(frMatchCase))
      st << stMatchCase;
    if (cd->Options.Contains(frWholeWord))
      st << stWholeWord;
    if (RichEdit1->SelLength)
      RichEdit1->SelStart += 1;
    newpos = RichEdit1->FindText(cd->FindText, RichEdit1->SelStart,
      RichEdit1->Text.Length(), st);
    if (newpos != -1) {
      RichEdit1->SelStart = newpos;
      RichEdit1->SelLength = cd->FindText.Length();
    }
    else {
      MessageBox(NULL, "End of document reached.", "Find/Rep", MB_OK);
      RichEdit1->SelStart = 0;
    }
    Prostudujte si tuto obsluhu. Zpracovßvajφ se zde volby dialogovΘho okna hledßnφ. Stejnou obsluhu je nutno jeÜt∞ p°ipojit ke stejnΘ udßlosti komponenty ReplaceDialog. U komponenty ReplaceDialog je nutno vytvo°it jeÜt∞ obsluhu udßlosti OnReplace (nazveme ji Replace). Bude tvo°ena p°φkazy:
    if (RichEdit1->SelLength == 0)
      Find(Sender);
    else {
      RichEdit1->SelText =  ReplaceDialog1->ReplaceText;
      Find(Sender);
    }
    if (ReplaceDialog1->Options.Contains(frReplaceAll))
      while (RichEdit1->SelLength !=0)
        Replace(Sender);
    Zb²vß jeÜt∞ vytvo°it obsluhu udßlosti OnCreate formulß°e. Je tvo°ena p°φkazem
    RichEdit1->SelStart = 0;
    Aplikace je hotova, m∙₧eme ji vyzkouÜet. Pokuste se p°idat tyto funkce do aplikace textovΘho editoru vytvo°enΘho v p°edchozφ kapitole.
  3. V dalÜφ aplikaci se vφce seznßmφme s komponentou RichEdit. Tato aplikace je dlouhß, nebudeme ji vytvß°et, ale stßhneme si ji. Jednß se o demonstraΦnφ aplikaci firmy Borland. Aplikaci vyzkouÜejte. Aplikace obsahuje paletu nßstroj∙, pravφtko a stavov² °ßdek. Podrobn∞ji se podφvßme pouze na n∞kterΘ obsluhy udßlostφ.

  4. Aplikace obsahuje dalÜφ formulß° s informacemi o aplikaci. Tento formulß° obsahuje pouze obsluhu udßlosti OnShow. Obsluha bude tvo°ena nßsledujφcφmi p°φkazy (zjistφme zde velikost dostupnΘ pam∞ti a procento jejφho vyu₧itφ):
    TMemoryStatus MS;
    MS.dwLength = sizeof(MS);
    GlobalMemoryStatus(&MS);
    PhysMem->Caption = FormatFloat((AnsiString)"#,###' KB'",
      MS.dwTotalPhys / 1024);
    LPSTR lpMemLoad = new char[5];
    sprintf(lpMemLoad,"%d %%",MS.dwMemoryLoad);
    FreeRes->Caption = (AnsiString)lpMemLoad;
    delete [] lpMemLoad;
    Tento formulß° je vy°azen ze seznamu automaticky vytvß°en²ch formulß°∙.
  5. ZaΦneme nejprve popisovat jednoduchΘ obsluhy udßlostφ. Obsluha volby Edit | Cut je tvo°ena p°φkazem:

  6. RichEdit1->CutToClipboard();
    Stejnß obsluha je p°i°azena i stisku tlaΦφtka CutButton. Obdobn∞ jsou vy°eÜeny i volby Edit | Copy a Edit | Paste (a odpovφdajφcφ tlaΦφtka). Obsluha volby Edit | Font (tlaΦφtko pro tuto funkci nemßme) je tvo°ena p°φkazy:
    FontDialog1->Font->Assign( RichEdit1->SelAttributes );
    if ( FontDialog1->Execute() )
      CurrText()->Assign( FontDialog1->Font );
    RichEdit1->SetFocus();
    Volba Help | About je tvo°ena p°φkazy (je pot°eba vlo₧it hlaviΦkov² soubor druhΘho formulß°e do jednotky prvnφho formulß°e):
    Form2 = new TForm2(Application);
    Form2->ShowModal();
    delete Form2;
    Pro dalÜφ obsluhy voleb v nabφdce jsou vytvo°eny dalÜφ polo₧ky a metody formulß°e. Do soukromΘ Φßsti deklarace formulß°e jsou vlo₧eny deklarace:
    AnsiString FFileName;
    bool FUpdating;
    int FDragOfs;
    bool FDragging;
    TTextAttributes *__fastcall CurrText(void);
    void __fastcall GetFontNames(void);
    void __fastcall SetFileName(const AnsiString FileName);
    void __fastcall CheckFileSave(void);
    void __fastcall SetupRuler(void);
    void __fastcall SetEditRect(void);
    void __fastcall ShowHint(TObject *Sender);
    Na zaΦßtku programovΘ jednotky hlavnφho formulß°e je deklarace nßsledujφcφch konstant:
    const float RulerAdj = 4.0/3.0;
    const int GutterWid = 6;
    Implementace uveden²ch metod bude vypadat takto (je zde i dalÜφ pomocnß funkce):
    TTextAttributes *__fastcall TMainForm::CurrText(void)
    {
      return RichEdit1->SelAttributes;
    }
    int __stdcall EnumFontsProc(TLogFontA &LogFont,
      TTextMetricA &/*TextMetric*/, int /*FontType*/, Pointer Data)
    {
      TCharsetObject *FontCharset;
      FontCharset = new TCharsetObject((int)LogFont.lfCharSet);
      ((TStrings *)Data)->AddObject((AnsiString)LogFont.lfFaceName,
        FontCharset);
      return 1;
    }
    void __fastcall TMainForm::GetFontNames(void)
    { HDC hDC = GetDC(0);
      void * cTmp = (void *)FontName->Items;
      EnumFonts(hDC, NULL, (FONTENUMPROC) EnumFontsProc, (long) cTmp );
      ReleaseDC(0,hDC);
      FontName->Sorted = True;
    }
    void __fastcall TMainForm::SetFileName(const AnsiString FileName)
    {
      LPSTR lpBuf = new char[MAX_PATH];
      sprintf(lpBuf, LoadStr(Percent_s_102).c_str(),
        ExtractFileName(FileName).c_str(), Application->Title.c_str());
      Caption = (AnsiString)lpBuf;
      FFileName = FileName;
      delete lpBuf;
    }
    void __fastcall TMainForm::CheckFileSave(void)
    { if ( RichEdit1->Modified ) {
        switch(MessageBox(Handle,LoadStr(SaveChanges_103).c_str(),
        LoadStr(Confirmation_104).c_str(),
        MB_YESNOCANCEL | MB_ICONQUESTION))
            {  case ID_YES    : FileSaveClick(this);
               case ID_CANCEL : Abort();
            };
       }
    }
    void __fastcall TMainForm::SetupRuler(void)
    { int iCtr = 1;
      char sTmp[201];
      while (iCtr < 200) {
        sTmp[iCtr] = 9;
        iCtr++;
        sTmp[iCtr] = '|';
        iCtr++;
      }
      Ruler->Caption = (AnsiString)sTmp;
    }
    void __fastcall TMainForm::SetEditRect(void)
    { TRect Rct = Rect(GutterWid, 0, RichEdit1->ClientWidth-GutterWid,
                  ClientHeight);
      SendMessage(RichEdit1->Handle, EM_SETRECT, 0, long(&Rct));
    }
    Pokuste se urΦit, co provßd∞jφ jednotlivΘ metody. PovÜimn∞te si ₧e v t∞chto metodßch pou₧φvßme zdroje °et∞zc∙. Mß to ten d∙vod, ₧e aplikaci se pozd∞ji budeme sna₧it p°evΘst z angliΦtiny na n∞mΦinu a ÜvΘdÜtinu. V metodßch se pou₧φvajφ takΘ dalÜφ objekty. Jednß se o instance t°φdy TCharsetObject. Tato t°φda reprezentuje znakovou mno₧inu pφsma. T°φda mß deklaraci:
    class TCharsetObject : public TObject
    {
    public:
        int Charset;
        __fastcall TCharsetObject(int FCharset);
    };
    a definice konstruktoru tΘto t°φdy vypadß takto:
    __fastcall TCharsetObject::TCharsetObject(int FCharset)
      : TObject()
    {
         Charset = FCharset;
    }
    Jeliko₧ instance t∞chto objekt∙ budeme p°i°azovat do vlastnosti Objects seznam∙ °et∞zc∙ jmen pφsem, musφme takΘ zajistit jejich uvoln∞nφ p°i ukonΦenφ aplikace. Vytvo°φme tedy obsluhu udßlosti OnDestroy formulß°e. Bude tvo°ena p°φkazy:
    for(int n = 0;n < FontName->Items->Count;n++)
      if( FontName->Items->Objects[n] ){
        delete FontName->Items->Objects[n];
        FontName->Items->Objects[n] = NULL;
      }
    Nynφ se ji₧ m∙₧eme podφvat na obsluhy dalÜφch voleb v nabφdce. Obsluha volby File | New bude tvo°ena p°φkazy:
    CheckFileSave();
    SetFileName((AnsiString)LoadStr(Untitled_101));
    RichEdit1->Lines->Clear();
    RichEdit1->Modified = false;
    Obsluhu volby File | Open a tlaΦφtka OpenButton tvo°φ:
    CheckFileSave();
    if (OpenDialog->Execute()) {
      RichEdit1->Lines->LoadFromFile(OpenDialog->FileName);
      SetFileName(OpenDialog->FileName);
      RichEdit1->SetFocus();
      RichEdit1->Modified = false;
      RichEdit1->ReadOnly = OpenDialog->Options.Contains(ofReadOnly);
    }
    Obdobn∞ pro File | Save a tlaΦφtko SaveButton to budou p°φkazy:
    if ( !strcmp(FFileName.c_str(),LoadStr(Untitled_101).c_str()) )
      FileSaveAsClick(Sender);
    else {
      RichEdit1->Lines->SaveToFile(FFileName);
      RichEdit1->Modified = false;
    }
    Obsluhu File | Save As tvo°φ p°φkazy:
    if ( SaveDialog->Execute() ) {
      RichEdit1->Lines->SaveToFile(SaveDialog->FileName);
      SetFileName(SaveDialog->FileName);
      RichEdit1->Modified = false;
    }
    Obsluhu volby File | Print a tlaΦφtka PrintButton tvo°φ p°φkaz:
    if ( PrintDialog->Execute() ) RichEdit1->Print( FFileName );
    a obsluhu File | Exit p°φkaz:
    Close();
    Obsluha volby Edit | Undo a stisknutφ tlaΦφtka UndoButton je tvo°ena:
    if ( RichEdit1->HandleAllocated() )
      SendMessage(RichEdit1->Handle, EM_UNDO, 0, 0);
    Pokuste se pochopit jak tyto obsluhy a dalÜφ metody pracujφ. DalÜφ obsluhy voleb nßm ji₧ srozumitelnΘ asi nebudou. Obsluhu Help | Contents tvo°φ p°φkaz:
    Application->HelpCommand(HELP_CONTENTS, 0);
    Obsluhu Help | Search for Help On nßpov∞dy tvo°φ:
    Application->HelpCommand(HELP_PARTIALKEY, (long) "");
    a obsluha Help | How to Use Help je tvo°ena:
    Application->HelpCommand(HELP_HELPONHELP, 0);
    Tφm jsme dokonΦili vytvß°enφ obsluh voleb v nabφdce. Zb²vß nßm vy°eÜit jeÜt∞ stisknutφ n∞kolika tlaΦφtek na palet∞. Obsluha stisku tlaΦφtka BoldButton obsahuje p°φkazy:
    if ( !FUpdating ) {
      if ( BoldButton->Down )
        CurrText()->Style = CurrText()->Style << fsBold;
      else
        CurrText()->Style = CurrText()->Style >> fsBold;
    }
    Pro tlaΦφtko ItalicButton a UnderlineButton to jsou obdobnΘ obsluhy. Pro vÜechna t°i tlaΦφtka zarovnßvßnφ bude pou₧ita obsluha s p°φkazy:
    if ( !FUpdating ) {
      TControl *oAliBtn = (TControl*)(Sender);
      RichEdit1->Paragraph->Alignment = (TAlignment)oAliBtn->Tag;
    }
    Obsluha stisku poslednφho tlaΦφtka, tj. tlaΦφtka BulletsButton je tvo°ena p°φkazy:
    if ( !FUpdating )
      RichEdit1->Paragraph->Numbering = (TNumberingStyle)BulletsButton->Down;
    Zb²vajφ jeÜt∞ obsluhy OnChange editaΦnφho ovladaΦe velikosti pφsma a kombinovanΘho ovladaΦe jmΘna pφsma. Obsluha editaΦnφho ovladaΦe je tvo°ena p°φkazy:
    int fontsize = atoi(FontSize->Text.c_str());
    if ((!FUpdating) &&  (fontsize)) {
      if (fontsize < 1) {
        ShowMessage(LoadStr(Numberbetween_105));
        FontSize->Text = 1;
      }
      else if (fontsize > 1638) {
        ShowMessage(LoadStr(Numberbetween_105));
        FontSize->Text = 1638;
      }
      CurrText()->Size = atoi(FontSize->Text.c_str());
    }
    a obsluha kombinovanΘho okna obsahuje:
    TCharsetObject* ChasrsetObject;
    if ( !FUpdating ) {
      ChasrsetObject = (TCharsetObject*)FontName->Items
                       ->Objects[FontName->ItemIndex];
      CurrText()->Charset = (unsigned char)ChasrsetObject->Charset;
      CurrText()->Name = FontName->Items->Strings[FontName->ItemIndex];
    }
    Dßle se budeme zab²vat vytvß°enφm obsluh dalÜφch udßlostφ. V udßlosti OnCreate formulß°e budeme takΘ m∞nit obsluhu udßlosti OnHint aplikace. Do soukromΘ Φßsti deklarace t°φdy formulß°e tedy vlo₧φme
    void __fastcall ShowHint(TObject *Sender);
    a do jednotky formulß°e zapφÜeme zm∞n∞nou obsluhu.
    void __fastcall TMainForm::ShowHint(TObject* /*Sender*/)
    {
      StatusBar->SimpleText = Application->Hint;
    }
    Nynφ ji₧ m∙₧eme vytvo°it obsluhu udßlosti OnCreate formulß°e. Bude tvo°ena t∞mito p°φkazy:
    Application->OnHint = &ShowHint;
    OpenDialog->InitialDir = ExtractFilePath(ParamStr(0));
    SaveDialog->InitialDir = OpenDialog->InitialDir;
    GetFontNames();
    SetupRuler();
    SelectionChange(this);
    Pro komponentu RichEdit vytvo°φme obsluhu udßlosti OnSelectionChange (nazveme ji SelectionChange) s t∞mito p°φkazy:
    char sizebuf[6];
    try {
      FUpdating = true;
      FirstInd->Left = int(RichEdit1->Paragraph->FirstIndent*RulerAdj)-
        4+GutterWid;
      LeftInd->Left  = int((RichEdit1->Paragraph->LeftIndent+
        RichEdit1->Paragraph->FirstIndent)*RulerAdj)-
        4+GutterWid;
      RightInd->Left = Ruler->ClientWidth-6-int(
        (RichEdit1->Paragraph->RightIndent+GutterWid)*RulerAdj);
      BoldButton->Down = RichEdit1->SelAttributes->Style.Contains(fsBold);
      ItalicButton->Down = RichEdit1->SelAttributes->Style.Contains(fsItalic);
      UnderlineButton->Down = RichEdit1->SelAttributes->Style.Contains(fsUnderline);
      BulletsButton->Down = bool(RichEdit1->Paragraph->Numbering);
      FontSize->Text = itoa(RichEdit1->SelAttributes->Size, sizebuf, 10);
      FontName->Text = RichEdit1->SelAttributes->Name;
      switch((int)RichEdit1->Paragraph->Alignment)
      { case 0: LeftAlign->Down   = true; break;
        case 1: RightAlign->Down  = true; break;
        case 2: CenterAlign->Down = frue; break;
      }
    }
    catch (...) {
      FUpdating = false;
    }
    FUpdating = false;
    Obsluha OnResize pravφtka bude tvo°ena p°φkazem:
    RulerLine->Width = (int)Ruler->ClientWidth - (RulerLine->Left*2);
    a obsluhu OnResize formulß°e tvo°φ p°φkazy:
    SetEditRect();
    SelectionChange(Sender);
    Pro formulß° jeÜt∞ vytvo°φme obsluhu udßlosti OnPaint s p°φkazem
    SetEditRect();
    a obsluhu udßlosti OnCloseQuery tvo°enou p°φkazy:
    try {
      CheckFileSave();
    }
    catch (...) {
      CanClose = false;
    }
    Do konstruktoru formulß°e p°idßme jeÜt∞ p°φkaz:
    SetFileName((AnsiString)LoadStr(Untitled_101));
    Tφm mßme v∞tÜinu aplikace hotovou. Zb²vß dokonΦit jeÜt∞ ovlßdßnφ pravφtka. To provedeme v dalÜφm bod∞. Pokuste se pochopit, co a jak provßd∞jφ jednotlivΘ obsluhy.
  7. V tomto bod∞ se budeme zab²vat ovlßdßnφm indikßtor∙ okraj∙ na pravφtku. Pro vÜechny t°i indikßtory okraj∙ na pravφtku vytvo°φme obsluhy udßlostφ OnDouseDown, OnMouseMove a OnMouseUp. Prvnφ dv∞ z t∞chto obsluh jsou pro vÜechny t°i indikßtory spoleΦnΘ. Obsluhu OnMouseDown tvo°φ p°φkazy:

  8. TLabel * oTmpLabel = (TLabel *)Sender;
    FDragOfs = oTmpLabel->Width / 2;
    oTmpLabel->Left = oTmpLabel->Left+X-FDragOfs;
    FDragging = True;
    a obsluhu OnMouseMove p°φkazy:
    if (FDragging) {
      TLabel * oTmpLabel = (TLabel *)Sender;
      oTmpLabel->Left = oTmpLabel->Left+X-FDragOfs;
    }
    Obsluhu OnMouseUp indikßtoru prvnφho °ßdku tvo°φ p°φkazy:
    FDragging = false;
    RichEdit1->Paragraph->FirstIndent = int((FirstInd->Left+
                                        FDragOfs-GutterWid) / RulerAdj);
    LeftIndMouseUp(Sender, Button, Shift, X, Y);
    pro indikßtor levΘho okraje pou₧ijeme p°φkazy:
    FDragging = false;
    RichEdit1->Paragraph->LeftIndent = int((LeftInd->Left+FDragOfs-GutterWid)/
                          RulerAdj)-RichEdit1->Paragraph->FirstIndent;
    SelectionChange(Sender);
    a pro indikßtor pravΘho okraje p°φkazy:
    FDragging = false;
    RichEdit1->Paragraph->RightIndent =
      int((Ruler->ClientWidth-RightInd->Left+FDragOfs-2) /
      RulerAdj)-2*GutterWid;
    SelectionChange(Sender);
    Nynφ je ji₧ naÜe aplikace hotova. M∙₧eme ji vyzkouÜet.
  9. NaÜe aplikace mß takΘ nabφdku, kterß umo₧≥uje p°epφnat jazyk aplikace (angliΦtina, n∞mΦina a ÜvΘdÜtina). Obsluhy t∞chto voleb v nabφdce jsou tvo°eny p°φkazy (je zde i pomocnß funkce):

  10. void SetLocaleOverrides(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);
          }
    }
    void __fastcall TMainForm::US1Click(TObject *Sender)
    {
      SetLocaleOverrides((Application->ExeName).c_str(), "ENU");
      LPSTR lpBuf = new char[256];
      sprintf(lpBuf, LoadStr(Restart_106).c_str(),
              LoadStr(Language_108).c_str());
      ShowMessage(operator +(lpBuf, LoadStr(Restart_107).c_str()));
    }
    void __fastcall TMainForm::German1Click(TObject *Sender)
    {
      SetLocaleOverrides((Application->ExeName).c_str(), "DEU");
      LPSTR lpBuf = new char[256];
      sprintf(lpBuf, LoadStr(Restart_106).c_str(),
              LoadStr(Language_109).c_str());
      ShowMessage(operator +(lpBuf, LoadStr(Restart_107).c_str()));
    }
    void __fastcall TMainForm::Swedish1Click(TObject *Sender)
    {
      SetLocaleOverrides((Application->ExeName).c_str(), "SVE");
      LPSTR lpBuf = new char[256];
      sprintf(lpBuf, LoadStr(Restart_106).c_str(),
              LoadStr(Language_110).c_str());
      ShowMessage(operator +(lpBuf, LoadStr(Restart_107).c_str()));
    }
    Tyto p°φkazy pouze naΦφtajφ zdroje °et∞zc∙ s p°φsluÜn²mi texty (z DLL) a p°i°azujφ je k aplikaci. Nynφ je zapot°ebφ vytvo°it pot°ebnΘ zdroje °et∞zc∙, vytvo°it z nich DLL a tyto DLL ulo₧it do stejnΘho adresß°e, jako je aplikace. Ukß₧eme si, jak vypadß projekt pro vytvo°enφ DLL pro jeden jazyk (nap°. angliΦtinu; pro ostatnφ dva jazyky pou₧ijeme ji₧ hotovΘ DLL). Stßhn∞te si soubor s projektem vytvo°enφ DLL pro angliΦtinu. Rozbalte tento soubor a v C++ Builderu otev°ete projekt Richenu.bpr. P°ekladem tohoto projektu se vytvo°φ pot°ebnß DLL. Tento projekt obsahuje soubor zdroj∙ se zdroji °et∞zc∙, kterΘ pot°ebuje naÜe aplikace. ProhlΘdn∞te si, z jak²ch soubor∙ se tento projekt sklßdß a p°elo₧te jej. P°i p°ekladu vznikne soubor Richenu.enu. DalÜφ dv∞ DLL pro n∞mΦinu a ÜvΘdÜtinu (Richdeu.deu a Richsve.sve) jste si stßhli spoleΦn∞ s projektem pro vytvo°enφ DLL pro angliΦtinu. Ulo₧te vÜechny tyto t°i DLL do stejnΘho adresß°e jako je p°edchozφ aplikace. A vyzkouÜejte, jak lze m∞nit jazyk volbou v nabφdce. Nov² jazyk se projevφ a₧ p°i dalÜφm spuÜt∞nφ aplikace.

  11. Obvykle p°eruÜφme provßd∞nφ programu na bodu p°eruÜenφ, abychom zjistili hodnotu jednΘ nebo vφce prom∞nn²ch. Hodnoty urΦen²ch prom∞nn²ch lze zjistit ve Sledovacφm okn∞. Do Sledovacφho okna lze p°idßvat prom∞nnΘ podle pot°eby. Na ka₧dΘm °ßdku tohoto okna je v₧dy uvedeno jmΘno prom∞nnΘ a jejφ hodnota. Zp∙sob zobrazenφ hodnoty je urΦen typem prom∞nnΘ a zobrazovacφm nastavenφm pro sledovan² prvek.

  12. Ladφcφ prost°edek a Editor k≤du mß slu₧bu usnad≥ujφcφ testovßnφ hodnoty prom∞nnΘ. Jednß se o bublinkovou nßpov∞du vyhodnocovaΦe v²razu. Tuto slu₧bu (ToolTip evaluator) zapφnßme na strßnce Code Insight dialogovΘho okna Environment Options. Po zastavenφ provßd∞nφ programu umφstφme kurzor editoru na prom∞nnou a v bublinkovΘ nßpov∞d∞ je zobrazena hodnota tΘto prom∞nnΘ.
    Sledovacφ okno mß vlastnφ mφstnφ nabφdku. Jsou zde tyto volby:
     
    Volba Popis
    Edit Watch Umo₧≥uje editaci sledovanΘho prvku (nap°. zm∞na zp∙sobu zobrazenφ).
    Add Watch P°idßvß nov² prvek do Sledovacφho okna.
    Enable Watch Povoluje sledovan² prvek.
    Disable Watch Zakazuje sledovan² prvek
    Delete Watch RuÜφ sledovan² prvek.
    Enable All Watches Povoluje vÜechny prvky Sledovacφho okna.
    Disable All Watches Zakazuje vÜechny prvky Sledovacφho okna.
    Delete All Watches RuÜφ vÜechny prvky Sledovacφho okna.
    Stay on Top P°esouvß Sledovacφ okno nad ostatnφ okna v IDE.
    Break When Changed Kdy₧ se prom∞nnß ve Sledovacφm okn∞ zm∞nφ, pak lad∞nφ je p°eruÜeno. Zm∞n∞nß prom∞nnß je zobrazena Φerven∞.

    Volby Edit Watch a Add Watch zobrazujφ dialogovΘ okno vlastnostφ sledovßnφ (okno lze takΘ zobrazit dvojit²m kliknutφm na sledovanΘm prvku). Do Φßsti Expression v hornφ Φßsti okna zadßvßme jmΘno editovanΘ nebo p°idßvanΘ prom∞nnΘ. Jednß se o kombinovanΘ okno, kterΘ lze pou₧φt k v²b∞ru d°φve pou₧it²ch sledovacφch prvk∙. Polo₧ku Repeat Count pou₧φvßme p°i zkoumßnφ polφ. Umo₧≥uje urΦit, kolik prvk∙ pole mß b²t vypisovßno. Pokud zde nezadßme ₧ßdnou hodnotu, pak jsou vypisovßny vÜechny prvky pole. Polo₧ka Digits je pou₧φvßna p°i zkoumßnφ reßln²ch hodnot. Zadßvßme zde poΦet v²znamn²ch Φφslic, kterΘ majφ b²t zobrazovßny (provßdφ se zaokrouhlovßnφ). ZnaΦka Enabled urΦuje zda souΦasn² prvek je prßv∞ povolen. Okno obsahuje jeÜt∞ °adu voliΦ∙, kterΘ slou₧φ k nastavenφ zp∙sobu zobrazenφ hodnoty.
    JednotlivΘ prvky Sledovacφho okna mohou b²t povolenΘ nebo zakßzanΘ. ZakßzanΘ prvky jsou zobrazeny nev²razn∞ a jako svou hodnotu zobrazujφ <disabled>.
    Prom∞nnou do sledovacφho okna lze p°idat n∞kolika zp∙soby. NejrychlejÜφ je kliknout na jmΘnu prom∞nnΘ v Editoru k≤du a v mφstnφ nabφdce editoru zvolit Add Watch at Cursor. Sledovan² prvek je p°φmo p°idßn do Sledovacφho okna. Ostatnφ zp∙soby p°idßvßnφ prom∞nnΘ, zobrazφ dialogovΘ okno Vlastnostφ sledovßnφ.
    P°i dosa₧enφ bodu p°eruÜenφ, Sledovacφ okno zobrazuje souΦasnΘ hodnoty prom∞nn²ch uveden²ch ve Sledovacφm okn∞. Pokud Sledovacφ okno nenφ otev°eno, pak jej zobrazφme volbou View | Watches.

  13. Inspektor lad∞nφ umo₧≥uje zobrazit data objekt∙ (jako jsou t°φdy nebo komponenty). Umo₧≥uje takΘ prohlφ₧et jednoduchΘ datovΘ typy. Inspektor lad∞nφ je mo₧no pou₧φt pouze p°i p°eruÜenφ provßd∞nφ programu. K prohlΘdnutφ objektu klikneme na jmΘn∞ objektu ve zdrojovΘm k≤du a v mφstnφ nabφdce Editoru k≤du zvolφme Inspect. Okno Inspektora objekt∙ obsahuje detaily zobrazenΘho objektu. P°i prohlφ₧enφ t°φdy, okno Inspektora objekt∙ obsahuje t°i strßnky. Strßnka Data zobrazuje vÜechny datovΘ slo₧ky t°φdy v hierarchickΘm seznamu (nejprve jsou data vlastnφ t°φdy a dßle data p°edk∙). K dalÜφ inspekci datovΘ slo₧ky dvojit∞ klikneme na sloupci hodnot datovΘ slo₧ky. Tφm otev°eme dalÜφ okno Inspektora lad∞nφ pro urΦenou datovou slo₧ku. Strßnka Methods Inspektora lad∞nφ zobrazuje metody t°φdy. Strßnka Properties zobrazuje vlastnosti t°φdy. Strßnky Methods a Properties jsou zobrazeny pouze p°i zkoumßnφ t°φdy. P°i zkoumßnφ jednoduch²ch datov²ch typ∙ je zobrazena pouze strßnka Data.

  14. Mφstnφ nabφdka Inspektora lad∞nφ obsahuje n∞kolik voleb, kterΘ umo₧≥ujφ pracovat s Inspektorem lad∞nφ a jednotliv²mi prom∞nn²mi. T∞mito volbami se zde nebudeme podrobn∞ji zab²vat. Inspektor lad∞nφ poskytuje kompletnφ p°ehled o stavu objektu.
    ╚asto si pot°ebujeme prohlΘdnou vÜechny lokßlnφ prom∞nnΘ prßv∞ provßd∞nΘ funkce. Lze to provΘst jejich p°idßnφm do Sledovacφho okna. LepÜφ mo₧nostφ je volba Run | Inspect Local Variables. P°i pou₧itφ tΘto volby okno Inspektora lad∞nφ zobrazφ hodnoty vÜech lokßlnφch prom∞nn²ch souΦasn∞ provßd∞nΘ funkce.
    S dalÜφmi mo₧nostmi ladφcφho prost°edku se op∞t seznßmφme v dalÜφ kapitole.
7. Textov² editor II