-
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:
-
vytvoříme všechny služby MDI,
-
v podřízeném okně vytvoříme textový editor,
-
umožníme aplikaci zavádění a ukládání souborů,
-
přidáme možnost tisku a
-
zajistíme rozumné ukončení aplikace (dotaz na uložení neuloženého souboru
při uzavírání aplikace).
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í.
-
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.
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.
-
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:
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.
-
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:
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.
-
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:
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.
-
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.
-
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:
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í.
-
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:
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.
-
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).
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.
-
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.
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. |
-
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á.
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).
-
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í.
Dalšími činnostmi integrovaného ladícího prostředku se
budeme zabývat v následující kapitole.