Előző számunkban ott tartottunk a gyakorlati részben, hogy nesze neked semmi fogd meg jól, mert kicsit tényleg gyakorlatiasra sikerült a StatusBar és Menu leírása. Most kicsit jobban részletezem, hisz nem árt ha tisztában vagyunk az alap fogalmakkal s használatukkal. Aki úgy érzi, hogy teljesen tisztában van e dolgokkal, az is átfuthatja hátha van valami hasznos elméleti dolog még számára is !

A Turbo Vision felületű programok a képernyőt - általában - három részre osztják: a desktop-ra, a menubar-ra és a status line-ra. A desktop-ról már volt szó sőt saját, új desktop-ot is készítettünk. Amikor initializáljuk az applikációt a constructor TApplication.Init metódussal, akkor annak elődje a TProgram.Init három másik virtuális metódust az InitDesktop, InitMenuBar és InitStatusLine hív meg. Ennek képletes leírását az alábbi ábrán láthatjuk:

Ezek a metódusok (InitDesktop, InitMenuBar és InitStatusLine) állítják be a megfelelő képernyőelemeket. Mivel mindhármuk virtuális metódus ezért az applikáció megváltoztatása nélkül (tehát nem kell se a TApplication.Init-jét se semmi mást macerálnunk) közvetlenül állíthatjuk be őket úgy, hogy tökéletesen müxenek. (s visszahatnak elődjeikre hisz virtuálisak)

Először nézzük a StatusLine-t:
Az előzőek szerint az applikáció objektumának az
InitStatusLine virtuális metódusa initializálja a StatusLine-t úgy, hogy létrehozza azt, és egyenlővé teszi az APP.PAS Unit globális változójával a StatusLine: PStatusLine;-nal. Tehát az APP Unit-ban, ami a TApplication objektum típust - is - tartalmazza az INTERFACE részben deklarálták a StatusLine változót.

 

Unit APP;

 

INTERFACE

   
 

{... Objektumok definiálása, stb.}

   
 

const

 

Application: PProgram = nil;

 

Desktop: Pdesktop = nil;

 

StatusLine: PstatusLine = nil;

 

MenuBar: PMenuView = nil;

   
 

{... Egyéb dolgok}

   
 

IMPLEMENTATION

   
 

{... Az objektumok kódja}

   
 

BEGIN

 

{...}

 

END.

A StatusLine változó típusa PStatusLine (TStatusLine) objektum ami a Menu.PAS Unit-ban található. Ez az objektum típus a TView-ból származik, és a képernyő alján lesz látható 1 sor vastagságban. Tehát ennek a változónak fogunk értéket adni az InitStatusLine metódussal, az alábbiak alapján:

 

program Proba;

 

type

 

TMyApp = Object(TApplication)

 

procedure InitStatusLine; virtual;

 

{ ... egyéb új metódusok}

 

end;

   
 

var MyApp: TMyApp;

 

BEGIN

 

MyApp.Init;

 

MyApp.Run;

 

MyApp.Done;

 

END.

Programunkban új objektum típust származtatunk, és itt szúrjuk be az InitStatusLine procedure-át. A InitStatusLine procedure kódját pedig az alábbiakban szúrjuk be, és megkezdjük a StatusLine elhelyezését:

 

program Proba;

 

type

 

TMyApp = Object(Tapplication)

 

procedure InitStatusLine; virtual;

 

{ ... egyéb új metódusok}

 

end;

   
 

procedure TMyApp.InitStatusLine;

 

var R: TRect;

 

begin

 

GetExtent(R);

 

R.A.Y := R.B.Y - 1;

 

{...}

 

end;

   
 

var MyApp: TMyApp;

 

BEGIN

 

MyApp.Init;

 

MyApp.Run;

 

MyApp.Done;

 

END.

Amint láthatjuk a procedure-ában lekérdezzük az applikáció méretét a GetExtent() rutinnal, s az eredmény a TRect típusú R változóba kerül. Az R változó tartalma nagy valószínűség szerint:

R.A.X = 0; R.A.Y = 0; R.B.X = 80; R.B.Y = 25; [R = ( (0,0) , (80,25) )]

