online kép - Fájl  tubefájl feltöltés file feltöltés - adja hozzá a fájlokat onlinefedezze fel a legújabb online dokumentumokKapcsolat
  
 

Letöltheto dokumentumok, programok, törvények, tervezetek, javaslatok, egyéb hasznos információk, receptek - Fájl kiterjesztések - fajltube.com

Online dokumentumok - kep
  

Delphi gyakorló feladatok

számítógépes



felso sarok

egyéb tételek

jobb felso sarok
 
FOLYAMATVIZUALIZÁLÓ ÉS SCADA PROGRAM-RENDSZEREK
A rendszer karbantartasa
A szamítógép-halózatok hasznalata
Adatbevitel, szűrés, rendezés adatlap nézetben - ACCESS
TCP szerver készítése
Bűvész programok, utility-k
Delphi gyakorló feladatok
Osztott adatbazisok
Nemzetközi szamítógépes halózatokon elérhető adatbazisok
Delphi gyakorló feladatok
 
bal also sarok   jobb also sarok

Delphi gyakorló feladatok

Téma: Futás idejű grafika használata II.

Megismerendő eszközök


Ebben a feladatban olyan egyszerű grafikai alkalmazást készítünk, melynek segítségével vonalas rajzokat, alakzatokat készíthetünk az egér bizonyos eseményeinek hatására. A programkészítés fő lépései a következők lesznek:


Az egérhez kapcsolódó események kezelése

Eszköztár készítése gyorsító gombokkal

Toll és ecset beállítás

Státuszsor készítése

Bitmap-re történő rajzolás

Grafika nyomtatása

Munka grafikus állományokkal

A vágólap grafikus tartalmának használata



Az egérhez kapcsolódó események kezelése


Négy olyan egérhez kapcsolódó esemény van, amelyekre az alkalmazásban reagálhatunk. A következő három önálló esemény: egérgomb lenyomása , felengedése és az egér mozgatása. A negyedik, az egérrel történő kattintás azonban egy kicsit eltér az előzőektől, mert az bizonyos esetekben speciális billentyű kombináció eredményeként is generálható (pl. Enter leütése modális dialógusablakban). Ebben a feladatban csak az önálló egéreseményekkel foglalkozunk.


Az alkalmazásban az egér által kiváltott események hatására alakzatokat fogunk rajzolni: az egérgomb lenyomására kezdjük, felengedésére befejezzük a rajzot. A fix kiindulópont és a felengedés pillanatáig változó végp 111d34b ont között folyamatosan új és új alakzatokat kell rajzolni, az előző állapotokat pedig törölni kell. Elsőként egy szakaszt próbálunk megjeleníteni a fenti technikával. Később pedig más alakzatokat is.

A Delphi önálló egéreseményei


A Delphi három önálló egéreseményének: (OnMouseDown, OnMouseMove és OnMouseUp) öt-öt paramétere van. Ezek a következők:


Paraméter Jelentés

Sender Az objektum, mely detektálta az eseményt.

Button A lenyomott egérgomb: mbLeft, mbMiddle, vagy mbRight.

Shift           Speciális billentyűk állapotát adja vissza az esemény pillanatában: Alt, Ctrl és Shift billentyűk.

X, Y           A pont koordináta, ahol az esemény történt.


A legtöbb esetben a koordináták értéke az elsődleges, de sokszor az egérgombokat is figyelni kell, hogy melyik generálta az eseményt.


Az egérgomb lenyomására történő reakció


Valahányszor a felhasználó lenyom egy egérgombot, akkor egy OnMouseDown esemény játszódik le. Ebben a feladatban a lenyomás hatására kezdjük majd el a rajzolást.


Azért, hogy vizsgálni tudjuk az eseménykezelőt, próbáljunk meg egy rövid szöveget kiírni a lenyomás helyszínén. Az X és Y paraméterek segítségével a TextOut metódust hívjuk meg a szöveg megjelenítésére:


procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y:             Integer);

begin

Canvas.TextOut(X, Y, IntToStr(X)+', '+IntToStr(Y));

end;


Teszteljük a kódot.


A megoldandó feladatban az egérgomb lenyomása csak a szakasz kiinduló pontját azonosítja. Ezért elsőként módosítsuk az eseménykezelőt:


procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

Canvas.MoveTo(X, Y);

end;


Az egérgomb felengedéséhez kapcsolódó eseménykezelő


Az OnMouseUp esemény akkor történik, amikor felengedjük az egérgombot.

A feladatban egy szakaszt jelenítünk meg a felengedést lekezelő eljárásban:


procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

Canvas.LineTo(X, Y);

end;


Futás során azonban csak akkor láthatjuk a szakaszokat, ha már felengedtük az egérgombot.


Az egér mozgásának követése


