Cikk Együttműködés a régiók


Windows API biztosít egy sor funkciót, amely lehetővé teszi, hogy leírja tetszőleges (ha akarja - egy meglehetősen komplex) geometriai alakzat, amely alkalmas lehet a windows, vagy a terminológia a Delphi, ellenőrzéseket. Használati lehet például rajz a vásznon, a környezetben egy adott régióban a frissítés ablak, stb Amellett, hogy ezek a funkciók itt viszonylag ártatlan, technológia pozvolyayaet régiók is, hogy a megcsúfolása a nemes körvonalai bármely leszármazottja TWinControl (más szóval, bármilyen felügyelete Handle, aka TForm, TButton, stb.) Különösen jól régiók használják formák, azok rajz és frissítése. Nos, kezdetnek, lássuk, mi ezt nagyon régióban.

Win32 SDK meghatározza a régió az alábbiak szerint:

A Microsoft Windows, a régió nevezzük négyszög, sokszög vagy ellipszis (vagy két vagy több ilyen adatok), amely lehet tölteni, festett, fordított, keretezett és fel lehet használni, hogy meghatározza a helyét a kurzor

(Vagyis van egy szabványos funkció, amely meghatározza, hogy egy pont része (X, Y) a mi régióban).

Három fő típusa a felsorolt ​​régiókban az SDK: téglalap, ellipszis, sokszög és. Mintegy chotvortom típusú, téglalap alakú, lekerekített élekkel, szégyenletesen csendes, jól és a füge vele. Úgy látszik, ez annak a ténynek köszönhető, hogy lehet beszerezni az első kettő. Az a tény, hogy a régiók kombinálhatók egymással használ logikai operátorokat OR, XOR, stb De ahhoz, hogy ezt még visszatérünk később.

HRGN = típusú LongWord;


Mint látható, semmi rendkívüli. Valójában ez egy mutató a szerkezet a memóriában. Ez a szerkezet a következőképpen jellemezhető:


_RGNDATA = rekord
RDH. TRgnDataHeader;
Buffer. sor # 91; 0 0 # 93; A KAR;
Fenntartva. sor # 91; 0. 2 # 93; A KAR;
végén;


Figyelemre méltó, hogy a Win32 SDK _RGNDATA bejelentett egy kicsit másképp. A legérdekesebb tagja ezt a rekordot, természetesen, TRgnDataHeader. A Windows.pas modul megjelenik, és ez:

_RGNDATAHEADER = csomagolt rekord
dwSize. DWORD;
iType. DWORD;
nCount. DWORD;
nRgnSize. DWORD;
rcBound. TRect;
végén;


Itt érdemes figyelembe venni részletesebben.

Egyesíti régiók P2 és P3, így átfedő területek


Vissza értékek lehetnek NULLREGION (üres régió), SIMPLEREGION (a téglalap), COMPLEXREGION (minden más) és ERROR (nifiga nem jött létre). Lássuk, hogyan néz ki a gyakorlatban (nem sok gyötrelem, én csak befejező az előző példában).

eljárás TForm1. FormCreate # 40; Feladónak. TObject # 41; ;
var
ap. sor # 91; 1. 7 # 93; A TPoint;
av. sor # 91; 1. 2 # 93; Az egész szám;
r. r2. r3. R4. hRGN;
kezdődik
ap # 91; 1 # 93;. = Point # 40; 0 0 # 41; ;
ap # 91; 2 # 93;. = Point # 40; Szélesség. 0 # 41; ;
ap # 91; 3 # 93;. = Point # 40; Szélesség. Magasság div 2 # 41; ;
ap # 91; 4 # 93;. = Point # 40; 0. Magasság div 2 # 41; ;
ap # 91; 5 # 93;. = Point # 40; Szélesség div 2. Magasság div 2 # 41; ;
ap # 91; 6 # 93;. = Point # 40; 0. Magasság # 41; ;
ap # 91; 7 # 93;. = Point # 40; Szélesség. magasság # 41; ;
av # 91; 1 # 93;. = 4;
av # 91; 2 # 93;. = 3;
r. = CreatePolyPolygonRgn # 40; ap. av. 2. WINDING # 41; ;
megpróbál
r2. = CreateRoundRectRgn
# 40; Szélesség div 4 - 20. Magasság div 6-20.
Szélesség div 4 + 20. Magasság div 6 + 20. 16. 16 # 41; ;
r3. = CreateRoundRectRgn
# 40; Szélesség div 4 * 3 - 20. Magasság div 6-20.
Szélesség div 4 * 3 + 20. Magasság div + 20. 6 16. 16 # 41; ;
R4. = CreateEllipticRgn # 40; szélesség
div 10. Magasság div 9 * 3.
Szélesség div 10 * 9. Magasság div 9 * 4 # 41; ;
megpróbál
CombineRgn # 40; r. r. r2. RGN_XOR # 41; ;
CombineRgn # 40; r. r. r3. RGN_XOR # 41; ;
CombineRgn # 40; r. r. R4. RGN_XOR # 41; ;
végül
DeleteObject # 40; r2 # 41; ;
DeleteObject # 40; r3 # 41; ;
DeleteObject # 40; r4 # 41; ;
végén;
SetWindowRgn # 40; Kezelni. r. IGAZ # 41; ;
végül
DeleteObject # 40; r # 41; ;
végén;
végén;