Ezután az R.A.Y mezőt (ami eddig 0 volt) egyenlővé tesszük az R.B.Y - 1 -gyel és ez = 24. Így az R változó értéke ( (0, 24) , (80, 25) ). Ez egy olyan téglalapot ír le ami a teljes utolsó sort befedi.
Van egy fontos dolog amit el kellene mondani, ez a help context. Minden view-nak van egy Word
mezője (a TView objektum típustól kezdődően) a help context mező, a változó azonosítója: HelpCtx. Ez a változó a view-oknál úgy általában arra szolgál, hogy saját Help készítésekor a Help objektum a HelpContext számok alapján tudja, hogy mely help részletet kell megjeleníteni. A StatusLine-nál van még egy másik szerepe is, még pedig: A StatusLine nem csak a forrókulcsok (ALT-X, F3 , stb.) megjelenítésére szolgál, hanem üzenetek is megjelennek itt alul a képernyőn. Az üzenetek lehetnek hibaüzenetek, vagy pl.: a menüben a könnyebb eligazodást szolgáló menüpont leírások. (akár csak: a Borland Pascal editor-ában, vagy a Windows-os programoknál.)
A StatusLine objektum lácolt pointer-es rekordból áll, s ezt státusz definíciónak nevezzük. A státusz definíció tartalmazza azt a HelpContext tartományt amihez a adott StatusLine tartozik. (Ez így először kicsit hülyén hangzik de később "k
ihomályosul" !) Továbbá a státusz definíció tartalmazza a StatusKey-ket. (» státusz mezőt). Státusz definíciót a NewStatusDef függvénnyel hozhatunk létre. Lássuk:

 

New(StatusLine, Init(R,

{a méret megadása, R: TRect}

 

NewStatusDef(0, $FFFF,

{a HelpContext tartomány}

 

StdStatusKeys(nil),

{standard státusz mezők}

 

nil));

{nincs egyéb HelpContext tartomány}

A méret megadása egyértelmű, lásd feljebb, de a HelpContext tartomány még homályos lehet, újabb példával tán világosabb lesz:

 

procedure TMyApp.InitStatusLine;

 

var R: TRect;

 

begin

 

GetExtent(R); {az applikáció méretének lekérdezése}

 

R.A.Y := R.B.Y - 1; {a StatusLine a képernyő alsó sorába kerül}

 

New(StatusLine, Init(R, {Létrehozzuk a StatusLine-t, ezt a változót az APP Unitban deklarálták, majd megadjuk a méretet - R}

 

NewStatusDef(0, $EFFF, {első HelpContext tartomány}

 

NewStatusKey~F3~ Open', kbF3, cmOpen, {file megnyitása}

 

NewStatusKey~F4~ New', kbF4, cmNew, {ablak megnyitása}

 

NewStatusKey~ALT+F3~ Close', kbAltF3, cmClose, {ablak bezár}

 

StdStatusKeys(nil)))), {standard státusz mezők - APP Unit}

 

NewStatusDef($F000, $FFFF, {második HelpContext tartomány}

 

NewStatusKey~F6~ Next', kbF6, cmOrderNext, {Következő ablak}

 

NewStatusKey~Shift+F6~ Prev', kbShiftF4, cmOrderPrev, {előző}

 

StdStatusKeys(nil))), {standard státusz mezők - APP Unit}

 

nil)), {nincs több HelpContext tartomány}

 

)); {a New és az Init zárójeleit zárjuk be.}

 

end;

Na ez egy teljes StatusLine definíció, magyarázkodjunk:

  • Az APP Unit-ban már deklarálták a StatusLine változót most ennek adunk értéket a New() függvénnyel
  • A méret megadása egyértelmű, fent már elmagyaráztatott
  • Továbbá azt is tudjuk, hogy a NewStatusDef() függvénnyel lehet StatusLine-t, ill. a HelpContext-től függő tartományokra beosztott StatusLine-t készíteni.
    DE mire is jó ez a sokszor emlegetett HelpContext-es tartomány ?
    A StatusLine definíciót tartományokra oszthatjuk. A különböző tartományok különböző státusz mezőket, forrókulcsokat tartalmaznak annak függvényében, hogy mire van szükség ha különböző használatú, célú ablakokat nyitunk meg, vagy a menü különböző részeiben járunk. Mivel említettem, hogy minden view-nak van HelpContext-je ezért könnyedén meg lehet azt csinálni, hogy ha megnyitunk pl.: egy szövegszerkesztő ablakot akkor a státuszsorban megjelenjen a SAVE, az UNDO, stb. parancsok forrókulcsai. Viszont ha más típusú ablakot nyitunk meg (pl.: személyi adatokat kérünk be) akkor más forrókulcsok jelenjenek meg a státuszsorban. (pl.: új név beké
    se, stb.)
    Ennek megvalósítása felettébb egyszerű: azoknak az ablak típusoknak melyek szövegszerkesztést látnak el
    $1000-s HelpContext-et adunk mégpedig így: SzerkesztőAblak.HelpCtx:=$1000; Az adatbekérő dialógusoknak pedig így: AdatDialógus.HelpCtx:=$1800; Most már megvannak a különböző HelpContext bejegyzések, a dolgunk ennek megfelelően alakítani a StatusLine-t. Pl.:
 