Az OnMouseMove esemény akkor történik, amikor a felhasználó mozgatja az egeret.


Készítsük el a következő eseménykezelőt az egér OnMouseMove eseményéhez:


procedure TForm1.FormMouseMove(Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

Canvas.LineTo(X, Y);

end;


Ekkor azonban nem csak akkor készül rajz ha lenyomott az egérgomb, hanem az egér minden megmozdítása egy-egy rövid szakaszt eredményez. Kézenfekvő, hogy el kell tárolni egy változóban azt, hogy lehetséges-e a rajzolás.


A Drawing Boolean változót deklaráljuk a form public változói között.

Hasonlóan deklaráljuk az Origin-nak és a MovePt-nak nevezett pontokat is:


type

TForm1 = class(TForm)

procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

procedure FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormMouseMove(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

public

Drawing: Boolean;

Origin, MovePt: TPoint;

end;


Módosítsuk az eseménykezelőket az alábbiak szerint, majd teszteljük a programot:


procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

Drawing := True;

Canvas.MoveTo(X, Y);

end;


procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin

Canvas.LineTo(X, Y);

Drawing := False;

end;


procedure TForm1.FormMouseMove(Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y:             Integer);

begin

if Drawing then

Canvas.LineTo(X, Y);

end;


Habár most már csak az egérgomb lenyomása és felengedése között rajzolunk, az eredmény mégsem megfelelő, mert nem a kiinduló pontot köti össze a rajzunk az aktuális ponttal. Ennek az az oka, hogy a LineTo eseménykezelő folyamatosan módosítja az aktuális rajzpoziciót. Az Origin és a MovePt éppen ezért a kezdő és közbenső pontokat fogja azonosítani.


Állítsuk be az Origin változó értékét úgy, hogy a mouse-down esemény eltárolja a kívánt kezdőpontot és a mouse-up esemény innen kezdi majd a vonal húzását:

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y:             Integer);

begin

Drawing := True;

Canvas.MoveTo(X, Y);

Origin := Point(X, Y);

end;


procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y:             Integer);

begin

Canvas.MoveTo(Origin.X, Origin.Y);

Canvas.LineTo(X, Y);

Drawing := False;

end;


procedure TForm1.FormMouseMove(Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y:             Integer);

begin

if Drawing then

Canvas.MoveTo(Origin.X, Origin.Y);

Canvas.LineTo(X, Y);

end;


A továbbiakban már csak az előzőleg kirajzolt szakaszt kell mindig törölnünk. Az előző szakasz végpontjának eltárolására használjuk a MovePt korábban már deklarált változót.


Állítsuk be a MovePt pontot a közbenső szakaszok végpontjának, így törölhetjük az előző szakaszt a MovePt és az Origin pontok ismeretében:


procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

Drawing := True;

Canvas.MoveTo(X, Y);

Origin := Point(X, Y);

MovePt := Point(X, Y);

end;


