Delphi - Képernyő terület nagyítása

forráskód letöltése
Képzeljen el egy olyan programot, hogy ha lenyomja az egér bal gombját és elkezdi azt mozgatni, akkor folyamatosan kirajzolódik egy téglalap az egér pozícióján, bármely alkalmazás felett jár, és ennek a téglalapnak a képe megjelenik ebben az alkalmazásban a megadott mértékben felnagyítva.

A mellékelt példában egy ilyen alkalmazást láthat. Képzeljen el egy olyan programot, hogy ha lenyomja az egér bal gombját és elkezdi azt mozgatni, akkor folyamatosan kirajzolódik egy téglalap az egér pozícióján, bármely alkalmazás felett jár, és ennek a téglalapnak a képe megjelenik ebben az alkalmazásban a megadott mértékben felnagyítva.

A mellékelt példában egy ilyen alkalmazást láthat.


Nézzük először is az egér mozgatását. Mind a három, egérrel kapcsolatos eseményre szükségünk lesz (OnMouseMove, OnMouseDown, OnMouseUp).

Amikor lenyomjuk az egeret, akkor eltároljuk ezt az információt egy logikai változóban, hogy az egér gombja lenyomott állapotban van. Ezt az OnMouseUp eseménynél szintén állítjuk, de ott már az ellenkező értékre.

Lenyomáskor az FLast változónak alapértéket adunk, erre majd később szükségünk lesz.

Mikor létrejön az OnMouseMove esemény, akkor először ellenőrizzük, hogy az egér gomb le van-e nyomva, ha nincs, akkor nem csinálunk semmit, ha viszont igen, akkor a ClientToScreen függvénnyel meghatározzuk az egér koordináta pozícióját a képernyő koordináta rendszerében.

Az egér mozgásánál egy téglalapot kell folyamatosan kirajzolnunk és letörölnünk, ahogy mozog az egér.

Ezt úgy tesszük, hogy először törlünk a Rectangle eljárás hívásával, majd egy másik Rectangle hívással kirajzoljuk.

Törlésnél mindig a régi egér koordinátát kell figyelembe venni, melyet eltárolunk az FLast változóba. Az OnMouseDown-nál ezt a változót -1-re állítottuk, ezzel tudjuk jelezni, hogy még nem történt kirajzolás, így az első OnMouseMove esemény létrejöttekor nem kell törölni sem. Ezt ellenőrizzük is törlés előtt.

A téglalap bal felső koordinátája mindig az egér pozíciója lesz. A szélessége és magassága pedig a nagyítás mértékétől és a rajzoláshoz rendelkezésre álló terület nagyságától függ.

A téglalap rajzolásához nem használhatjuk a Form-ban lévő Canvas property-t, mert ezzel csak az adott Form-ra tudnánk rajzolni. Ezért a program indulásakor az OnCreate eseménynél létrehozunk egy saját TCanvas-t, melyhez a teljes képernyőt rendeljük rajzterületként.

Mivel a toll (Pen) kirajzolási módját pmNot-ra választjuk, így a kirajzoláskor a képernyő színeit inverzre változtatja. Ezzel elérjük azt, hogy ha egymás után kétszer rajzoljuk ugyanazt a téglalapot, akkor a második rajz után az nyomtalanul eltűnik, vagy így tudjuk letörölni a régi rajzot.

Mikor a felhasználó felengedi az egér gombját, akkor még szükségessé válik az utoljára kirajzolt téglalap törlése.

Miután az egér mozgatásánál megtörtént a téglalap aktualizálása, utána érvénytelenítjük az alkalmazásunk területét az Invalidate eljárással. Ezért létrejön a Form OnPaint eseménye, annak újrarajzolásához. Itt ha az egér gombja lenyomott állapotban van, akkor a StretchBlt függvény hívásával nagyítva kirajzoljuk az adott téglalapot a képernyőre.

A StretchBlt első paraméterében annak az eszköznek a leíróját kell megadnunk, ahová rajzolni szeretnénk. Ez jelen esetben maga a Form.

A következő négy paraméterben azt a befoglaló téglalapot adhatjuk meg, ahova a rajzolást el szeretnénk végezni.

A következő paraméter a forrás terület leírója, majd az ez utáni négy paraméter a forrás terület befoglaló téglalapja.

Az utolsó paraméterben a SRCCOPY konstans megadásával arra utasítjuk a függvényt, hogy egyszerű másolást hajtson végre.


Ezzel már majdnem készen is lennénk, de az eredmény elég elszomorítóan villogni fog az egér mozgatásánál. Történik ez mindazért, mert minden kirajzolása előtt letörlődik a képernyő területe. Vagyis fehér színnel lesz feltöltve a háttere és csak ezután kerül rá a nagyított kép.

Mivel mindig a teljes képernyő területet újrarajzoljuk, így felesleges előtte letörölni a régit. Ezért figyeltetjük, hogy mikor jön létre az WM_ERASEBKGND esemény és ha bekövetkezik, akkor az üzenet eredményének nullát adva letiltjuk a terület törlését.