New(StatusLine, Init(R,

 

NewStatusDef(0, $0FFF, {általános HelpContext tartomány}

 

StdStatusKeys(nil)))), {standard státusz mezők}

 

NewStatusDef($1000, $14FF, {Szövegszerkesztő ablak Context tartomány)

 

NewStatusKey~F2~ Save', kbF2, cmSave,

 

NewStatusKey~F3~ Open', kbF3, cmOpen, nil))),

 

NewStatusDef($1500, $2000, {Adat bekérő dialógus Context tartomány}

 

NewStatusKey~F5~ Új név', kbF5, cmNewName, nil)),

 

NewStatusDef($2000, $FFFF, {beépített TV tartomány ablakoknak}

 

NewStatusKey~ALT+F3~ Close', kbAltF3, cmClose,

 

StdStatusKeys(nil)))), {standard státusz mezők}

 

nil)))),

 

));

  • Most már láthatjuk - s talán értjük is - hogyan osztottuk fel tartományokra a státuszdefiníciót. Azért osztottuk tartományokra, mert pl.: van öt féle szövegszerkesztő ablak aminek a HelpContext-je $1000, ..., $1004. Mindegyikhez külön számot rendelünk mert pl. az egyik ablakban csak megjegyzéseket írunk, a másikban szövegfile-okat, ... és ha help-et írunk mindegyikhez külön help tartozik ami majd elmondja, hogy ez erre és erre jó, DE a szövegszerkesztő ablakok kezelése közös mindegyikben el lehet menteni a szöveget (F2 Save), ... így mindegyikre használható ugyanaz a StatusLine. Így a hasonló működésű view-oknak egy tartományban adunk HelpContext-et, ezt használjuk a státuszdefiníció során, s a StausLine is megegyezik.
  • Pár egyéb apróság: function NewStatusDef(AMin, AMax: Word; AItems: PStatusItem; ANext: PStatusDef): PStatusDef; Na ezt a függvényt hívtuk meg, megadtuk a tartomány minimumát, maximumát, a tartomány elemeit (LÁSD egy sorral alább !), és a következő tartományt.
  • A tartomány elemeit ugyanúgy egymásba láncolt pointer-es listaként adhatjuk meg. Új státusz elemet a NewStatusKey()-vel szúrhatunk be, e függvény paraméterei: function NewStatusKey(AText: String; AKeyCode: Word; ACommand: Word; ANext: PStatusItem): PStatusItem;
    Az AText
    az a szöveg ami a státuszsorban megjelenik. FONTOS: léteznek az úgynevezett tilde jelek: ~ az a szöveg amit két tilde jel közé zárunk az kiemelt színű lesz, így látszik, hogy az a forrókulcs. Pl.: AText:='~ALT-F3~ Bezár'; Itt az ALT-F3 lesz kiemelt színű, színesben piros.
    Az
    AKeyCod a szöveghez tarozó forrókulcs. A Turbo Vision DRIVERS Unit-ja előre deklarálta az összes lehetséges billentyűkódot, így csak konstans változónevekkel kell rá hivatkozni. A billentyű konstansok kbXXX formában vannak Ha az ALT és az A betűhöz tartozó konstansra van szükségünk akkor simán leírjuk: kbALTA. Ha az F3 gombéra akkor kbF3, de akár lehet is ALT + F3 = kbAltF3, stb.
    Az
    ACommend egy parancs Word, ha a státuszsorban meghívjuk ezt az adott mezőt (pl.: a forrókulccsal, vagy egérrel klikkantunk a státuszsor megfelelő részére) akkor a Turbo Vision eseménykezelő részeinek ezt a Word-öt adják át, hogy ez az esemény történt, és majd valahol ez az esemény feldolgozódik és pl. kinyílik egy ablak. DE az ESEMÉNYkezelés megérdemel egy teljes óriási cikket, s így is csak nagy vonalakban lehet elmagyarázni.
    Az ANext
    pedig csak egyszerűen a következő hasonló státuszmezőre mutat, ettől lesz láncolt listánk. (Így ezek az egymásba láncolt státuszmezők az elemei a státuszdefiníció ezen részének.)
    Lássunk egy képletes ábrát az elmondottakra:


