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