30.
Bővítsük a CrtPlus Unitot egy menu
függvénnyel. A függvénynek meg kell oldani a felhasználó által elkészített,
ablakban megjelenő menüpontokból való választást a kurzorvezérlő billentyűk
segítségével. A függvény visszaadott értéke a kiválasztott menüpont sorszáma, ESC-re kilép és a visszaadott érték nulla.
Eddigi programjaink olyanok voltak, hogy egy-egy
részét legfeljebb csak egyszer hajtotta végre futása közben. Az ilyen
felépítést lineárisnak is nevezhetnénk. Ha más feltételekkel (paraméterekkel)
akartuk lefuttatni, akkor újra el kellett indítani a programot és a bevitelt
kellett megváltoztatni. Ha a program újra futtatása nélkül, tetszőleges
sorrendben és számban szeretnénk egy-egy programrészletet használni anélkül,
hogy a teljes programot leállítanánk, ezt legkönnyebben menü segítségével
tudjuk elérni. A többször is végrehajtandó részfeladatokra általában
eljárásokat szoktunk szervezni. A Unit-ba
építhető végleges megoldás előtt, nézzünk néhány megoldási lehetőséget. Az
elsőben még a menü sorszáma alapján választhatunk. A főprogram Repeat ismétlő
eljárásának érdekessége, hogy a leállító feltétele False, azaz állandóan hamis. A
program végét jelentő menüpontban ugyanis az egyszerű megállítás mellett,
(pontosabban előtte) még egyéb tevékenységek is szükségesek lehetnek, pl.
adatok kimentése háttértárolóra vagy a környezeti paraméterek visszaállítása a
program futtatása előtti állapotnak megfelelően.
Program Menu1;
Uses NewDelay, Crt, CrtPlus;
Procedure Elso;
Begin
ClrScr;
Write('Első');
Tunj;
Varj;
End;
Procedure Masodik;
Begin
ClrScr;
Write('Második');
Tunj;
Varj;
End;
Procedure Vege;
Begin
ClrScr;
Write('Vége');
Tunj;
Varj;
Halt;
End;
Function
Menu: Byte;
Var Ch: Char;
Begin
ClrScr;
WriteXY(38,3,'Menü');
VVonal(37,42,4);
WriteXY(36,7,'1. Első');
WriteXY(36,9,'2. Második');
WriteXY(36,11,'3. Vége');
WriteXY(20,14,'A megfelelő szám segítségével választhat!');
Tunj;
Repeat
Ch:= ReadKey;
Until Ch In ['1'..'3',#27];
Menu:= Ord(Ch)-48;
End;
Begin
TextMode(CO80);
Repeat
Case Menu Of
1: Elso;
2: Masodik;
3: Vege;
End;
Until False;
End.
A második megoldásban egy jobbra mutató nyíl
mozgatható a menüpontok előtt, amikor a kívánt menüpont előtt áll,
megnyomhatjuk az ENTER-t, ezáltal a választás
megtörténik. (Az előző programból, Mentés másként (Save
as…) funkcióval készüljön a következő lista, és így
csak javítani kell a megfelelő részeket.)
Program Menu2;
Uses NewDelay, Crt, CrtPlus;
Procedure Elso;
Begin
ClrScr;
Write('Első');
Tunj;
Varj;
End;
Procedure Masodik;
Begin
ClrScr;
Write('Második');
Tunj;
Varj;
End;
Procedure Vege;
Begin
ClrScr;
Write('Vége');
Tunj;
Varj;
Halt;
End;
Function
Menu: Byte;
Var Ch: Char;
X, Y: Byte;
Mp: Byte;
Begin
Szinek(1,4);
ClrScr;
Ablak(7,0,31,6,50,12,True,'Menü');
WriteXY(36,7,'1. Első');
WriteXY(36,9,'2. Második');
WriteXY(36,11,'3. Vége');
WriteXY(13,18,'A le-fel billentyű segítségével választhat + ENTER!');
X:= 34;
Y:= 7;
Mp:= 1;
WriteXY(x,y,Chr(26));
Tunj;
Repeat
Ch:= ReadKey;
If Ch=#13 Then
Begin
Menu:= Mp;
Exit;
End;
If ch=#0 Then
Begin
Ch:= ReadKey;
WriteXY(X,Y,' ');
Case Ch Of
#72: If Y>7
Then
Begin
Dec(Y,2);
Dec(Mp);
End
Else
Begin
Y:= 11;
Mp:= 3;
End;
#80: If Y<11
Then
Begin
Inc(Y,2);
Inc(Mp);
End
Else
Begin
Y:= 7;
Mp:= 1;
End;
End;
WriteXY(x,y,Chr(26));
Tunj;
End;
Until False;
End;
Begin
TextMode(CO80);
Repeat
Case Menu of
1: elso;
2: masodik;
3: vege;
End;
Until False;
End.
A harmadik megoldás már megjelenésében a
véglegest tükrözi. A menüpontok között a kurzorvezérlőkkel választhatunk, az
aktuális menüpont inverz kiírással jelenik meg. Új nyelvi elem a konstans tömb
megadásának módja, mely tömb itt a menüpontok neveit tartalmazza.
Program Menu3;
Uses NewDelay, Crt, CrtPlus;
Const
Msor: Array[1..3]
Of String[9]=
(' Első ',
' Második ',
' Vége ');
Procedure Elso;
Begin
ClrScr;
Write('Első');
Tunj;
Varj;
End;
Procedure Masodik;
Begin
ClrScr;
Write('Második');
Tunj;
Varj;
End;
Procedure Vege;
Begin
ClrScr;
Write('Vége');
Tunj;
Varj;
Halt;
End;
Function
Menu:Byte;
Var Ch: Char;
I,X,Y: Byte;
Mp:Byte;
Begin
Szinek(1,4);
ClrScr;
Ablak(7,0, 33,6,48,12,
True,'Menü');
Szinek(7,0);
For I:= 1 To 3 Do
WriteXY(36,5+2*i,msor[i]);
WriteXY(13,18,'A le-fel billentyű segítségével választhat + ENTER!');
X:= 34;
Y:= 7;
Mp:= 1;
Szinek(0,15);
WriteXY(36,5+2*mp,msor[mp]);
Tunj;
Repeat
Ch:= ReadKey;
If Ch=#13 Then
Begin
Menu:= Mp;
Exit;
End;
If Ch=#0 Then
Begin
Ch:= ReadKey;
Szinek(7,0);
WriteXY(36,5+2*mp,msor[mp]);
Case Ch Of
#72: If Y>7
Then
Begin
Dec(Y,2);
Dec(Mp);
End
Else
Begin
Y:= 11;
Mp:= 3;
End;
#80: If Y<11
Then
Begin
Inc(Y,2);
Inc(Mp);
End
Else
Begin
Y:= 7;
Mp:= 1;
End;
End;
Szinek(0,15);
WriteXY(36,5+2*mp,msor[mp]);
Tunj;
End;
Until False;
End;
Begin
TextMode(CO80);
Repeat
Case Menu Of
1: Elso;
2: Masodik;
3: Vege;
End;
Until False;
End.
Nézzük ezek után a végleges megoldást a CrtPlus Unit-ban. Illesszük be
utolsó függvényként. Paraméterei: háttérszín, karakterszín, kiválasztó
háttérszín, bal felső csúcs X és Y koordinátája, menüsorok hossza, menüsorok
száma, aktuális menüpont sorszáma.
Unit CrtPlus;
Interface
Uses NewDelay, Crt;
. . .
Function menu(HSz,KSz,SZz,Bfx,Bfy,Sh,Ss,As:Byte):
Byte;
Implementation
. . .
Function
menu(HSz,KSz,VSz,Bfx,Bfy,Sh,Ss,As:Byte): Byte;
Var Ch: Char;
Begin
Szinez(Vsz,KSz,Bfx,Bfy+As-1,Sh);
repeat
Ch:= ReadKey;
If Ch=#0 Then
Begin
Ch:= ReadKey;
If Ch In [#71,#72,#75,#77,#79,#80] Then
Szinez(HSz,Ksz,Bfx,Bfy+As-1,Sh);
Case Ch Of
#71: As:=1;
#72,#75: If As>1
Then Dec(As) Else As:=
Ss;
#77,#80: If As<Ss
Then Inc(As) Else
As:= 1;
#79: As:=
Ss;
end;
If Ch In [#71,#72,#75,#77,#79,#80] Then
Szinez(VSz,KSz,Bfx,Bfy+As-1,Sh);
End;
Until Ch In [#13,#27];
If Ch=#13 Then Menu:= As
Else Menu:= 0;
End;
End.
A következő kis program a most megírt menu függvényt teszteli. Fontos elemezni, az ablak és a menu paramétereinek illesztését.
Program MenuPro;
Uses NewDelay, Crt, CrtPlus;
Const
Msor: Array[1..3]
Of String[9]=
(' Első ',
' Második ',
' Vége ');
Var Mp: Byte;
I: Byte;
Begin
TextMode(CO80);
Szinek(1,15);
ClrScr;
Ablak(7,0,33,4,45,8,True,'Menü');
For I:= 1 To 3 Do
WriteXY(35,4+I,Msor[I]);
Tunj;
Mp:= Menu(7,0,green,35,5,9,3,1);
WriteXY(1,24,Msor[Mp]);
Varj;
End.