Nos ennyi szerintem maximálisan elég (sőt sok is) a StatusLine használatáról ezután mindenkinek értenie kell aki eddig figyelemmel követte e rovatunkat, a CD-n a forráskód áttanulmányozása ajánlott. Nem feltétlenül csak a StatusLine miatt koptattam ennyit a billentyűt, hanem egyfajta logikát a Turbo Vision-ben általában használt láncolt lista felépítését, mikéntjét akartam bővebben leírni, hogy ezután máshol ne kelljen annyit magyarázkodni. Lehet, hogy sokak szerint fölösleges mert ez egyértelmű de nem mindenki középhaladó szintről indul, vannak köztetek kezdők is, s rájuk is gondolni kell.
Ezután tényleg jöjjön a Menu, amit nem fogok ily részletesen kitárgyalni, hisz hasonló használatának logikája.

A lényeg itt is ugyanaz a StatusLine-hoz hasonlóan az applikáció InitMenuBar virtuális metódusát kell átírni, s értéket adni az APP Unit-ban deklarált MenuBar változónak.
A menü felépítése ugyanúgy történik, egymásba láncolt listák elemeiből (items). Az elemek lehetnek menüparancsok, vagy legördülő almenük (submenu) menüparancsai. Ez egy kicsit lökötten hangzik, de pontosítsunk: A menüsávban is elhelyezhetünk menüparancsot, ilyenkor arra klikkantva a parancs rögtön végrehajtódik (így olyan, mint a StatusLine); A menüsávban általában almenük vannak és ezekből kell kiválasztani a menüparancsokat (menüpontokat). Álljunk neki építgetni menünket ! Az okosok azt mondják, hogy Turbo Vision-ben a menü készítése 3 lépcsőfokból áll:

  1. A menübár (MenuBar) méretének és elhelyezkedésének megadása
  2. A MenuItem-ek felépítése
  3. És végül a SubMenu-k (almenük) meghatározása.

Furcsának tűnhet, hogy előbb kell elkészíteni a menüpontokat, s csak utána annak a menünek a fejlécét amihez a menüpontok tartoznak. Amint említettem az okosak szerint ezt így kell csinálni, de szerintem maximálisan felcserélhető a 2. és 3. lépés.

 

procedure TmyApp.InitMenuBar;

 

var R: TRect;

 

begin

 

GetExtent(R); {az applikáció méretének lekérdezése}

 

R.B.Y := R.A.Y + 1; {a MenuBar a képernyő legfelső sorába kerül}

 

{...} {stb.}

 

end;

A méret meghatározása ennyi lett volna. (szerintem logIQs).

