Windows alkalmazások készítése A Windows rendszerben a felhasználó hozzászokott a menü, az eszköztár és a többalakos programok használatához. Első példánkban egy egyszerű képnéző programot készítünk, melyben megismerkedünk a menü, az eszköztár és a saját párbeszédpanel készítésével Menü készítése Programunk szolgáltatásai A menürendszeren át egy program valamennyi szolgáltatása elérhető. Esetünkben a program három menüt tartalmaz. A Fájl menü a kép megnyitására, mentésére és a program bezárására szolgál. A Szerkesztés menü segítségével a képet tükrözhetjük vízszintesen vagy függőlegesen, illetve adott szöggel elforgathatjuk. Végül a Kép menü egyetlen pontjával kiválaszthatjuk, hogy a kép betöltse-e a rendelkezésére álló területet.
A Szerkesztés menü A menüpontok kiválasztását sokféle szolgáltatás is támogatja. Ilyen a gyorsbillentyű vagy hot key (ábrákon a Ctrl+Shift+F), vagy az aláhúzott betű. Ez utóbbi az Alt gomb lenyomása után jelenik meg, és az adott menüt vagy menüpontot az aláhúzott betű lenyomásával választhatjuk ki. Programunk készítéséhez hozzunk létre egy új Windows alkalmazást! A programablakot nevezzük el frmPic-nek (erre a későbbiekben szükségünk lesz), majd írjuk be a címsorába a Képnéző szöveget. Menü készítése A Visual Basic alapvetően kétféle menü készítését támogatja: az ablak tetején lévő legördülő menüt (MenuStrip), és a jobb egérgomb hatására felbukkanó környezetérzékeny menüt (ContextMenuStrip). Ismerkedjük meg a legördülő menü (vagy egyszerűen menü) készítésével! A menü elhelyezéséhez válasszuk az eszközkészlet Menü vezérlőjét, és kattintsunk a tervezés alatt álló űrlapunkra. Mivel a menüt az űrlapon a rendszer helyezi el, ezért ikonja a képernyő
aljára kerül, miközben az űrlapon megjelenik a főmenü leendő helyén a Type Here felirat. Elvileg az űrlapra több főmenüt is elhelyezhetnénk, erre azonban ritkán van szükség, így ezúttal a főmenü jelenlegi nevét (MenuStrip1) nem is módosítjuk. Az egyes menüpontok tulajdonságait azonban már tervezés közben érdemes beállítani, ezért „szögezzük ki” a tulajdonság ablakot. Írjuk a Type Here mezőbe a &Fájl szöveget! Az & jel arra utal, hogy a mögötte lévő betű lesz aláhúzva. (Azonos betűvel kezdődő menüpontok esetén a programozó kénytelen egy belső betűt választani. A Word 2003-ban pl. a Formátum menü az Alt+T kombinációval érhető el: Formá&tum.) A menüpontnak feltétlenül olyan nevet adjuk, amely alapján a programkódból könnyen be tudjuk azonosítani: pl. mnuFájl. Ha készen vagyunk, lépjük az alatta lévő Type Here mezőre, és írjuk be a Meg&nyitás szöveget, a menüpont neve pedig legyen célszerűen az elérési útja: mnuFájlMegnyitás. A hosszú nevek ne zavarjanak, hiszen nem beírni kell őket a programkódba, hanem kiválasztani. A menüponthoz gyorsbillentyűt is rendelhetünk, ez a menüpont felirata után jelenik meg. A gyorsbillentyű a ShortcutKeys listából választhatjuk ki. Célszerű a felhasználó által megszokott lehetőséget, ezúttal a Ctrl+O kombinációt használni. A gyorsbillentyű megjelenítését a ShowShortcut tulajdonság False-ra állításával tilthatjuk le. &Fálj
mnuFájl Meg&nyitás
mnuFájlMegnyitás
Menté&s
mnuFájlMentés
Be&zárás
mnuFájlBezárás mnuSzerkesztés
&Szerkesztés &Vízszintes tükrözés
mnuSzerkesztésVízszintes
&Függőleges tükrözés
mnuSzerkesztésFüggőleges
&Elforgatás
mnuSzerkesztésElforgatás mnuKép
&Kép &Nyújtás
mnuKépNyújtás
Az ábrán programunk menüszerkezetét látjuk. Hozzuk létre őket önállóan! Menüelválasztó A menük kezelésénél gyakran van szükségünk menüelválasztóra. Ez egy vízszintes vonal, amely lehetővé teszi a menüpontok csoportosítását. A menüelválasztó tulajdonképpen egy
önálló menüpont, melynek Text tulajdonsága egy kötőjel, vagyis ezt kell a Type Here-hez beírni. A menüelválasztót is – bár kódot ritkán rendelnek hozzá – érdemes elnevezni, hogy a későbbiek során könnyen be lehessen azonosítani a menürendszerben. Sokszor egy X-szel jelölik: mnuFájlX. Menüpont jelölése A menüpont neve szürke sáv ténylegesen egy jelölőnégyzetet tartalmaz. Ezt a jelölőnégyzetnél megismert tulajdonságokkal állíthatjuk be, attól eltérően azonban értéke nem változik rákattintásra! Példánkban a képet egy képdobozban fogjuk megjeleníteni. Mint az Egyszerű Windows alkalmazások készítése c. fejezetben láttuk, ilyenkor a kép elhelyezésére több lehetőségünk is van. Esetünkben a Kép menü Nyújtás menüpontja fogja beállítani azt, hogy a kép 1:1 méretben jelenjen-e meg, vagy felvegye a képdoboz méretét. Első esetben lehet, hogy a kép nem tölti ki a dobozt, második esetben pedig torzulhat. Azt, hogy a kép nyújtva jelenik meg, vagyis kitölti a képdobozt, a Nyújtás menüpont előtti jelölőnégyzet fogja jelezni. A menüpont Checked tulajdonságának kezdeti állapotát a tulajdonság ablakban állíthatjuk be, ám később, amikor a felhasználó rákattint, már programkódból kell módosítanunk a menüpontot. A többi vezérlőhöz hasonlóan, kattintsunk kettőt a menüpontra, hogy megjelenjen az mnuKépNyújtás_Click eseménykezelő eljárás, ahol a menüpont Checked tulajdonságát egy elágazással módosíthatjuk: Private Sub mnuKépNyújtás_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuKépNyújtás.Click If mnuKépNyújtás.Checked = False Then mnuKépNyújtás.Checked = True Else mnuKépNyújtás.Checked = False End If End Sub
A menüpontok fontosabb tulajdonságai Tulajdonság Checked CheckSate
Leírás A menüpont előtti jelölőnégyzet állapota.
DisplayStyle
A menüpont megjelenését adja meg: csak szöveg/ csak kép/ mindkettő A kép és a szöveg egymáshoz viszonyított helyzete. A menüponthoz tartozó kép megadása.
TextImageRelation Image
Text ImageScaling TextDirection
A menüponthoz tartozó szöveg megadása. A kép átméretezve vagy teljes méretben jelenjen-e meg. A szöveg vízszintesen vagy függőlegesen jelenjen-e meg.
A menüponthoz tartozó gyorsbillentyű kiválasztása. ShortcutKeys Megjelenjen-e a gyorsbillentyű a menüpont mellett. ShowShortcutKeys ShortcutKeysDiplayString A gyorsbillentyű helyére ez a szöveg kerül. ToolTip AutoToolTip
Megadja a gyorstipp szövegét, ha a menüpontra mutatunk az egérrel. Ha értéke igaz, akkor a menüponthoz tartozó gyorstipp a menüpont felirata lesz.
Az eszköztár és a képdoboz beillesztése Az eszköztár segítségével a menürendszer menüpontjai gyorsabban érhetőek el. Ennek megfelelően úgy működik, hogy az elemeihez tartozó kód lényegében csak meghívja a megfelelő menüpontot. Ahhoz, hogy a képernyőt később kényelmesen tudjuk felosztani, már most helyezzünk el a szokásos módon egy Eszköztár (ToopStrip) vezérlőt. Az eszköztár automatikusan az űrlap tetején, a „rendes” helyén jelenik meg. Az eszköztár alatti területet teljes egészében a képre szánjuk, melyet egy képdobozban fogunk megjeleníteni. Szúrjunk be tehát erre a területre egy képdobozt, és nevezzük át pb1-re, hogy később könnyebben beírhassuk a nevét. Szeretnénk, ha a képdoboz teljes egészében betöltené az űrlap eszköztár alatti részét, és ez akkor is így maradna, amikor a felhasználó az űrlapot átméretezi. Ezt a Dock tulajdonság Fill beállításával tehetjük meg. A Dock tulajdonsággal ugyanis egy vezérlő hozzáragasztható az űrlap valamelyik oldalához, vagy kitölthető vele az űrlap szabadon lévő része.
A fájl menü menüpontjai A kép megnyitásához és mentéséhez a korábban már megismert OpenFileDialog és a SaveFileDialog vezérlőket használhatjuk. Vegyünk fel például az űrlapra egy OpenFileDialog vezérlőt ofd néven, és kattintsunk kettőt a Megnyitás menüpontra. Eddigi ismereteink alapján a menüponthoz a következő kódot rendelhetjük:
Private Sub mnuFájlMegnyitás_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuFájlMegnyitás.Click Try If ofd.ShowDialog = Windows.Forms.DialogResult.OK Then pb1.Image = Image.FromFile(ofd.FileName) End If Catch ex As Exception MsgBox("A fájl megnyitása nem sikerültű") End Try End Sub
A Mentés menüpontot hasonlóan készíthetjük el egy SaveFileDialog segítségével. Fájlműveletek közben könnyen generálhatnak kivételek, ezért mindig érdemes Try szerkezettel védeni a program futását. Feladatok: 1) Állítsuk be az OpenFileDialog egyes tulajdonságait (pl. Filter) úgy, hogy megjelenése felhasználóbarát legyen! 2) Mentés Készítsük el a mentés menüpontot! A menüpont tegye lehetővé a kép mentését más néven SaveFileDialog felhasználásával! Segítség: a pb1 képdobozban lévő képet pb1.Image.Save(„C:\csumi.jpg)” utasítással menthetjük a C:\csumi.jpg nevű fájlba.) Műveletek a képpel. Saját párbeszédpanel készítése A kép nyújtása A Kép menü segítségével a képdoboz érhető el. Ebben a menüben egyetlen pontot helyeztünk el, a Nyújtást. Ha a Nyújtás menüpontot bekapcsoljuk, akkor a kép teljesen kitölti a képdobozt. Fontos, hogy a kép ténylegesen nem változik, ez a beállítás csupán a megjelenítésre, azaz a képdobozra vonatkozik. Ebben a menüpontban pillanatnyilag egy elágazás van. Mint egy korábbi példában láttuk, a képdoboz SizeMode tulajdonsága határozza meg a kép méretezését. Alapértelmezés szerint a képdoboz bal felső sarkában van a kép bal felső sarka (Normal), míg a nyújtás a StretchImage érték hatására következik be. Ez a beállítás a kód beírása közben listából választható ki: Private Sub mnuKépNyújtás_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuKépNyújtás.Click If mnuKépNyújtás.Checked = False Then mnuKépNyújtás.Checked = True pb1.SizeMode = PictureBoxSizeMode.StretchImage
Else mnuKépNyújtás.Checked = False pb1.SizeMode = PictureBoxSizeMode.Normal End If End Sub
A kép tükrözése A pb1 képdobozban lévő képet a pb1.Image objektum azonosítja, így a pb1.Image metódusaival módosíthatjuk. Például a képet a RotateFlip metódussal tükrözhetjük vagy forgathatjuk; a kívánt lehetőséget egyszerűen ki kell választanunk egy listából. Ennek megfelelően a Szerkesztés menü első két menüpontja a következő: Private Sub mnuSzerkesztésVízszintes_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuSzerkesztésVízszintes.Click pb1.Image.RotateFlip(RotateFlipType.RotateNoneFlipX) pb1.Refresh() End Sub Private Sub mnuSzerkesztésFüggőleges_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuSzerkesztésFüggőleges.Click pb1.Image.RotateFlip(RotateFlipType.RotateNoneFlipY) pb1.Refresh() End Sub
A metódus képet (a memóriában) transzformálja ugyan, ám a képdobozt nem változtatja meg. A kép módosulását a képdoboz csak akkor követi, ha valami miatt frissíteni kell a képernyőt, pl. a felhasználó átméretezi az ablakot. Ha nem akarjuk megvárni, amíg a rendszer magától frissít, akkor a frissítést nekünk kell kezdeményeznünk a képdoboz Refresh metódusával. Új űrlap készítése a forgatáshoz Felhasználóbarát megoldás, ha az elforgatás szögét a felhasználó egy dialógusdobozban egy numerikus léptetővel viheti be, és közben egy előnézeti ábrán nyomon követheti az eredményt is. Programozási szempontból új problémát a két űrlap közötti adatkapcsolat fog jelenteni.
Az új űrlap hozzáadásához kattintsunk a Project menü Add Windows Form menüpontjára, és itt válasszuk a Windows Form lehetőséget. Az Open gombra kattintás után egy új abblakot kapunk, Form2 néven. Legyen az ablak új neve frmRot, majd állítsuk be a következő tulajdonságokat, hogy a megjelenő ablak a Windowsban megszokott párbeszédpanelnek megfelelően jelenjen meg. FormBorderStyle = FixedDialog (a párbeszédablak kerete) ControlBox = False (nem lesznek ablakikonok) ShowInTaskbar = False (nem jelenik meg a tálcán) Helyezzük el rajta a vezérlőket az ábra szerint. Új elem a numerikus léptető, melyet az eszközkészlet NumericUpDown ikonjával illeszthetünk be. A léptető Minimális és Maximális értékét a Minimum és a Maximum, lépésközét pedig a Increment tulajdonság adja meg. nup NumericUpDown Maximum =360 Increment = 90 pb2 PictureBox BorderStyle = Fixed3D SizeMode = StretchImage OK Button DialogResult = OK
Mégse Button DialogResult = Cancel
A párbeszédpanelből a felhasználó kétféle módon léphet ki: az OK gombbal elfogadja a módosításokat, a Mégse gombbal nem. Hogy melyiket választotta, az a meghívó frmPic főűrlapról a párbeszédpanel DialogResult tulajdonságaként fog látszani. Állítsuk ehhez a Mégse gomb DialogResult tulajdonságát Cancelre! Ez azt jelenti, hogy ha a felhasználó rákattint, akkor a párbeszédpanel DialogResult tulajdonsága automatikusan Cancelre áll, és az ablak becsukódik. Az Ok gomb esetében értelemszerűen a DialogResult tulajdonságot OK-ra kell állítani. A párbeszédpanel meghívása A képcserét a két űrlap között a következőképpen oldjuk meg. A párbeszédpanel meghívásakor programunk egyszerűen átmásolja a képet az frmRot képdobozába, ahol a felhasználó azt elforgatja. Ha a panelből való kilépéskor az OK gombra kattint a felhasználó, akkor visszamásoljuk az elforgatott képet a pb1 képdobozba. Private Sub mnuSzerkesztésElforgatás_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuSzerkesztésElforgatás.Click frmRot.pb2.Image = pb1.Image If frmRot.ShowDialog() = Windows.Forms.DialogResult.OK Then pb1.Image = frmRot.pb2.Image End If End Sub
A kép forgatása A kép forgatását a tükrözéshez hasonlóan, a RotateFlip metódussal végezhetjük. Ez azt jelenti, hogy első megközelítésben a numerikus léptetőhöz a következő kódot rendeljük: Public Class frmRot Private Sub nup_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles nup.ValueChanged If nup.Value = 90 Then pb2.Image.RotateFlip(RotateFlipType.Rotate90FlipNone End If If nup.Value = 180 Then pb2.Image.RotateFlip(RotateFlipType.Rotate180FlipNone End If If nup.Value = 270 Then pb2.Image.RotateFlip(RotateFlipType.Rotate270FlipNone End If pb2.Refresh() End Sub End Class
Ha a programot kipróbáljuk, meglepő dolgot tapasztalunk. Amikor a képtető értékét 90 fokról 180 fokra növeljük, a kép a 90 fokos elforgatáshoz képest fordul el 180 fokot, így az eredetihez képest nem 180, hanem 270 fokkal fordul el. Ezt természetes is, hiszen a RotateFlip mindig az aktuális képet fordítja el. A problémát egyszerűen megoldhatjuk, ha az eredeti képről készítünk egy másolatot pl. pic néven, és ezt minden alkalommal visszatöltjük elfogatás előtt a pb2.Image képdobozba:
Public Class frmRot Dim pic As Image Private Sub frmRot_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load pic = pb2.Image.Clone End Sub Private Sub nup_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles nup.ValueChanged pb2.Image = pic.Clone
…’ Ettől kezdve a kód változatlan A Clone metódus a kép másolatát adja át az értékadás bal oldalán álló objektumnak. Ennek hiányában a másik objektum csak a kép egy új neve volna, ahogy ezt az objektumorientált programozással foglalkozó fejezetben láttuk Objektum láthatósága Objektumorientált programozási ismereteink alapján furcsának tűnhet, hogy a programunk főűrlapjáról minden további nélkül elérjük a párbeszédpanel képdobozát. Ez a párbeszédpanel ugyanis másik osztályhoz tarozik. Természetesen az osztály készítése során a programozó megadhatja, hogy az osztály tagjai (mező, tulajdonság, metódus) „kívülről” elérhetők-e, vagyis mi a láthatóságuk. Az osztályok esetében a származtatás miatt azonban több lehetőség van, mint amit a változóknál megismertünk. A Public kulcsszó ebben az esetben is globális láthatóságot jelent. Ha a Protected kulcsszót használjuk, akkor az adott tag csak a saját és az abból származtatott osztályokból érhető el. A Friend azt jelenti, hogy a tag abból a programból érhető el, ahol a deklarálva van, amelyet tovább finomíthatunk a Protected Friend együttes használatával. Végül a Private kulcsszó használata esetén a tag csak saját osztályából érhető el, ebben az esetben tehát a megosztásnak nincs sok szerepe. Egy űrlapra helyezett objektum (esetünkben képdoboz) láthatóságát a tulajdonság lap Modifiers pontjának módosításával adhatjuk meg. Visual Basicben az alapértelmezett beállítás a Friend. Programunkban egy másik érdekes dolog, hogy a kép forgatását végző panelt nem példányosítottunk, hanem a programkódban magát az frmRot osztályt használtuk. Ez a Visual Basic egy sajátossága: ha az osztálynak csupán egy példányát használjuk, akkor azt nem kell példányosítani.