Nerasmotrennoy az első csoport a funkciót csak ExtCreateRgn. Nem fogom kúpos meg, kivéve azt, hogy egy-két olyan funkciója GetRegionData, hasznos lehet, például, hogy mentse és terhelési régiók / fájlból.

Régiók szükségesek nemcsak vágni lyukakat a formák. Néha nagyon hasznos lehet az eszköz saját „natív” minőség, azaz, felhívni a képernyőn meglehetősen bonyolult geometriai formák. Például, térképek megjelenítéséhez, ami a gyűjtemény sokszögű vonalak felépítve tömbök pontok. Hozzon létre egy sor nem leszünk problémája van, itt az ideje, hogy kitaláljuk, hogyan mutassa meg a felhasználó számára.

Levonja az első két funkció van már ismerős: ők is, így FillMode paraméter (alternatív / tekercs) a CreatePolygonRgn és CreatePolyPolygonRgn funkciókat. GetPolyFillMode kap egy kontextust a megadott feltöltési mód és SetPolyFillMode telepíti azt. Csak ebben az időben mi nem beszélünk a régióban, de csak a rajz. A beállított érték lesz értelmes az összes funkció, beépített terület, azaz a PaintRgn és FillRgn, míg maga a térség marad úgy, ahogy jött létre, de lesz festve másképp, ha áll több átfedő régiókban. Az egyszerű régiókban, mint például téglalap vagy ellipszis beállításával ez az érték nem változik semmi.

Szóval Nézzük, hogy sürgősen hozzon létre egy szál, és felhívni. Akkor biztosan ezt ugyanaz a funkciója, mint például a OnCreate, de akkor a kép is nagyon rövid életű - akár az első dolgozza át alakját. Ezért jár másképp: állapítsa magántulajdon fRgn, a OnCreate inicializálja a OnPaint jelenik meg, és a OnDestroy - megsemmisíti. módszer kódot az alábbiakban mutatjuk be:

eljárás TForm1. FormCreate # 40; Feladónak. TObject # 41; ;
kezdődik
fRgn. = CreateEllipticRgn # 40; 10. 10. 200. 200 # 41; ;
végén;

eljárás TForm1. FormDestroy # 40; Feladónak. TObject # 41; ;
kezdődik
DeleteObject # 40; fRgn # 41; ;
végén;

eljárás TForm1. FormPaint # 40; Feladónak. TObject # 41; ;
kezdődik
Vásznon. Brush. Színes. = ClBlack;
PaintRgn # 40; Vásznon. Kezelni. fRgn # 41; ;
végén;


Emlékeztetni kell arra, hogy a funkció a rajz régiók mindig dolgozik, színes,
meghatározott Canvas.Brush.Color. Még rajz egy határ (frame) alkalmazott nem a színe Canvas.Pen, hogy általában, úgy tűnik, hogy logikus és színes Canvas.Brush.

Semmi sem fordult körbe. Temetés típusát. Nézzük, hogy ez több vidám és ugyanakkor meg, hogyan üzemi FrameRgn:

eljárás TForm1. FormPaint # 40; Feladónak. TObject # 41; ;
var
bmp. TBitmap;
kezdődik
bmp. = TBitmap. létrehozása;
megpróbál
bmp. LoadFromFile # 40; 'C: WINDOWS \ Kék csipke 16.bmp' # 41; ;
Vásznon. Brush. Bitmap. = BMP;
PaintRgn # 40; Vásznon. Kezelni. fRgn # 41; ;
Vásznon. Brush. Színes. = ClBlack;
FrameRgn # 40; Vásznon. Kezelni. fRgn. Vásznon. Brush. Kezelni. 2. 2 # 41; ;
végül
Vásznon. Brush. Bitmap. = Nil;
bmp. mentes;
végén;
végén;


Én olyan kép van:

Cikk Együttműködés a régiók

Amennyire én tudom, FillRgn PaintRgn és funkciók különböznek egymástól, csak, hogy az első lehetővé teszi, hogy meghatározza a kefe nyele nem jár a jelenlegi canvas'om. Kérdéses funkció szempontjából Delphi, mint manipulálják az aktuális szín a vásznon könnyebb ecsettel eltérően létre egy külön példány TBrush osztályban. Itt valójában minden a rajz. Érdemes megjegyezni, hogy annak érdekében, hogy felhívja a régió nem kell tudni, hogy mit szeret. Egyszerűen át egy fogantyú ugyanennek az eljárásnak, és ez jelenik meg a képernyőn egy kör, ovális, háromszög, Dávid csillag - semmit.
Az elvégzett feladatok alapján más semmi különösen érdekes önmagában nem jelent, és általában, ez magától értetődő. rassotrim így néhány közülük.

Tesszük ezt egy példa. Nézzük zavarba a képesség, hogy húzza az egeret az egész kör alakban, teremtett az előző példában. Amire szükségünk van. Először is, ne feledje, ahol elkezdted húzás (fStartX, fStartY). Másodszor, a zászló (fDragging), jelezve, hogy a felhasználó valóban peretskivaet régiónkban, nem csak kergeti a szúnyoghálóval. Harmadszor, meg kell, hogy kiderítse mutatott a régió helyett (PtInRegion). Negyedszer, meg kell mozgatni a régióban, ahogy mozog az egér (OffsetRgn). Itt talán minden. Ebben az időben, akkor a modul, így a teljes szöveg. Az egyetlen dolog, érdemes megemlíteni - az ingatlan DoubleBuffered. Van kitéve igaz, hiszen különben nem vibrál. Szóval

felhasználások
Windows-t. Üzenetek. SysUtils. Változatok. Osztályok. Graphics.
Controls. Formákat. dialógusok;

típus
TForm1 = osztály # 40; TForm # 41;
eljárás FormCreate # 40; Feladónak. TObject # 41; ;
eljárás FormDestroy # 40; Feladónak. TObject # 41; ;
eljárás FormPaint # 40; Feladónak. TObject # 41; ;
eljárás FormMouseDown # 40; Feladónak. TObject; Gombot. TMouseButton; Shift.
TShiftState; X. Y. Integer # 41; ;
eljárás FormMouseMove # 40; Feladónak. TObject; Shift.
TShiftState; X. Y. Integer # 41; ;
magán

fDragging. logikai;
fRgn. hRGN;
fStartX.
fStartY. integer;
nyilvános

végén;

var
Form1. TForm1;

eljárás TForm1. FormCreate # 40; Feladónak. TObject # 41; ;
kezdődik
fRgn. = CreateEllipticRgn # 40; 10. 10. 200. 200 # 41; ;
fDragging. = FALSE;
DoubleBuffered. = TRUE;
végén;

eljárás TForm1. FormDestroy # 40; Feladónak. TObject # 41; ;
kezdődik
DeleteObject # 40; fRgn # 41; ;
végén;

eljárás TForm1. FormPaint # 40; Feladónak. TObject # 41; ;
var
bmp. TBitmap;
kezdődik
bmp. = TBitmap. létrehozása;
megpróbál
bmp. LoadFromFile # 40; 'C: WINDOWS \ Kék csipke 16.bmp' # 41; ;
Vásznon. Brush. Bitmap. = BMP;
PaintRgn # 40; Vásznon. Kezelni. fRgn # 41; ;
Vásznon. Brush. Színes. = ClBlack;
FrameRgn # 40; Vásznon. Kezelni. fRgn. Vásznon. Brush. Kezelni. 2. 2 # 41; ;
végül
Vásznon. Brush. Bitmap. = Nil;
bmp. mentes;
végén;
végén;

