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.