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