eljárás TForm1. FormMouseDown # 40; Feladónak. TObject; Gombot.
TMouseButton; Shift. TShiftState; X. Y. Integer # 41; ;
kezdődik
ha # 40; Gomb = mbLeft # 41; és # 40; PtInRegion # 40; fRgn. X. Y # 41; # 41; ezután kezdődik
fDragging. = TRUE;
fStartX. = X;
fStartY. = Y;
végén;
végén;

eljárás TForm1. FormMouseMove # 40; Feladónak. TObject; Shift.
TShiftState; X. Y. Integer # 41; ;
kezdődik
ha # 40; ssLeft a Shift # 41; és fDragging majd kezdődik
OffsetRgn # 40; fRgn. X - fStartX. Y - fStartY # 41; ;
fStartX. = X;
fStartY. = Y;
Frissítés;
végén;
végén;

eljárás TForm1. FormMouseUp # 40; Feladónak. TObject; Gombot. TMouseButton;
Shift. TShiftState; X. Y. Integer # 41; ;
kezdődik
fDragging. = FALSE;
végén;


Mint látható, semmi bonyolult a régiókban nem. De a lehetőségek adnak elég érdekes. Ábra bármilyen alakú lehet színezett, ahogy tetszik (beleértve a képek), hogy megjelenítse, annak meghatározására, hogy egy pont része (X, Y) az ábrán, mozgassa, és még sok más több. Hogy teljes legyen a kép, amit csak meg kell tanulni, hogy a régiók a lemezen, és olvassa el a hátán.

Mentése és betöltése régió

Mint említettük az elején, az összes adatot tárolja a régióban RGNDATA szerkezetét. Utaltak olyan funkció, amely lehetővé teszi, hogy a szerkezet, hogy: GetRegionData. Ez a funkció van egy szép jellegzetessége: ha a harmadik lehetőség az, hogy át nulla, akkor vissza fog térni a szükséges memória mennyiségét, hogy mentse a régióban.

eljárás SaveRegion # 40; Fájlnevet. húr # 41; ;
var
s. TStream;
méretét. bíboros;
adatokat. pointer;
kezdődik
s. = TFileStream. teremt # 40; Fájlnevet. fmCreate # 41; ;
megpróbál
méretét. = GetRegionData # 40; fRgn. sizeof # 40; RGNDATA # 41;. nulla # 41; ;
adatokat. = GlobalAllocPtr # 40; GPTR. méret # 41; ;
megpróbál
GetRegionData # 40; fRgn. méretét. adat # 41; ;
s. ír # 40; adatokat ^. méret # 41; ;
végül
GlobalFreePtr # 40; adat # 41; ;
végén;
végül
s. mentes;
végén;
végén;


Hasonlóképpen, el tudja olvasni, és a lemezen rögzített régióban:

funkció LoadRegion # 40; Fájlnevet. húr # 41;. hRGN;
var
adatokat. PRgnData;
s. TStream;
kezdődik
s. = TFileStream. teremt # 40; Fájlnevet. fmOpenRead # 41; ;
megpróbál
adatokat. = GlobalAllocPtr # 40; GPTR. s. méret # 41; ;
megpróbál
s. olvas # 40; adatokat ^. s. méret # 41; ;
Eredmény. = ExtCreateRegion # 40; nulla. s. Méretét. adatok ^ # 41; ;
végül
GlobalFreePtr # 40; adat # 41; ;
végén;
végül
s. mentes;
végén;
végén;


Itt, ezen talán be tudjuk fejezni ezt a felülvizsgálatot nem állítja, hogy teljes.
Remélhetőleg valaki ezt opus bátorítják az valami jó menet, vagy csak menteni néhány órát mászik Win32 SDK.Vse kérdéseket feltenni a szappan. Erre ICQ: 89576939. de a legjobb az egészben, persze, itt ezen a fórumon.
Sok szerencsét.


Üdvözlettel,
X77.

Kapcsolódó cikkek