Program MyMenu; (* Copyright(c) : 1997 JERMiC Sw * Coded by : Laat (Laat@4u.net) * * Hi, All! * * Some time ago in my mind grew up one idea which found its * implementation in following peace of code. The main idea is * simple as 2by2is4 - processing menu. * After looking at this source you maight find yourself * wondering - what's up with this Laat, why's he doing all the * things so complicated? Well, my answer is - you can * cut/change/combinate this prog till you feel good and * statisfied. Anyway, i made this version of program for * myself, not even for use, just for seeing how these things * look like meanwhile writing program. * So, it is slightly possible that i will post some new (well, * that depends on how to look at this topic) source with simplified * version of menu rocessing. * * As Yours as you want me to be, * Laat * * 15/11/97 *) Uses Crt; Type tItem = record x, y : Word; HotKey : Char; Data : String; End; (* The same as UpCase applied to string-type *) Function UpCaseS ( S : String ): String; Var i : Integer; Swaps : String; Begin Swaps:=''; If S<>'' then For i:=1 to Length(S) do Swaps:=Swaps+UpCase(S[i]); UpCaseS:=Swaps; End; Procedure CursorOff;assembler; (* Hides cursor *) Asm mov AH,$01 mov CH,$20 mov CL,$0 int $10 End; Procedure CursorOn; assembler; (* Shows cursor *) Asm mov AH,$01 mov CH,$3 mov CL,$4 int $10 End; (* Procedure used to make this program shorter (tired of writing TextColor * and TextBackGround together all the time). *) Procedure Col ( _Fc, _Bc: Byte ); Begin TextColor(_Fc); TextBackGround(_Bc); End; (* Function which executes given menu. * Requires: * _Arr - Array of TItem type (see Type section); * _Fg, _Bg - Text and background colors of unselected items; * _Fg1, _Bg1 - Text and background colors of selected items; * Pos - Start position of cursor in the menu by default; * _N - How much items there are in you menu. * Returns: * Number of chosen menu or value '0' if Esc has been pressed. * *) Function ExecuteMenu ( _Arr: Array of tItem; _Fg, _Bg, _Fg1, _Bg1: Byte; _Pos: Byte; _N: Byte ): Byte; Var (* _N,*) _J, _J1 : Integer; _TheEnd, _Ext, _Esc, _Found : Boolean; _Ch : Char; Procedure Draw; (* Draws Menu _Arr *) Var _i : Integer; Begin For _i:=0 to _N-1 do Begin If _Arr[_I].Y+_i>50-_Arr[_I].Y then Break; GotoXY(_Arr[_I].X, _Arr[_I].Y); If _i+1<>_Pos then Begin Col(_Fg, _Bg); Write(' '+_Arr[_i].Data+' '); Col(4, _Bg); End Else Begin Col(_Fg1, _Bg1); Write(' '+_Arr[_i].Data+' '); Col( 4, _Bg1); End; GotoXY(_Arr[_i].x+Pos(UpCase(_Arr[_i].HotKey), UpCaseS(_Arr[_i].Data)),_Arr[_i].y); If Pos(UpCase(_Arr[_i].HotKey), UpCaseS(_Arr[_i].Data))<>0 then Write(_Arr[_i].Data[Pos(UpCase(_Arr[_i].HotKey),UpCaseS(_Arr[_i].Data))]); End; End; Begin (* _N:=SizeOf(_Arr) div 255; - this was useful till we got menu items * defined in Const section (such arrays * have fixed size, as you already know of * course). *) _Esc:=False; _TheEnd:=False; _Found:=False; Repeat Draw; _Ch:=UpCase(ReadKey); Case _Ch of #000 : Begin (* Extended keystroke is got *) _Ext:=True; _Ch:=ReadKey; Case _Ch of (* UpArr *) #72, #75 : If _Pos>1 then Dec(_Pos) Else _Pos:=_N; (* DnArr *) #80, #77 : If _Pos<_N then Inc(_Pos) Else _Pos:=1; (* End *) #79 : _Pos:=_N; (* Home *) #71 : _Pos:=1; End; End; (*Esc*)#027 : Begin _TheEnd:=True; _Esc:=True; End; (*Ent*)#013 : _TheEnd:=True; (*Other*) Else Begin _J:=_Pos-1; _J1:=_J; Inc(_J); Repeat If _J>=_N then _J:=0; If _J=_J1 then Break; If UpCase(_Arr[_J].HotKey)=_Ch then Begin _Pos:=_J+1; Break; End else Inc(_J); Until _Found; End; End Until _TheEnd; If _Esc then ExecuteMenu:=0 Else ExecuteMenu:=_Pos; End; Const (* Menu to execute * Thought it is hard to define in const, you could use your * brain and write your own procedure which adds given menu item * to a given array, for example, header of such a procedure maight * look like : * Procedure AddItem ( var ArrayToAddIn: Array of TItem; * ItemToAdd: TItem; * ToWhichPosition: Byte ); *) Arr : Array[1..10]of tItem=((X:10; Y: 5; HotKey:'F'; Data:'First '), (X:10; Y: 6; HotKey:'S'; Data:'Second '), (X:10; Y: 7; HotKey:'T'; Data:'Third '), (X:10; Y: 8; HotKey:'F'; Data:'Fourth '), (X:10; Y: 9; HotKey:'I'; Data:'Fifth '), (X:10; Y:10; HotKey:'S'; Data:'Sixth '), (X:10; Y:11; HotKey:'H'; Data:'Seventh'), (X:10; Y:12; HotKey:'E'; Data:'Eighth '), (X:10; Y:13; HotKey:'N'; Data:'Ninth '), (X:10; Y:14; HotKey:'T'; Data:'Tenth ')); Var n : Integer; Begin Col(07, 00); ClrScr; CursorOff; GotoXY(01, 25); WriteLn(#24','#25','#27','#26',Home,End,Esc'); n:=ExecuteMenu(Arr ,00, 07, 15, 01, 02, 10); Col(07, 00); ClrScr; CursorOn; If n<>0 then WriteLn('Your choice was: ', Arr[n].Data) else WriteLn('Where is your choice?'); End.