-
Nynφ se budeme zab²vat aplikacφ grafickΘho editoru. Budeme zde pou₧φvat
palety nßstroj∙ (bude zapot°ebφ mnoho obrßzk∙) a abychom je nemuseli vytvß°et
sami op∞t si stßhneme ji₧ hotovou aplikaci. Nßsleduje
popis tΘto aplikace. Na formulß° jsou vlo₧eny t°i komponenty Panel.
Majφ nastaveny vlastnosti Align na alTop (tφm zabφrajφ celou
Üφ°ku formulß°e), majφ zruÜen² titulek a obsahujφ tlaΦφtka.
TlaΦφtka na hornφm panelu se jmenujφ: LineButton, RectangleButton,
EllipseButton,
RoundRectButton,
PenButton
a BrushButton. Majφ p°i°azeny vhodnΘ obrßzky. U prvnφho tlaΦφtka
je nastavena jeho vlastnost
Down na true a z prvnφch Φty°
tlaΦφtek je vytvo°ena skupina (GroupIndex
je nastaveno na 1). TlaΦφtka
Pera
a èt∞tce (poslednφ dv∞ tlaΦφtka) jsou jedno tlaΦφtkovΘ skupiny,
kterΘ pracujφ jako p°epφnacφ. Majφ nastaveny vlastnosti AllowAllUp
na true a vlastnost
GroupIndex pro PenButton na 2
a pro BrushButton na 3.
Budeme se sna₧it vytvo°enou paletu nßstroj∙ zapojit do prßce. Zapamatujeme
si zvolen² nßstroj a p°i dalÜφ prßci jej budeme pou₧φvat. K zapamatovßnφ
zvolenΘho nßstroje je nejvhodn∞jÜφ pou₧φt v²Φtov² typ. P°idßme tedy p°ed
deklaraci typu formulß°e deklaraci v²ΦtovΘho typu TDrawingTool a
slo₧ku DrawingTool tohoto typu vlo₧φme do ve°ejnΘ Φßsti deklarace
typu formulß°e (jsou zde p°idßny i slo₧ky, o kter²ch jsme se zmφnili na
zßv∞r p°edchozφ kapitoly a slo₧ka pro ulo₧enφ jmΘna souboru):
enum TDrawingTool {dtLine, dtRectangle, dtEllipse,
dtRoundRect};
bool Drawing;
TPoint Origin, MovePt;
TDrawingTool DrawingTool;
AnsiString CurrentFile;
Zm∞nu nßstroje provßdφme v reakci na udßlost OnClick stisknutΘho
tlaΦφtka. Vytvo°φme tedy nßsledujφcφ obsluhy udßlostφ:
void __fastcall TForm1::LineButtonClick(TObject
*Sender)
{
DrawingTool = dtLine;
}
void __fastcall TForm1::RectangleButtonClick(TObject
*Sender)
{
DrawingTool = dtRectangle;
}
void __fastcall TForm1::EllipseButtonClick(TObject
*Sender)
{
DrawingTool = dtEllipse;
}
void __fastcall TForm1::RoundRectButtonClick(TObject
*Sender)
{
DrawingTool = dtRoundRect;
}
Nynφ ji₧ m∙₧eme °φci formulß°i, kter² typ nßstroje mß pou₧φt a je nutno
jeÜt∞ formulß° nauΦit jak jej mß pou₧φt. Kreslφcφ nßstroj se pou₧φvß v
obsluhßch udßlostφ OnMouseUp a OnMouseMove. Tyto obsluhy
vyu₧φvajφ zvolen² nßstroj (jeden ze Φty° mo₧n²ch) k provedenφ kreslenφ.
void __fastcall TForm1::FormMouseUp(TObject
*Sender,
TMouseButton Button, TShiftState
Shift, int X, int Y)
{
switch (DrawingTool){
case dtLine:
Canvas->MoveTo(Origin.X,
Origin.Y);
Canvas->LineTo(X,
Y);
break;
case dtRectangle:
Canvas->Rectangle(Origin.X,
Origin.Y, X, Y);
break;
case dtEllipse:
Canvas->Ellipse(Origin.X,
Origin.Y, X, Y);
break;
case dtRoundRect:
Canvas->RoundRect(Origin.X,
Origin.Y, X, Y,
(Origin.X
- X) /2, (Origin.Y - Y) / 2);
break;
}
Drawing = false;
}
void __fastcall TForm1::FormMouseMove(TObject
*Sender,
TShiftState Shift,
int X, int Y)
{
if (Drawing) {
Canvas->Pen->Mode = pmNotXor;
switch (DrawingTool) {
case dtLine:
Canvas->MoveTo(Origin.X, Origin.Y);
Canvas->LineTo(MovePt.X, MovePt.Y);
Canvas->MoveTo(Origin.X, Origin.Y);
Canvas->LineTo(X, Y);
break;
case dtRectangle:
Canvas->Rectangle(Origin.X, Origin.Y, MovePt.X, MovePt.Y);
Canvas->Rectangle(Origin.X, Origin.Y, X, Y);
break;
case dtEllipse:
Canvas->Ellipse(Origin.X, Origin.Y, MovePt.X, MovePt.Y);
Canvas->Ellipse(Origin.X, Origin.Y, X, Y);
break;
case dtRoundRect:
Canvas->RoundRect(Origin.X, Origin.Y, MovePt.X, MovePt.Y,
(Origin.X - MovePt.X) / 2, (Origin.Y - MovePt.Y) / 2);
Canvas->RoundRect(Origin.X, Origin.Y, X, Y,
(Origin.X - X) / 2, (Origin.Y - Y) / 2);
break;
}
MovePt = Point(X,Y);
}
Canvas->Pen->Mode = pmCopy;
}
V t∞chto metodßch se n∞kolikrßt opakuje stejn² k≤d. Tento opakujφcφ
se k≤d vlo₧φme do samostatnΘ metody, kterou v obou obsluhßch pou₧ijeme.
Deklarace metody DrawShape je vlo₧ena do ve°ejnΘ Φßsti (na jejφ
konec) deklarace typu formulß°e (mohli bychom ji vlo₧it i do soukromΘ Φßsti):
void __fastcall DrawShape(TPoint TopLeft,
TPoint BottomRight,
TPenMode AMode);
Definice tΘto metody je zapsßna do programovΘ jednotky. Metoda mß tento
tvar:
void __fastcall TForm1::DrawShape(TPoint
TopLeft, TPoint BottomRight,
TPenMode AMode){
Canvas->Pen->Mode = AMode;
switch (DrawingTool){
case dtLine :
Canvas->MoveTo(TopLeft.x,
TopLeft.y);
Canvas->LineTo(BottomRight.x,
BottomRight.y);
break;
case dtRectangle :
Canvas->Rectangle(TopLeft.x,
TopLeft.y,
BottomRight.x, BottomRight.y);
break;
case dtEllipse :
Canvas->Ellipse(TopLeft.x,
TopLeft.y,
BottomRight.x, BottomRight.y);
break;
case dtRoundRect :
Canvas->RoundRect(TopLeft.x,
TopLeft.y, BottomRight.x,
BottomRight.y, (TopLeft.x - BottomRight.x)/2,
(TopLeft.y - BottomRight.y)/2);
break;
}
}
Tato metoda je pou₧ita k dßle uvedenΘmu zjednoduÜenφ naÜich obsluh
udßlostφ:
void __fastcall TForm1::FormMouseUp(TObject
*Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
if (Drawing){
DrawShape(Origin, Point(X,
Y), pmCopy);
Drawing = false;
}
}
void __fastcall TForm1::FormMouseMove(TObject
*Sender,
TShiftState Shift, int X, int Y)
{
if (Drawing){
DrawShape(Origin, MovePt,
pmNotXor);
MovePt = Point(X, Y);
DrawShape(Origin, MovePt,
pmNotXor);
}
}
Tφm mßme volbu kreslφcφho nßstroje vy°eÜenou.
-
Dßle se budeme zab²vat dalÜφmi paletami nßstroj∙ (jedna se t²kß pera a
druhß Üt∞tce). Paleta nßstroj∙ nemusφ b²t stßle viditelnß. Pokud aplikace
obsahuje mnoho palet nßstroj∙, pak zobrazujeme pouze tu, kterou prßv∞ pou₧φvßme.
K vytvo°enφ skrytΘ palety nßstroj∙ nastavφme vlastnost panelu Visible
na false. V naÜi aplikaci mßme dv∞ dalÜφ komponenty panelu (budou
reprezentovat skrytΘ palety), jeden je nazvan² PenBar a druh² BrushBar
(jsou zruÜeny hodnoty jejich vlastnostφ Caption). Vlastnosti komponent
jsou nastaveny podle dalÜφho popisu (ovladaΦe jsou uvßd∞ny zleva doprava).
U prvnφch osmi tlaΦφtek z BrushBar (vzory v²pln∞) je nastavena vlastnost
GroupIndex
na 1 a u prvnφch Üesti tlaΦφtek z PenBar (typy Φar) je nastavena
GroupIndex
takΘ na 1.
TlaΦφtka na BrushBar jsou nazvßna takto: SolidBrush,
ClearBrush,
VerticalBrush,
HorizontalBrush,
FDiagonalBrush,
BDiagonalBrush,
CrossBrush,
DiagCrossBrush
a BrushColor. U prvnφho tlaΦφtka je nastavena vlastnost Down
na true. Obdobn∞ pro
PenBar se tlaΦφtka jmenujφ: SolidPen,
DashPen,
DotPen,
DashDotPen,
DashDotDotPen,
ClearPen
a PenColor. Prvnφ tlaΦφtko je op∞t stisknutΘ. Na tΘto palet∞ je
umφst∞n takΘ editaΦnφ ovladaΦ nazvan² PenSize a vlastnost
Text
je u n∞j nastavena na 1. K tomuto editaΦnφmu ovladaΦi je p°ipojena
komponenta UpDown (je pojmenovanß PenWidth a jejφ vlastnost
Associate je nastavena na
PenSize).
K ukrytφ nebo zobrazenφ palety nßstroj∙ m∞nφme jejφ vlastnost Visible
na false nebo true. Obvykle to provßdφme v reakci na jistou
udßlost nebo zm∞nu re₧imu aplikace. V naÜem p°φpad∞ skrytφ a zobrazovßnφ
palety pera a Üt∞tce budeme ovlßdat tlaΦφtky PenButton a BrushButton,
tedy obsluhami jejich stisku.
void __fastcall TForm1::PenButtonClick(TObject
*Sender)
{
PenBar->Visible = PenButton->Down;
}
void __fastcall TForm1::BrushButtonClick(TObject
*Sender)
{
BrushBar->Visible = BrushButton->Down;
}
Jestli₧e nynφ spustφme naÜi aplikaci, m∙₧eme zobrazovat a ukr²vat paletu
pera a paletu Üt∞tce (jsou umφst∞ny v hornφ Φßsti formulß°e pod paletou
kreslφcφch nßstroj∙).
Styl pera urΦuje typ zobrazovanΘ Φßry (plnß, Φßrkovanß, teΦkovanß atd.).
Ke zm∞n∞ stylu pera, nastavφme vlastnost pera Style na hodnotu urΦujφcφ
po₧adovan² styl. Je mo₧no pou₧φt n∞kterou z nßsledujφcφch konstant: psSolid,
psDash,
psDot,
psDashDot,
psDashDotDot
nebo
psClear. M∙₧eme tedy pro ka₧dΘ tlaΦφtko urΦujφcφ styl vytvo°it
obsluhu udßlosti
OnClick a p°i°adit v nφ odpovφdajφcφ konstantu
vlastnosti
Style. V naÜem programu budeme ale postupovat jin²m zp∙sobem.
Pro vÜechna tato tlaΦφtka vytvo°φme sdφlenou obsluhu udßlosti (nazveme
ji SetPenStyle) a stisknutΘ tlaΦφtko v nφ urΦφme pomocφ parametru
Sender.
void __fastcall TForm1::SetPenStyle(TObject
*Sender)
{
if (Sender == SolidPen)
Canvas->Pen->Style = psSolid;
else if (Sender == DashPen)
Canvas->Pen->Style = psDash;
else if (Sender == DotPen)
Canvas->Pen->Style = psDot;
else if (Sender == DashDotPen)
Canvas->Pen->Style = psDashDot;
else if (Sender == DashDotDotPen)
Canvas->Pen->Style = psDashDotDot;
else if (Sender == ClearPen)
Canvas->Pen->Style = psClear;
}
Barva pera urΦuje barvu kreslenΘ Φßry, vΦetn∞ obrys∙ kreslen²ch tvar∙.
Pro zm∞nu barvy pera zm∞nφme vlastnost pera Color. Barvu zadßvßme
volbou v dialogovΘm okn∞ barev Windows. Na formulß°i je komponenta ColorDialog,
a je vytvo°ena nßsledujφcφ obsluha udßlosti OnClick pro tlaΦφtko
PenColor:
ColorDialog1->Color = Canvas->Pen->Color;
if (ColorDialog1->Execute())
Canvas->Pen->Color = ColorDialog1->Color;
èφ°ka pera urΦuje tlouÜ¥ku Φßry v bodech. Ke zm∞n∞ Üφ°ky pera p°i°adφme
Φφselnou hodnotu vlastnosti pera Width. Obsluha udßlosti
OnChange
editaΦnφho ovladaΦe PenSize je tvo°ena p°φkazem:
Canvas->Pen->Width = PenWidth->Position;
Styl Üt∞tce urΦuje v²pl≥ov² vzor p°i vypl≥ovßnφ tvar∙. P°eddefinovanΘ
styly zahrnujφ plnou plochu, prßzdn² styl a r∙znΘ styly Ürafovßnφ. Pro
zm∞nu stylu Üt∞tce, nastavφme jeho vlastnost Style na jednu z p°eddefinovan²ch
hodnot: bsSolid, bsClear, bsHorizontal, bsVertical,
bsFDiagonal,
bsBDiagonal,
bsCross
nebo bsDiagCross. V naÜi aplikaci je sdφlenß obsluha udßlosti pro
vÜech osm tlaΦφtek stylu Üt∞tce (obdobn∞ jako pro styl pera):
void __fastcall TForm1::SetBrushStyle(TObject
*Sender)
{
if (Sender == SolidBrush) Canvas->Brush->Style
= bsSolid;
else if (Sender == ClearBrush) Canvas->Brush->Style
= bsClear;
else if (Sender == HorizontalBrush)
Canvas->Brush->Style = bsHorizontal;
else if (Sender == VerticalBrush)
Canvas->Brush->Style = bsVertical;
else if (Sender == FDiagonalBrush)
Canvas->Brush->Style = bsFDiagonal;
else if (Sender == BDiagonalBrush)
Canvas->Brush->Style = bsBDiagonal;
else if (Sender == CrossBrush) Canvas->Brush->Style
= bsCross;
else if (Sender == DiagCrossBrush)
Canvas->Brush->Style = bsDiagCross;
}
Barva Üt∞tce urΦuje barvu v²pln∞. P°i jejφ zm∞n∞ m∞nφme hodnotu vlastnosti
Üt∞tce Color. V naÜi aplikaci zm∞nu barvy Üt∞tce vy°eÜφme obdobn∞
jako zm∞nu barvy pera. Obsluha stisku tlaΦφtka ColorBrush je tvo°ena
p°φkazy:
ColorDialog1->Color = Canvas->Brush->Color;
if (ColorDialog1->Execute())Brush->Color
= ColorDialog1->Color;
Nynφ ji₧ m∙₧eme kreslit r∙znΘ tvary, m∞nit jejich barvy, zadßvat v²pl≥ovΘ
vzory apod. VyzkouÜejte.
-
Dßle se budeme zab²vat stavov²m °ßdkem. P°esto₧e m∙₧eme k vytvo°enφ stavovΘho
°ßdku vyu₧φt komponentu Panel, je jednoduÜÜφ pou₧φt p°φmo komponentu
StatusBar.
Tato komponenta nßm umo₧nφ rozd∞lit stavov² °ßdek na n∞kolik textov²ch
oblastφ. K vytvo°enφ stavov²ch panel∙ na stavovΘm °ßdku pou₧ijeme Editor
stavovΘho °ßdku a p°idßme k≤d pro aktualizaci jednotliv²ch stavov²ch panel∙.
M∙₧eme takΘ urΦit, jak zarovnßvat text na jednotliv²ch panelech. V naÜi
aplikaci pou₧ijeme stavov² °ßdek k zobrazovßnφ sou°adnic poΦßtku ka₧dΘho
prvku a sou°adnic aktußlnφ pozice myÜi. V naÜi aplikaci je na formulß°
p°idanß komponenta StatusBar, nazvanß StatusBar1 a je rozd∞lena
na dva panely. Dßle je p°idßn k≤d k obsluhßm udßlostφ, kterΘ aktualizujφ
stavov² °ßdek. Nßsleduje text zm∞n∞n²ch obsluh udßlostφ:
void __fastcall TForm1::FormMouseDown(TObject
*Sender,
TMouseButton Button,
TShiftState Shift, int X, int Y)
{
Drawing = true;
Canvas->MoveTo(X, Y);
Origin = Point(X, Y);
MovePt = Origin;
TVarRec tempvar[2] = {X, Y};
StatusBar1->Panels->Items[0]->Text
=
Format("Origin: (%d, %d)",
tempvar, 2);
}
void __fastcall TForm1::FormMouseMove(TObject
*Sender,
TShiftState Shift,
int X, int Y)
{
if (Drawing){
DrawShape(Origin, MovePt,
pmNotXor);
MovePt = Point(X, Y);
DrawShape(Origin, MovePt,
pmNotXor);
}
TVarRec tempvar[2] = {X, Y};
StatusBar1->Panels->Items[1]->Text
=
Format("Current: (%d,
%d)", tempvar, 2);
}
-
╚as, kdy kreslφme p°φmo na formulß° ji₧ minul. Mnohem Φast∞ji aplikace
kreslφ na bitovΘ mapy, nebo¥ bitovΘ mapy jsou velmi flexibilnφ pro operace
(jako je kopφrovßnφ, tisk nebo ulo₧enφ). Komponenta Image je komponenta,
kterß m∙₧e obsahovat bitovou mapu a umo₧≥uje snadnΘ vlo₧enφ jednΘ nebo
vφce bitov²ch map na formulß°. Bitovß mapa takΘ nemusφ mφt stejnou velikost
jako formulß°; m∙₧e b²t menÜφ nebo v∞tÜφ.
╚asto aplikace pot°ebuje zobrazovat vφce informacφ, ne₧ se vejde do
jistΘ oblasti. N∞kterΘ ovladaΦe (nap°. okna seznam∙) mohou automaticky
rolovat sv²m obsahem. I jinΘ ovladaΦe (vΦetn∞ samotnΘho formulß°e) takΘ
poskytujφ schopnost rolovßnφ. Builder obsluhuje tyto posuvnΘ oblasti ovladaΦem
naz²van²m posuvnΘ okno. PosuvnΘ okno se podobß panelu, kter² m∙₧e obsahovat
jinΘ ovladaΦe, ale posuvnΘ okno je normßln∞ neviditelnΘ. Jestli₧e ovladaΦe
obsa₧enΘ v posuvnΘm okn∞ nejsou ve viditelnΘ oblasti okna, pak je automaticky
zobrazen jeden nebo dva posuvnφky, umo₧≥ujφcφ rolovat oknem. K vytvo°enφ
posuvnΘ oblasti, umφstφme ovladaΦ
ScrollBox na formulß° a nastavφme
jeho meze na oblast, se kterou chceme rolovat (Φasto to provedeme pomocφ
vlastnosti Align). V naÜi aplikaci vytvo°φme posuvnou oblast zabφrajφcφ
celou plochu formulß°e mezi paletou nßstroj∙ a stavov²m °ßdkem. Na formulß°
je umφst∞na komponenta
ScrollBox a jejφ vlastnost Align je
nastavena na alClient.
Pomocφ komponenty Image specifikujeme oblast na formulß°i, kterß
m∙₧e obsahovat objekt obrßzku (nap°. bitovou mapu nebo metasoubor). Velikost
obrßzku lze nastavit manußln∞ nebo vyu₧φt ovladaΦ Image k udr₧ovßnφ
velikosti svΘho obrßzku p°i b∞hu aplikace. Jestli₧e p°edpoklßdßme, ₧e tento
ovladaΦ bude schopen m∞nit svou velikost, pak nastavφme umφst∞nφ jeho levΘho
hornφho rohu. V naÜi aplikaci je na formulß° p°idßna komponenta Image
a jsou u nφ nastaveny tyto vlastnosti: Name na Image, AutoSize
na true, Left na 0, Top na 0, Width
na 200 a Height na 200. Kdy₧ umφstφme ovladaΦ Image,
pak je bez obrßzku. Jestli₧e mß obsahovat n∞jak² obrßzek, m∙₧eme p°i nßvrhu
nastavit jeho vlastnost Picture. OvladaΦ takΘ m∙₧e zavΘst sv∙j obrßzek
ze souboru p°i b∞hu aplikace. Jestli₧e pot°ebujeme prßzdnou bitovou mapu
pro kreslenφ, m∙₧eme ji vytvo°it p°i b∞hu aplikace. K vytvo°enφ prßzdnΘ
bitovΘ mapy p°i spuÜt∞nφ aplikace vytvo°φme obsluhu udßlosti OnCreate
pro formulß° a vytvo°en² objekt bitovΘ mapy p°i°adφme vlastnosti Picture->Graphic
ovladaΦe Image.
void __fastcall TForm1::FormCreate(TObject
*Sender)
{
TBitmap *Bitmap = new Graphics::TBitmap();
Bitmap->Width = 200;
Bitmap->Height = 200;
Image->Picture->Graphic = Bitmap;
}
P°i°azenφ bitovΘ mapy vlastnosti Graphic obrßzku vytvß°φ vzßjemn²
vztah bitovΘ mapy a objektu obrßzku. Bitovou mapu tedy nenφ nutno ruÜit,
zruÜφ ji objekt obrßzku. M∙₧eme p°i°adit objektu obrßzku dalÜφ bitovou
mapu a obrßzek uvolnφ starou bitovou mapu a p°evezme °φzenφ novΘ. Jestli₧e
nynφ spustφme aplikaci, vidφme na klientskΘ oblasti formulß°e bφlou oblast
reprezentujφcφ bitovou mapu. Jestli₧e klientskß oblast okna nem∙₧e zobrazit
cel² obrßzek, jsou automaticky zobrazeny posuvnφky pomocφ nich₧ lze zobrazit
zbytek obrßzku. Obrßzek ale nelze kreslit, nebo¥ kreslenφ stßle probφhß
na formulß°i, kter² je nynφ p°ekryt posuvn²m oknem a komponentou Image.
Pro kreslenφ je nutno nynφ pou₧φt plßtno ovladaΦe Image namφsto
plßtna formulß°e. Nejsnadn∞ji to provedeme zm∞nou vÜech v²skyt∙ Canvas
na Image->Canvas v naÜφ programovΘ jednotce p°i°azenΘ k formulß°i.
Dßle musφme p°i°adit obsluhy udßlostφ myÜφ odpovφdajφcφm udßlostem ovladaΦe
Image.
V Inspektoru objektu zobrazφme udßlosti objektu Image a odpovφdajφcφm
udßlostem p°i°adφme ji₧ existujφcφ obsluhy udßlostφ formulß°e
FormMouseDown,
FormMouseMove
a FormMouseUp. P∙vodnφ obsluhy pro formulß° m∙₧eme zruÜit, ale nenφ
to nutnΘ. Nynφ po spuÜt∞nφ aplikace ji₧ m∙₧eme kreslit, ale pouze na ovladaΦi
Image.
M∙₧eme takΘ skr²t nebo zobrazit paletu pera nebo paletu Üt∞tce a rolovat
obrßzkem.
-
Aplikace obsahuje takΘ nabφdku. Nabφdka obsahuje obvyklΘ volby. Obsluha
volby File | Exit je tvo°ena p°φkazem:
Close();
Aplikaci m∙₧eme spustit a vyzkouÜet.
Tisk obrßzku z aplikace Builderu je jednoduch². Musφme p°idat hlaviΦkov²
soubor Printers.hpp do programovΘ jednotky formulß°e, kterß bude
tisknout. Tento hlaviΦkov² soubor deklaruje objekt nazvan² Printer,
kter² mß plßtno reprezentujφcφ tiÜt∞nou stranu. Obrßzek vytiskneme kopφrovßnφm
obrßzku na plßtno tiskßrny. V naÜi aplikaci vytvo°φme nßsledujφcφ obsluhu
udßlosti OnClick pro volbu File | Print:
void __fastcall TForm1::Print1Click(TObject
*Sender)
{
int BitmapInfoSize, BitmapImageSize;
long DIBWidth, DIBHeight;
PChar BitmapImage;
Windows::PBitmapInfo BitmapInfo;
Graphics::TBitmap *Bitmap;
Printer()->BeginDoc();
Bitmap = new Graphics::TBitmap();
Bitmap->Assign(Image->Picture);
GetDIBSizes(Bitmap->Handle,
BitmapInfoSize, BitmapImageSize);
BitmapInfo = (PBitmapInfo)
new char[BitmapInfoSize];
BitmapImage = (PChar)
new char [BitmapImageSize];
GetDIB(Bitmap->Handle,
0, BitmapInfo, BitmapImage);
DIBWidth = BitmapInfo->bmiHeader.biWidth;
DIBHeight = BitmapInfo->bmiHeader.biHeight;
StretchDIBits(Printer()->Canvas->Handle,
0, 0, DIBWidth, DIBHeight,
0, 0, DIBWidth, DIBHeight,
BitmapImage, BitmapInfo,
DIB_RGB_COLORS, SRCCOPY);
delete [] BitmapImage;
delete [] BitmapInfo;
delete Bitmap;
Printer()->EndDoc();
}
-
Obrßzky existujφ pouze p°i b∞hu aplikace. ╚asto chceme pou₧φt stejn² obrßzek
nebo chceme ulo₧it vytvo°en² obrßzek pro pozd∞jÜφ pou₧itφ. Komponenta Image
usnad≥uje zavßd∞nφ obrßzku a jejich uklßdßnφ. Princip uklßdßnφ a zavßd∞nφ
grafick²ch soubor∙ je stejn² jako u jin²ch soubor∙. Na formulß° tedy p°idßme
komponenty OpenDialog a SaveDialog. K zavedenφ grafickΘho
souboru do ovladaΦe Image volφme metodu LoadFromFile objektu
Picture
ovladaΦe Image. Obsluha udßlosti OnClick volby File |
Open vypadß takto:
void __fastcall TForm1::Open1Click(TObject
*Sender)
{
if (OpenDialog1->Execute()){
CurrentFile = OpenDialog1->FileName;
Image->Picture->LoadFromFile(CurrentFile);
}
}
Kdy₧ vytvo°φme nebo modifikujeme obrßzek, Φasto jej chceme ulo₧it do
souboru pro pozd∞jÜφ pou₧itφ. Objekt obrßzku m∙₧e uklßdat grafiku v n∞kolika
formßtech a v²vojß° aplikace m∙₧e vytvß°et a registrovat vlastnφ formßty
grafick²ch soubor∙, kterΘ objekt obrßzku pak m∙₧e pou₧φt. K ulo₧enφ obsahu
ovladaΦe Image do souboru volßme metodu SaveToFile objektu
Picture
ovladaΦe Image. Nßsledujφ obsluhy udßlostφ
OnClick voleb
File
| Save a File | Save As:
void __fastcall TForm1::Save1Click(TObject
*Sender)
{
if (CurrentFile != EmptyStr){
Image->Picture->SaveToFile(CurrentFile);
}
else{
SaveAs1Click(Sender);
}
}
void __fastcall TForm1::SaveAs1Click(TObject
*Sender)
{
if (SaveDialog1->Execute()){
CurrentFile = SaveDialog1->FileName;
Save1Click(Sender);
}
}
Obrßzek v ovladaΦi m∙₧eme kdykoli p°i b∞hu aplikace nahradit jin²m
obrßzkem. Jestli₧e p°i°adφme novou grafiku k obrßzku, kter² ji₧ mß grafiku,
pak novß grafika nahradφ existujφcφ. Vytvß°enφ novΘ grafiky je stejn² proces
jako jsme pou₧ili p°i vytvß°enφ inicializaΦnφ grafiky (obsluha udßlosti
OnCreate),
ale musφme dßt u₧ivateli mo₧nost zvolit i jinou ne₧ implicitnφ velikost
obrßzku. To snadno provedeme pomocφ dialogovΘho okna. NaÜe aplikace obsahuje
dialogovΘ okno NewBMPForm s editaΦnφmi ovladaΦi WidthEdit
a HeightEdit. Obsluha volby File | New je tvo°ena p°φkazy:
void __fastcall TForm1::New1Click(TObject
*Sender)
{
Graphics::TBitmap *Bitmap;
NewBMPForm->ActiveControl = NewBMPForm->WidthEdit;
NewBMPForm->WidthEdit->Text =
IntToStr(Image->Picture->Graphic->Width);
NewBMPForm->HeightEdit->Text =
IntToStr(Image->Picture->Graphic->Height);
if (NewBMPForm->ShowModal() != IDCANCEL){
Bitmap = new Graphics::TBitmap();
Bitmap->Width = StrToInt(NewBMPForm->WidthEdit->Text);
Bitmap->Height = StrToInt(NewBMPForm->HeightEdit->Text);
Image->Picture->Graphic
= Bitmap;
CurrentFile = EmptyStr;
}
}
Je d∙le₧itΘ pochopit, ₧e p°i°azenφ novΘ bitovΘ mapy k vlastnosti Graphic
objektu obrßzku, zp∙sobφ zruÜenφ existujφcφ bitovΘ mapy a vytvo°enφ vzßjemnΘho
vztahu s novou.
-
Schrßnku Windows m∙₧eme pou₧φt pro kopφrovßnφ a vklßdßnφ grafiky ve svΘ
aplikaci nebo k v²m∞n∞ grafiky s jinou aplikacφ. Objekt schrßnky pracuje
s r∙zn²mi typy informacφ, vΦetn∞ grafick²ch. D°φve ne₧ m∙₧eme pou₧φt objekt
schrßnky ve svΘ aplikaci, musφme p°idat hlaviΦkov² soubor Clipbrd.hpp
do jednotky, ve kterΘ chceme schrßnku pou₧φvat. M∙₧eme kopφrovat libovoln²
obrßzek, vΦetn∞ obsahu ovladaΦe Image do schrßnky. Po vlo₧enφ do
schrßnky je obrßzek p°φstupn² pro vÜechny aplikace Windows. Pro kopφrovßnφ
obrßzku do schrßnky p°i°adφme obrßzek k objektu schrßnky pou₧itφm metody
Assign.
V naÜφ aplikaci je nßsledujφcφ obsluha volby Edit | Copy.
void __fastcall TForm1::Copy1Click(TObject
*Sender)
{
Clipboard()->Assign(Image->Picture);
}
Vyjmutφ grafiky do schrßnky se podobß kopφrovßnφ, s tφm, ₧e je jeÜt∞
nutno zruÜit kopφrovanou grafiku. Nejprve vytvo°φme kopii ve schrßnce a
potom zruÜφme originßl. Nßsleduje obsluha volby Edit | Cut:
void __fastcall TForm1::Cut1Click(TObject
*Sender)
{
TRect ARect;
Copy1Click(Sender);
Image->Canvas->CopyMode = cmWhiteness;
ARect = Rect(0, 0, Image->Width, Image->Height);
Image->Canvas->CopyRect(ARect, Image->Canvas,
ARect);
Image->Canvas->CopyMode = cmSrcCopy;
}
Jestli₧e schrßnka obsahuje bitovou mapu, m∙₧eme ji vlo₧it do libovolnΘho
objektu obrßzku, vΦetn∞ ovladaΦe Image nebo samotnΘho formulß°e.
Pro vlo₧enφ grafiky ze schrßnky, volßme metodu schrßnky HasFormat
k zjiÜt∞nφ, zda schrßnka obsahuje grafiku (pro test na grafiku p°edßme
metod∞ parametr CF_BITMAP) a pokud schrßnka grafiku obsahuje, pak
ji p°i°adφme. V naÜi aplikaci je nßsledujφcφ obsluha volby
Edit | Paste:
void __fastcall TForm1::Paste1Click(TObject
*Sender)
{
Graphics::TBitmap *Bitmap;
if (Clipboard()->HasFormat(CF_BITMAP)){
Bitmap = new Graphics::TBitmap();
try{
Bitmap->Assign(Clipboard());
Image->Canvas->Draw(0,
0, Bitmap);
delete Bitmap;
}
catch(...){
delete Bitmap;
}
}
}
Nynφ ji₧ se schrßnkou m∙₧eme pracovat b∞₧n²m zp∙sobem a lze ji tedy
vyu₧φt pro p°enos obrßzk∙ mezi r∙zn²mi aplikacemi. NaÜe aplikace je hotova.
-
Pokuste se aplikaci grafickΘho editoru doplnit n∞jakou dalÜφ Φinnostφ.
Vytvo°te pro tuto aplikaci takΘ nßpov∞du.