Most jön a 2. Lépés, a menüelemek - menüparancsok meghatározása DE még nincsenek almenük ! Nos, ha csak menüelemek vannak akkor ‘menünk' úgy néz ki, mint a StatusLine, ez a legegyszerűbb menü. (Igaz ezt a megoldást csak ritkán használjuk, ha két, vagy három dolog között kell választani.) Nézzük a lényeget: mindenegyes menüelem (MenuItem) 6 (!) részből épül fel, ezek:

  • Először is a menü neve, az a szöveg ami megjelenik a menüben. (pl: ‘Open')
  • Másodszor a hozzá tartozó forrókulcs szöveg része (ha van ilyen). (pl.: ‘F3')
  • Harmadszor a forrókulcs (ha van ilyen) scan kódja, a megszokott kbXXXX konstanssal.
  • A lényeg: a parancs ami végrehajtódik ha a rámegyünk, vagy ráklikkantunk a menüelemre.
  • A HelpContext száma. (Erről már sokat beszéltünk. FIGYELEM: így egyszerűen meg lehet azt is csinálni, hogy ahogy megyünk a menüben más-más StatusLine jelenik meg. Lásd:PELDA1.PAS!)
  • Pointer a következő menüelemre. (Ettől lesz láncolt listánk, ha meg nincs következő elem akkor Nil);

Lássunk végre valami menüt:

 

procedure TmyApp.InitMenuBar;

 

var R: TRect;

 

begin

 

GetExtent(R);

 

R.B.Y := R.A.Y + 1;

 

MenuBar := New(PMenuBar, Init(R, NewMenu(

   
 

NewItem(‘~N~ew', ‘', kbNoKey, cmNew, hcNew,

 

NewItem(‘~O~pen', ‘F3', kbF3, cmOpen, hcOpen,

 

NewItem(‘~S~ave', ‘F2', kbF2, cmSave, hcSave,

 

NewItem(‘~S~ave as...', ‘', kbNoKey, cmSaveAs, hcSaveAs,

 

NewLine(

 

NewItem(‘~E~xit', ‘ALT+X', kbAltX, cmQuit, hcExit,

 

nil)))))))));

 

end;

Na végre ez már valami menü féle de még mindig elég satnya, ollan (olyan) mint a StatusLine, DE azért egy kis magyarázatra szorul.

  • A méretmeghatározás OK. Azután: Az APP Unit-ban deklarált MenuBar változónak adunk PMenuBar típusú Pointer értéket a New() függvénnyel. A TMenuBar (PMenuBar) constructor Init; metódusának paraméterként a méret kell - ezt adjuk meg az R változóval - és egy PMenu típusú Pointer, ezt pedig a NewMenu() függvénnyel adjuk meg.
  • A NewMenu() függvénynek pedig paraméterként PMenuItem típusú Pointer-t kell megadni.
  • PMenuItem típusú Pointer-t pedig a NewItem()függvénnyel lehet létrehozni.
  • A NewItem()függvénynek pedig a fent elmondott 6 dolog kell. Ezek:
    A név: az a betű amit tilde jelek (~ ~) közé zárunk az kiemelt színű lesz, és ALT+ EzABetűvel lehet azt a menüt meghívni. Pl.: ‘~N~ew' a név. ALT+N -
    meghívódik a menüparancs. De a későbbiekben ugyanígy lehet a File almenüt ALT+F-fel lehívni.
  • A forrókulcs szövegének és scan kódjának megadás egyértelmű.
  • A cmXXXX parancsokról még később bőven szólunk.
  • A hcXXXX - HelpContext számokról meg már szólottunk.
  • A fenti hat dolog közül az utolsó pedig a következő menüelemre mutató PMenuItem Pointer. Ha van következő elem akkor a vessző után simán újra beírhatjuk a NewItem() függvényt hiszen ennek a függvénynek a visszatérési értéke PMenuItem. Így láncoljuk egymásba a menüelemeket.
  • Láttuk a fenti forráslistában a NewLine() függvényt ez nem mást csinál, mint elválasztja a menüben a különböző értelmű menüelemeket egy vonallal. (Mivel a NewLine() függveny is PMenuItem visszatérésű ezért nyugodtan belerakhatjuk a láncolt listába.)
    Az eddig elmondottak valahogy így fognak kinézni:


Láthatjuk, hogy egy sorban helyezkednek el a menüelemek így olyan, mint a StatusLine.

A fenti példát módosítsuk és hozzunk létre almenüket (Az almenü nem más, mint az a legördülő menüpontokból álló verikális menübox.): (Ez a 3. lépés)

Almenük létrehozása:

Az almenü elemeknek nincsenek forrókulcsaik, mint a sima menüelemeknek. (Így se szöveg, se billentyű konstans nincs.) Az almenük létrehozásakor használt paraméterei a NewSubMenu()-nek:

  • Szöveg felirat az almenünek. (Ugyanúgy, mint a sima menüelemnél, a tilde jelek itt is használhatóak.)
  • A Help Context szám
  • Pointer az első menüelemre az almenüben
  • Pointer a következő almenüre.

Nézzünk egy egyszerű példát:

 

procedure TMyApp.InitMenuBar;

 

var R: TRect;

 

begin

 

GetExtent(R);

 

R.B.Y := R.A.Y + 1;

 

MenuBar := New(PMenuBar, Init(R, NewMenu(

 

NewSubMenu~F~ile', hcNoContext, NewMenu(

 

NewItem~O~pen', ‘F3', kbF3, cmOpen, hcOpen,

 

nil)), {nincs több menüelem}

 

nil){nincs több almenü}

 

))); {a New, Init, NewMenu zárójeleit zárjuk be}

 

