online kép - Fájl  tube fájl feltöltés file feltöltés - adja hozzá a fájlokat online fedezze fel a legújabb online dokumentumok Kapcsolat
   
 

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
   
kategória
 

Biológia állatok Fizikai Földrajz Kémia Matematika Növénytan Számítógépes
Filozófia
Gazdaság
Gyógyszer
Irodalom
Menedzsment
Receptek
Vegyes

 
 
 
 













































 
 

Delphi gyakorló feladatok

számítógépes

Fájl küldése e-mail Esszé Projekt


egyéb tételek

 
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
 
 

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:

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

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

3.   Toll és ecset beállítás


4.   Státuszsor készítése

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

6.   Grafika nyomtatása

7.   Munka grafikus állományokkal

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

1.   Helyezzünk egy Panel komponenst a form-ra.

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

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

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

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

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

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

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

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

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

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

1.   Kiválasztjuk a gombot

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

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

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

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

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

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

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

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

1.   Kép betöltése

2.   Kép mentése

3.   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: 1013