procedure TForm1.FormMouseMove(Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

if Drawing then

begin

Canvas.Pen.Mode := pmNotXor; Canvas.MoveTo(Origin.X, Origin.Y);

Canvas.LineTo(MovePt.X, MovePt.Y);

Canvas.MoveTo(Origin.X, Origin.Y);

Canvas.LineTo(X, Y);

end;

MovePt := Point(X, Y);

Canvas.Pen.Mode := pmCopy;

end;


A toll módjának pmNotXor-ra állítása biztosítja a pixelek folyamatos törlését ha nem háttérszínűek voltak azok, illetve beállítását ellenkező esetben. A pmCopy-ra való visszaállítás eredményezi, hogy az egérgomb felengedése után a toll kirajzolja az utolsó  szakaszt.


A többi alakzatot is hasonló technikával kell majd kirajzolni. Ehhez azonban előbb lehetőséget kell biztosítani az alakzatok közötti választásra.

Eszköztár használata


Az eszköztár (tool bar) egy panel, amely rendszerint a form tetején a menüsor alatt helyezkedik el és vezérlő eszközöket, többnyire gyorsító gombokat tartalmaz.


Az eszköztár elkészítése érdekében a következőket kell megoldani:


Helyezzünk egy Panel komponenst a form-ra.

Állítsuk be a panel Align tulajdonságát alTop-ra. Ennek a beállításnak a hatására a panel állandó magassága mellett a szélessége megegyezik folyamatosan a form kliensterületének a szélességével, ha átméretezzük az ablakot.

Helyezzünk el gyorsító gombokat és más vezérlő elemeket a panelra.


A mintafeladat megoldásához készítsünk elő egy eszköztárat egy panel komponens használatával. Töröljük a Caption tulajdonságát.


A későbbiekben fogjuk elhelyezni a gyorsító gombokat és újabb eszköztárakat is létre fogunk hozni.


Gyorsító gombok elhelyezése az eszköztáron


Az eszköztárak készítéséhez a Delphi speciális gombokat (speed button) biztosít. A gyorsító gomboknak nem szokott felirata lenni, hanem csak egy kis grafika (glyph) jelenik meg rajtuk. A gyorsító gombnak háromféle funkciója lehet:


Szabályos nyomógombként funkcionálhat.

Ki - és bekapcsolhatóak, ha rákattintunk.

Rádiógombként is használhatóak.


Gyorsító gombok eszköztáron való alkalmazásakor négy feladatot kell megoldanunk:


A gyorsító gombot az eszköztárra kell helyeznünk.

Grafikát (glyph) kell hozzárendelnünk a gombhoz.

A kezdeti feltételeket be kell állítanunk.

Csoportosítani kell a gyorsító gombokat.


Helyezzünk hat gyorsító gombot az eszköztárra az alábbi ábra szerinti elrendezésben és változtassuk meg a nevüket, ahogy az jelezve van.



Az alapértelmezett magassága az eszköztárnak 41 pixel, a gyorsító gombnak 25. Ha a gombok Top tulajdonságát 8-ra állítjuk, akkor éppen középen helyezkednek el függőleges irányban a panelen.


Minden gyorsító gombon célszerű elhelyezni egy olyan grafikus ábrát, amely a gomb funkciójára utal. Ha egy képet rendelünk a gombhoz, akkor a gomb működése során jelzi, hogy a gomb benyomott-e vagy sem. Lehetőség van azonban arra, hogy különböző képeket rendeljünk a gomb különböző állapotaihoz. Általában tervezési időben rendelünk képet a gyorsító gombhoz, futási időben pedig a különböző képeket cserélhetjük.


A kép (glyph) hozzárendelése a gyorsító gombhoz a következő módon történik tervezési időben:


Kiválasztjuk a gombot

Az objektum felügyelőben a Glyph tulajdonság érték oszlopában duplán kattintunk.

A Delphi megnyitja a képszerkesztőt és a Load paranccsal tölthetünk be képet., amit majd az <OK> gombbal rendelhetjük a gyorsító gombhoz.


Készítsünk és/vagy rendeljünk az ábrának megfelelő képeket a gyorsító gombokhoz.



A gyorsító gombok kezdeti állapotának beállítása


Ahhoz, hogy egy gyorsító gomb lenyomott állapotban jelenjék meg, állítsuk a Down tulajdonságát True-ra.


Mivel az elkészítendő alkalmazásban a vonal az alapértelmezett rajzolási alakzat, állítsuk a LineButton Down tulajdonságát True-ra.


Gyorsító gombok csoportba sorolása


A gyorsító gombok egy halmaza gyakran reprezentál egymást kölcsönösen kizáró választásokat. Ekkor a gombokat csoportba kell foglalni és ha a csoport valamelyik elemére kattintunk, kiválasztjuk azt, akkor a többi gomb kiemelt állapotban kell hogy megjelenjék. A csoportbasorolást a GroupIndex tulajdonság ugyanolyan értékre történő beállításával valósíthatjuk meg.


A rajzolási alakzatokat megjelenítő gombok kizáró választásokat testesítenek meg, ezért rendeljük a GroupIndex tulajdonságukhoz az 1 értéket.


Gyakran előforduló feladat, hogy olyan csoportban szereplő gombot kell készítenünk, mely más gomboktól függetlenül benyomható illetve kikapcsolható. Ezt a funkciót az AllowAllUp tulajdonság beállításával generálhatjuk. Ha ezt a tulajdonságot True-ra állítottuk, akkor minden a csoportban elhelyezkedő gombra is arra áll és lehetővé teszi azt, hogy mindig csak egy gomb legyen kiválasztott, vagy a kiválasztottságot meg tudjuk szüntetni.


Mind a tollhoz, mind az ecsethez tartozó gomb AllowAllUp property-jét állítsuk True-ra, majd rendeljünk a PenButton-hoz 2-es GroupIndex értéket, a BrushButton-hoz 3-t.


Rajzolás különböző eszközökkel


A grafikus programban folyamatosan tudnunk kell, hogy a felhasználó milyen rajzeszközt választott. Egy felsorolt típust deklarálunk erre a célra.


A form típus deklarációs részéhez adjuk a TDrawingTool típus deklarációját:


type

TDrawingTool = (dtLine, dtRectangle, dtEllipse, dtRoundRect);

TForm1 = class(TForm)


Megjegyzés: a Delphi konvenciói szerint a típusok deklarációját T-vel kezdjük, a hasonló konstansokat (pl. felsorolt típus elemei) pedig 2 karakteres előtaggal, (a dt jelentése: "drawing tool").


A form deklarációjához rendeljük a DrawingTool változót, amely az aktuális rajzolási eszközt fogja jelenteni.


public

Drawing: Boolean;

Origin, MovePt: TPoint;

DrawingTool: TDrawingTool;

end;


Mivel az objektumok mezői a zéró értékkel lesznek inicializálva, így a DrawingTool értéke indításkor dtLine lesz.


A rajzolási eszközök változtatásához készítsük el a következő eseménykezelőket, amelyek megváltoztatják a DrawingTool változó értékét annak megfelelően, hogy melyik gyorsító gombot nyomtuk meg.


procedure TForm1.LineButtonClick(Sender: TObject);

begin

DrawingTool := dtLine;

end;


procedure TForm1.RectangleButtonClick(Sender: TObject);

begin

DrawingTool := dtRectangle;

end;


procedure TForm1.EllipseButtonClick(Sender: TObject);

begin

DrawingTool := dtEllipse;

end;


procedure TForm1.RoundedRectButtonClick(Sender: TObject);

begin

DrawingTool := dtRoundRect;

end;


A rajzolási eszközök beállítása utáni lépés az lesz, hogy a legelsőként megírt vonalszakasz rajzolásához hasonló eseménykezelőket készítsünk különböző rajzeszközök esetében is.


A rajzeszközök használata


A megfelelő alakzat kirajzolásához módosíthatnánk az eseménykezelőket az alábbiak szerint:


procedure TForm1.FormMouseUp(Sender: TObject);

begin

case DrawingTool of

dtLine:

begin

Canvas.MoveTo(Origin.X, Origin.Y);

Canvas.LineTo(X, Y)

end;

dtRectangle:

Canvas.Rectangle(Origin.X, Origin.Y, X, Y);

dtEllipse:

Canvas.Ellipse(Origin.X, Origin.Y, X, Y);

dtRoundRect:

Canvas.RoundRect(Origin.X, Origin.Y, X, Y, (Origin.X - X) div 2, (Origin.Y - Y) div 2); end;

Drawing := False;

end;


procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

begin

if Drawing then

begin

Canvas.Pen.Mode := pmNotXor;

case DrawingTool of

dtLine:

begin

Canvas.MoveTo(Origin.X, Origin.Y);

Canvas.LineTo(MovePt.X, MovePt.Y);

Canvas.MoveTo(Origin.X, Origin.Y);

Canvas.LineTo(X, Y);

end;

dtRectangle:

begin

Canvas.Rectangle(Origin.X, Origin.Y, MovePt.X, MovePt.Y);

Canvas.Rectangle(Origin.X, Origin.Y, X, Y);

end;

dtEllipse:

begin

Canvas.Ellipse(Origin.X, Origin.Y, X, Y);

Canvas.Ellipse(Origin.X, Origin.Y, X, Y);

end;

dtRoundRect:

begin

Canvas.RoundRect(Origin.X, Origin.Y, X, Y, (Origin.X - X) div 2,

(Origin.Y - Y) div 2);

Canvas.RoundRect(Origin.X, Origin.Y, X, Y, (Origin.X - X) div 2,

(Origin.Y - Y) div 2);

end;

end;

MovePt := Point(X, Y);

end;

Canvas.Pen.Mode := pmCopy;

end;


Mivel azonban ismétlődő részek vannak a kódban, ezért deklaráljunk egy alakzatrajzoló eljárást és ezt hívjuk majd a fenti rutinok módosított változatában.


A form objektum deklaráció public részéhez írjuk be a következő DrawShape eljárást:


type TForm1 = class(TForm)




public


procedure DrawShape(TopLeft, BottomRight: TPoint; AMode: TPenMode);

end;


Az implementation részben határozzuk meg a rutin működését:


procedure TForm1.DrawShape(TopLeft, BottomRight: TPoint; AMode: TPenMode);

begin

with Canvas do

begin

Pen.Mode := AMode;

case DrawingTool of

dtLine:

begin

MoveTo(TopLeft.X, TopLeft.Y);

LineTo(BottomRight.X, BottomRight.Y);

end;

dtRectangle:

Rectangle(TopLeft.X, TopLeft.Y, BottomRight.X, BottomRight.Y);

dtEllipse:

Ellipse(TopLeft.X, TopLeft.Y, BottomRight.X, BottomRight.Y);

dtRoundRect:

RoundRect(TopLeft.X, TopLeft.Y, BottomRight.X, BottomRight.Y,

(TopLeft.X - BottomRight.X) div 2, (TopLeft.Y - BottomRight.Y) div 2);

end;

end;

end;


Az eddigi eseménykezelőket pedig módosítsuk a DrawShape eljárás hívásával az alábbiak szerint:


procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

DrawShape(Origin, Point(X, Y), pmCopy);

Drawing := False;

end;


procedure TForm1.FormMouseMove(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y:             Integer);

begin

if Drawing then

begin

DrawShape(Origin, MovePt, pmNotXor);

MovePt := Point(X, Y);

DrawShape(Origin, MovePt, pmNotXor);

end;

end;


A toll és az ecset beállítása

A program fejlesztésének alábbi szakaszában a rajzolási színek és stílusok beállítása érdekében az alábbi tevékenységeket végezzük el:


Rejtett eszköztár elkészítése és annak be-, illetve kikapcsolása

A toll stílusának megváltoztatása

A toll színének módosítása

A toll vastagságának állítása

Az ecset stílusának módosítása

Az ecset színének szabályozása


Rejtett eszköztár elkészítése és annak be-, illetve kikapcsolása


Rejtett eszköztár készítéséhez a már megismert módszer szerint hozzunk létre egy eszköztárat (Ne felejtsük el a panel Align tulajdonságát alTop-ra állítani!) és állítsuk be Visible property-t False-ra.


Készítsünk egy PenBar és egy BrushBar nevű rejtett eszköztárakat, amint azt az alábbi ábra mutatja. A gyorsító gombokon kívül használjuk a következő komponenseket: ColorGrid, ScrollBar, és Label a PenBar esetében és ColorGrid a BrushBar estében


A komponensek beállítása a következő legyen:


Component        Property Value

SolidPen              Glyph SOLID.BMP

Down True

DashPen              Glyph DASHED.BMP

DotPen                Glyph DOTTED.BMP

DashDotPen        Glyph DASHDOT.BMP

DashDotDotPen  Glyph DASHDOT2.BMP

ClearPen              Glyph CLEAR.BMP

PenColor             BackgroundEnabled False

GridOrdering go8x2

Height 30

Top 5

Width 144

PenWidth            LargeChange 10

Top 12

PenSize               FocusControl PenWidth

Caption 1

Top 13

SolidBrush Glyph FSOLID.BMP

Down True

ClearBrush Glyph FCLEAR.BMP

HorizontalBrush Glyph FHORIZ.BMP

VerticalBrush      Glyph FVERT.BMP

FDiagonalBrush  Glyph FDIAG.BMP

BDiagonalBrush Glyph BDIAG.BMP

CrossBrush Glyph CROSS.BMP

DiagCrossBrush  Glyph DCROSS.BMP

BrushColor BackgroundEnabled False

GridOrdering go8x2

Height 30

Top 5

Width 144


Az eszköztárak elrejtése


Ha több eszköztárat alkalmazunk egy programban, akkor előfordul, hogy bizonyos eszköztárakat rendre el akarunk rejteni, ki akarjuk kapcsolni azokat. (Előfordul, hogy ezeken az eszköztárakon egy-egy bezárás gomb is szerepel.)


Ebben az alkalmazásban a fő eszköztár toll és ecset gombjának beállításával fogjuk az imént elkészített eszköztárakat ki-, illetve bekapcsolni:


procedure TForm1.PenButtonClick(Sender: TObject);

begin

PenBar.Visible := PenButton.Down;

end;


procedure TForm1.BrushButtonClick(Sender: TObject);

begin

BrushBar.Visible := BrushButton.Down;

end;


A toll stílusának megváltoztatása


A toll stílusa meghatározza, hogy milyen vonalat rajzolhatunk: tömör vonal, szaggatott vonal, pont-vonal, stb.

A feladatban egyetlen eseménykezelőt fogunk elkészíteni a lehetséges vonal beállításokhoz, és a Sender paraméter vizsgálatának függvényében rendeljük a megfelelő konstans értéket a toll stílusához.


Osszuk meg a következő eseménykezelőt a toll stílus gombjaihoz. Az eseménykezelő neve SetPenStyle legyen, amit természetesen az objektum felügyelő segítségével állítsunk be:


procedure TForm1.SetPenStyle(Sender: TObject);

begin

with Canvas.Pen do

begin

if Sender = SolidPen then Style := psSolid

else if Sender = DashPen then Style := psDash

else if Sender = DotPen then Style := psDot

else if Sender = DashDotPen then Style := psDashDot

else if Sender = DashDotDotPen then Style := psDashDotDot

else if Sender = ClearPen then Style := psClear;

end;

end;


A toll színének módosítása


A toll színének megváltoztatásához a toll Color tulajdonságát kell beállítani. A felhasználó a ColorGrid használatával fogja beállítani a színeket.


Készítsük el a következő eseménykezelőt a ColorGrid-en való kattintáshoz:


procedure TForm1.PenColorClick(Sender: TObject);

begin

Canvas.Pen.Color := PenColor.ForegroundColor;

end;


A toll vastagságának állítása


A toll vastagságának állításához a toll Width tulajdonságát kel állítani. A gördítősáv használatával ez a feladat egyszerűen megoldható.


Kezeljük a gördítősáv (scroll bar) OnChange eseményét a következők szerint:


procedure TForm1.PenWidthChange(Sender: TObject);

begin

Canvas.Pen.Width := PenWidth.Position;

PenSize.Caption := IntToStr(PenWidth.Position);

end;


Az ecset stílusának módosítása


Az ecset stílusa azt határozza meg, hogy milyen mintákat használhatunk az alakzatok kitöltéséhez. Az előre definiált konstansok segítségével speciális hatásokat érhetünk el: (bsSolid, bsClear, bsHorizontal, bsVertical, bsFDiagonal, bsBDiagonal, bsCross, bsDiagCross).


Válasszuk ki a nyolc ecset-stílus gombot és készítsük el a következő SetBrushStyle közös eseménykezelőt az OnClick kezelésre:


procedure TForm1.SetBrushStyle(Sender: TObject);

begin

with Canvas.Brush do

begin

if Sender = SolidBrush then Style := bsSolid

else if Sender = ClearBrush then Style := bsClear

else if Sender = HorizontalBrush then Style := bsHorizontal

else if Sender = VerticalBrush then Style := bsVertical

else if Sender = FDiagonalBrush then Style := bsFDiagonal

else if Sender = BDiagonalBrush then Style := bsBDiagonal

else if Sender = CrossBrush then Style := bsCross

else if Sender = DiagCrossBrush then Style := bsDiagCross;

end;

end;


Az ecset színének szabályozása


Az ecset színe határozza meg az alakzat szinét.


Az ecset eszköztárán elhelyezkedő ColorGrid komponenshez készítsük el a következő eseménykezelőt:


procedure TForm1.BrushColorClick(Sender: TObject);

begin

Canvas.Brush.Color := BrushColor.ForegroundColor;

end;


Státusz sor készítése


A státusz sor az ablakok alján szokott megjelenni és rendszerint szövegek megjelenítésére alkalmazzák. Panel komponensek segítségével könnyen készíthetünk státusz sorokat.


Státusz sor készítése céljából adjunk egy panelt a form-ra, nevezzük StatusBar-nak és állítsuk be az Align tulajdonságát alBottom-ra. Töröljük a panel Caption mezejének tartalmát.


Helyezzünk két további panelt (OriginPanel és CurrentPanel) a státusz sorra. Az egyiket igazítsuk balra (alLeft), a másikat pedig a megmaradt kliens területhez (alClient). Állítsuk be a kívánt 3-D effektusokat a BevelInner és BorderWidth tulajdonságokkal, majd módosítsuk az alábbi eseménykezelőket:


procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

Drawing := True;

Canvas.MoveTo(X, Y);

Origin := Point(X, Y);

MovePt := Origin;

OriginPanel.Caption := Format('Origin: (%d, %d)', [X, Y]);

end;


procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

begin

if Drawing then

begin

DrawShape(Origin, MovePt, pmNotXor);

MovePt := Point(X, Y);

DrawShape(Origin, Point(X, Y), pmNotXor);

end;

CurrentPanel.Caption := Format('Current: (%d, %d)', [X, Y]);

end;


Rajzolás a bimap-re


Bár gyakran előfordul, hogy direkt a form-ra rajzolunk, ennél jóval általánosabb, hogy egy alkalmazásban valamilyen bitmap-re kell rajzolnunk. A bitmap-ek nagyon hatékony lehetőséget biztosítanak olyan funkciókhoz, mint másolás, nyomtatás, mentés, stb. A bitmap természetesen eltérő méretű lehet, mint a form: lehet nagyobb, vagy kisebb. Egy gördítő box-ot (scroll box) helyezve a form-ra, és ebbe helyezve egy image komponenst, szinte tetszőleges méretű képet hatékonyan kezelhetünk, szükség esetén gördíthetünk..


Ebben az alkalmazásban az eszköztárak és a státusz sor közötti egész területet gördíthető részként fogjuk használni. Ezért helyezzünk egy scroll box komponenst a form-ra és állítsuk az Align tulajdonságát alClient-re, biztosítván azt, hogy a kép kitöltse szükség esetén a form teljes munkaterületét.


Az image control egy olyan komponens, amely lehetővé teszi, hogy bitmap, vagy metafile képet tartalmazzon. A méretét vagy kézzel, vagy futás közben állíthatjuk be.


Helyezzünk egy image control-t a form-ra úgy, hogy az a scroll box-ban helyezkedjék el. Állítsuk be az image tulajdonságait a következők szerint:


Tulajdonság  Érték

Name Image

AutoSize True

Left 0

Top 0


A bitmap kezdeti méretének beállítása


Amikor egy image komponenst helyezünk a form-ra az még nem tartalmaz képet. Csak a kép "tartóját" határozza meg. Az image control Picture tulajdonságát állíthatjuk tervezési időben, ha az a célunk, hogy mindig ugyanazt a képet tartalmazza. Szabályozhatjuk azonban futási időben is, ha valamely háttértárolón elhelyezkedő képet kell megjeleníteni, vagy amennyiben rajzolni szeretnénk rá. Ekkor futási időben kell egy üres bitmap-et létrehoznunk.


Az alkalmazás indításakor egy üres bitmap-nek kell megjelennie. Ezért a form OnCreate eseménykezelőjében hozzunk létre egy bitmap objektumot és az image Picture.Graphic tulajdonságához rendeljük azt hozzá:


procedure TForm1.FormCreate(Sender: TObject);

var

Bitmap: TBitmap;

begin

Bitmap := TBitmap.Create;

Bitmap.Width := 200;

Bitmap.Height := 200;

Image.Picture.Graphic := Bitmap;

end;


A hozzárendeléssel az image komponens lesz a bitmap tulajdonosa és így nem kell majd nekünk felszabadítani a futtatás végén.


Ha most teszteljük az alkalmazást, akkor már egy a szükség szerint gőrdítősávokkal szabályozható rajzolási területünk van, a rajzolási tevékenységek azonban nem látszanak, mert az alkalmazás még a form-ra rajzol.


Rajzolás a bitmap-re


Két dolgot kell megoldanunk annak érdekében, hogy a bitmap-re rajzoljunk a form helyett. Használjuk az image control canvas-át a form canvas-a helyett és az egér eseménykezelőit is az image control-hoz kell, hogy rendeljük.


Cseréljük le a "Canvas " string minden előfordulását "Image.Canvas "-ra. majd az objektum felügyelőben az image control OnMouseDown eseményéhez rendeljük FormMouseDown eseménykezelőt. Hasonlóan járjunk el az OnMouseMove és az OnMouseUp események esetében is. Ha szeretnénk, akkor a form eseménykezelői közül eltávolíthatjuk a már feleslegessé vált fenti három eljárást.. (Mivel a form sosem fogja megkapni az eseményeket, így nem szükséges e módosítás).


Menü készítése


Az alkalmazás vezérléséhez készítsük el a következő főmenüt.


Helyezzünk egy MainMenu komponenst a form-ra az alábbi beállításokkal:


&File &Edit

&New        Cu&t

&Open...    &Copy

&Save        &Paste

Save &as...

&Print

- <hyphen>

E&xit


A File|Exit parancshoz (OnClick) írjuk meg a következő eseménykezelőt:


procedure TForm1.Exit1Click(Sender: TObject);

begin

Close;

end;


Amikor a menürendszert használjuk, akkor észrevehetjük, hogy bizonyos esetekben felesleges vonalak jelennek meg a rajzon miután a menüelemre kattintottunk. Ennek az az oka, hogy a Windows néha egy mouse-up üzenetet küld.


Módosítsuk az OnMouseUp eseménykezelőt, ellenőrizzük a Drawing változó beállítását rajzolás előtt:


procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

if Drawing then

begin

DrawShape(Origin, Point(X, Y), pmCopy);

Drawing := False;

end;

end;


Grafika nyomtatása


Grafikus képek kinyomtatása egyszerű feladat Delphi-ben. A Printers unit-ot soroljuk fel a form uses-ai között. E unitban vannak deklarálva a Printer objektum, amely rendelkezik canvas tulajdonsággal és a kinyomtatandó lapot reprezentálja. A grafikus kép kinyomtatása érdekében másoljuk a képet a Printer canvas-ára.


Ha a File menü Print elemére kattintunk, akkor a következő eljárás futtatásával nyomtathatjuk ki a képet:


procedure TForm1.Print1Click(Sender: TObject);

begin

with Printer do

begin

BeginDoc;

Canvas.Draw(0, 0, Image.Picture.Graphic);

EndDoc;

end;

end;


Grafikus állományok használata


A feladat ezen részében az alábbiakat oldjuk meg:


Kép betöltése

Kép mentése

Kép helyettesítése


Helyezzünk egy-egy open-file, save-file dialog box-ot a form-ra. A CurrentFile string típusú változót pedig a form public változói közé vegyük fel. Ebben a változóban tároljuk majd az aktuális kép nevét.


Kép betöltése


Grafikus file betöltése érdekében használjuk az image control Picture objektumának LoadFromFile metódusát.


A File|Open menü OnClick eseményéhez készítsük el a következő eseménykezelőt:


procedure TForm1.Open1Click(Sender: TObject);

begin

if OpenDialog1.Execute then

begin

CurrentFile := OpenDialog1.FileName;

Image.Picture.LoadFromFile(CurrentFile);

end;

end;

Kép mentése


A Delphi Picture objektuma különböző formátumokat biztosít, ha menteni akarunk. Mindehhez a SaveToFile metódust kell csak meghívnunk. Ezen eljárás paramétere a fájl neve. Ha egy új képet szeretnénk menteni, vagy egy meglévőt más néven szeretnénk tárolni, akkor lehetőséget kell biztosítani, hogy a felhasználó beállíthassa az állomány nevét.


A File|Save és File|Save As menükhöz készítsük el az alábbi kezelőket:


procedure TForm1.Save1Click(Sender: TObject);

begin

if CurrentFile <> '' then

Image.Picture.SaveToFile(CurrentFile)

else

SaveAs1Click(Sender);

end;


procedure TForm1.SaveAs1Click(Sender: TObject);

begin

if SaveDialog1.Execute then

begin

CurrentFile := SaveDialog1.FileName;

Save1Click(Sender);

end;

end;

Kép helyettesítése


Ha egy image control Picture objektumához egy új grafikát rendelünk, akkor a régi grafika helyettesítődik. A helyettesítés előtt biztosítani kell, hogy a felhasználó beállíthassa a kép alapvető méreteit, vagy valamilyen alapértelmezett méreteket használhat. Ehhez készítsük el az alábbi form-ot, a hozzátartozó unit-ot nevezzük BMPDlg-nak, a form-ot pedig NewBmpForm-nak. Az edit box-okat az ábrán látható nevekkel azonosítsuk.



Adjuk a BMPDlg unit-ot a projektünkhöz és hivatkozzunk a főform uses részben a BMPDlg unit-ra is.


Ezután írjuk meg a következő eseménykezelőt a File|New parancs OnClick eseményéhez:


procedure TForm1.New1Click(Sender: TObject);

var

Bitmap: TBitmap;

begin

with NewBMPForm do

begin

ActiveControl := WidthEdit;

WidthEdit.Text := IntToStr(Image.Picture.Graphic.Width);

HeightEdit.Text := IntToStr(Image.Picture.Graphic.Height);

if ShowModal <> idCancel then

begin

Bitmap := TBitmap.Create;

Bitmap.Width := StrToInt(WidthEdit.Text);

Bitmap.Height := StrToInt(HeightEdit.Text);

Image.Picture.Graphic := Bitmap;

CurrentFile := '';

end;

end;

end;


Megjegyzés: Ha egy új bitmap-et rendelünk a Graphic tulajdonsághoz, akkor automatikusan lebomlik a régi bitmap és az új tulajdonosa lesz a Picture objektum.


A Clipboard használata grafika esetén


A Windows Clipboard-ját használhatjuk alkalmazások közötti adatcserére grafikák esetében is. A Delphi Clipboard objektuma egyszerű kezelési lehetőséget biztosít.


A ClipBrd unit-ot soroljuk fel a uses részben.


Grafika vágólapra helyezése


A vágólapra másoláshoz rendeljük a képet a Clipboard objektum Assign metódusával a vágólaphoz.


Az alkalmazásban az Edit|Copy menün történő kattintásra reagáljunk a következő eljárással:

procedure TForm1.Copy1Click(Sender: TObject);

begin

Clipboard.Assign(Image.Picture);

end;


Grafika vágólapra vágása


A kivágás hasonló a másoláshoz, de törölni kell a grafikát a forrásról, például a rajzolási terület fehérre festésével.


Az Edit|Cut menü OnClick eseményéhez rendeljük az alábbi eseménykezelőt:


procedure TForm1.Cut1Click(Sender: TObject);

var

ARect: TRect;

begin

Copy1Click(Sender);

with Image.Canvas do

begin

CopyMode := cmWhiteness;

ARect := Rect(0, 0, Image.Width, Image.Height);

CopyRect(ARect, Image.Canvas, ARect);

CopyMode := cmSrcCopy;

end;

end;


Grafika beillesztése


Ha a Windows vágólap bitmap grafikát tartalmaz, akkor beilleszthetjük azt bármely image objektumba. Elsőként hívjuk meg a Clipboard HasFormat metódusát, annak leellenőrzésére, hogy grafika van-e a vágólapon. A HasFormat Boolean értékű függvény és True-val tér vissza, ha a vágólap tartalma olyan formátumú, mint amit a paraméterben átadtunk a függvénynek. Ezután egyszerűen hozzárendelhetjük a vágólap tartalmát a bitmap-hez.


A Clipboard tartalmát az Edit|Paste menün való kattintás hatására fogjuk beilleszteni:


procedure TForm1.PasteButtonClick(Sender: TObject);

var

Bitmap: TBitmap;

begin

if Clipboard.HasFormat(CF_BITMAP) then

try

Bitmap.Assign(Clipboard);

Image.Canvas.Draw(0, 0, Bitmap);

finally

Bitmap.Free;

end;

end;

end;

Találat: 1750


Felhasználási feltételek