end;

Ez a menü így fog kinézni ha elindítjuk példaprogramunkat:

Egy kis magyarázat:

  • A NewSubMenu() függvénnyel lehet almenüt létrehozni. E függvénynek a visszatérési típusa PMenuItem, ezért bárhol beszúrhatjuk menürendszerünkben. Nem csak a menü sávban lehet egy legördülő almenü, hanem egy almenünek is lehet almenüje, de ezt később.
  • A NewSubMenu() függvény első paramétere az almenü neve. Pl.: ‘~F~ile'. Ekkor - mivel az F betű van a tile jelek között ha ALT+F -et nyomunk legördül a File menü. (Tehát az ALT+ a tile jelek közötti betűvel lehet meghívni az adott almenüt - akár csak a menüelemeket.)
  • A második paraméter a Help Context szám, jelen esetben hcNoContext ami annyit jelent, hogy NINCS help context-je ! (A hcNoContext értéke = 0.)
  • A harmadik paraméter az első menüelem Pointer-e DE kicsit megzavarva ... Minek kell ide a NewMenu() függvény, ha menüelemről van szó és ennek típusa PMenuItem ? A NewMenu() függvény bemenő paramétere PMenuItem típusú és a visszatérési típusa is. NewMenu() függvény a bemenő PMenuItem típusú Pointer-nek és általa meghatározott menüelemnek helyet foglal a heap-ben. (Különben így logikusabb is a felépítése az egésznek, hisz az új almenünek (legördülő menünek) egy ‘menüoszlopra' van szüksége és ezt a NewMenu() tesszük egy szemmel elkülöníthető egységgé.) A NewMenu() függvény paramétereként adjuk meg az egymásba láncolt menüelemeket (PMenuItem), ide beszúrhatnánk az utolsó előtti forráskód részlet menüelemeit. A első nil, azt jelöli, hogy nincs több menü elem.
  • A második nil pedig azt, hogy NINCS több almenü !

Nézzünk több menüelemből álló almenüt:

 

MenuBar := New(PMenuBar, Init(R, NewMenu(

 

NewSubMenu~F~ile', hcNoContext, NewMenu(

 

NewItem~O~pen', ‘F3', kbF3, cmOpen, hcOpen,

 

NewItem~N~ew', ‘F4', kbF4, cmNew, hcNew,

 

nil))), {nincs több menüelem}

 

nil){nincs több almenü}

 

))); {a New, Init, NewMenu zárójeleit zárjuk be}

Ez meg így néz ki:

Látjuk, hogy a NewItem() függvénnyel egymásután simán szúrhatjuk be a menüelemeket, csak a zárójelekre vigyázni: annyi csukó-zárójel legyen amennyi nyitó.

Nézzünk valami érdekesebbet, legyen több almenünk:

 

MenuBar := New(PMenuBar, Init(R, NewMenu(

 

NewSubMenu~F~ile', hcNoContext, NewMenu(

 

NewItem~O~pen', ‘F3', kbF3, cmOpen, hcOpen,

 

NewItem~N~ew', ‘F4', kbF4, cmNew, hcNew,

 

nil))), {nincs több menüelem e almenüben}

 

NewSubMenu~W~indow', hcNoContext, NewMenu(

 

NewItem~N~ext', ‘F6', kbF6, cmNext, hcNoContext,

 

NewItem~Z~oom', ‘F5', kbF5, cmZoom, hcNoContext,

 

nil)), {nincs több menüelem e almenüben}

 

nil))){nincs több almenü}

 

))); {a New, Init, NewMenu zárójeleit zárjuk be}

Ez már sokkal jobban néz ki:

A fenti példa is egyértelmű, az almenüket is egymás után helyezzük el, persze mindegyik almenüt megfelelően lezárjuk - azzal, hogy nincs több menüelem pontosan a nil-lel. -.

Egy oldallal feljebb beszéltünk valami NewLine() függvényről ami elválasztja egy almenüben a különböző típusú parancsokat, lássuk példával:

 

MenuBar := New(PMenuBar, Init(R, NewMenu(

 

NewSubMenu~F~ile', hcNoContext, NewMenu(

 

NewItem~O~pen', ‘F3', kbF3, cmOpen, hcOpen,

 

NewItem~N~ew', ‘F4', kbF4, cmNew, hcNew,

 

NewLine(

 

NewItem~E~xit', ‘Alt+X', kbAltX, cmQuit, hcExit,

 

nil))))), {nincs több menüelem e almenüben}

 

NewSubMenu~W~indow', hcNoContext, NewMenu(

 

NewItem~N~ext', ‘F6', kbF6, cmNext, hcNoContext,

 

NewItem~Z~oom', ‘F5', kbF5, cmZoom, hcNoContext,

 

nil)), {nincs több menüelem e almenüben}

 

nil))){nincs több almenü}

 

))); {a New, Init, NewMenu zárójeleit zárjuk be}

Így néz ki:

Végezetül valami nagyon szép: almenü almenüje:

 

MenuBar := New(PMenuBar, Init(R, NewMenu(

 

NewSubMenu~F~ile', hcNoContext, NewMenu(

 

NewItem~O~pen', ‘F3', kbF3, cmOpen, hcOpen,

 

NewItem~N~ew', ‘F4', kbF4, cmNew, hcNew,

 

NewLine(

 

NewItem~E~xit', ‘Alt+X', kbAltX, cmQuit, hcExit,

 

nil))))), {nincs több menüelem e almenüben}

 

NewSubMenu~W~indow', hcNoContext, NewMenu(

 

NewSubMenu('~A~rrange', hcNoContext, NewMenu(

 

NewItem('~T~ile', '', kbNoKey, cmTile, hcTile,

 

NewItem('C~a~scade', '', kbNoKey, cmCascade, hcCascade,

 

NewItem('Cl~o~se all', '', kbNoKey, cmCloseAll, hcCloseAll,

 

nil)))),

 

NewSubMenu('~C~ommands', hcNoContext, NewMenu(

 

NewItem('~S~ize/Move','Ctrl+F5', kbCtrlF5, cmResize, hcResize,

 

NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcZoom,

 

NewItem('~N~ext', 'F6', kbF6, cmNext, hcNext,

 

NewItem('~P~revious', 'Shift+F6', kbShiftF6, cmPrev, hcPrev,

 

NewItem('~C~lose', 'Alt+F3', kbAltF3, cmClose, hcClose,

 

nil)))))), {nincs több menüelem e almenüben}

 

nil))), {nincs több menüelem, se almenü e almenüben}

 

nil))){nincs több almenü}

 

));

És végezetül ez így néz ki:

Almenübe al-al menüt elvileg tisztes mélységig egymásba ágyazhatunk, de ember legyen a talpán ki sok al-al menü után kiigazodik a menü forráskódi felépítésén.

Menünk felépítését végezhetjük rutin munkaként, hogy ide egy NewItem(), ide egy NewSubMenu() kell, de ilyen al-al menüs zavargáskor szerintem - legalább is az elején - érdemes átgondolni, hogy ennek a függvénynek ez a paramétere, ezt ad vissza, és ez kell ide ... szóval érdemes logIQsan átgondolni.

Az APP Unit-ban vannak az úgyn. StdXXXMenuItems (StdFileMenuItems, StdEditMenuItems, StdWindowMenuItems) amik felettébb hasznosak, csak beszúrjuk őket egy menüelem (PMenuItem) helyére, s máris kész a szabványos menünk. (File, Edit, Window menü) (Lásd PELDA2.pas !)

 

Itt a vége fuss el vége, remélem mindenki tökéletesen megértette a StatusLine és MenuBar használatát, 8 és fél oldalt (+2 napot) áldoztam erre. Aki mégis elkavarodott volna a menük, szövevényes felépítésében az eMail-eljen nekem. (A szövevényes persze relatív, mint majdnem minden hisz első hallásra ‘szövevényesnek' tűnhet, de később egyértelművé, rutinná válik.)

Következő számunkban foglalkozunk egy csipetnyit a Turbo Vision esemény kezelésével, eseményeinek lekezelésével.