home *** CD-ROM | disk | FTP | other *** search
- PROGRAM MCMenu;
- { ver 0.000
- ^ bug fix
- ^^ minor rev
- ^ major rev
- { Turbo Pascal 5.5 }
-
- { Malaspina College Menu }
- { ALL work done on MY time, as was original concept. }
- { 0.100 work start Nov 18 1991 Tony Bigras BIGRAS@MALA.BC.CA
- (604) 753-3245 x2588 }
- { 0.708 seems ok menu wise most bugs out ( the ones I know about )
-
- 0.710 another bug in submenus with data going to end of file fixed
- adjusted calcfloatindex for N+ switch I had put it around func
- but it has to be global. That picked up 10k of .exe
-
- 0.711 fixed bug with empty lines in menu file causing
- invalid menu message
-
- 0.712 turn off cursor so menu looks cleaner
- turned on again at end of prog with call to co80
-
- 0.713 mouse support for microsoft mouse type
- left button = RETURN
- right button = ESC
- up and down = up down keys
- no mouse pointer just key translation
-
- 0.714 Monitor to full screen width
- Prompt on main screen for F1 for help
- Check DOS version min 3.00
- 0.715 figure out name of this program for
- appending to end of alt255.bat file.
- only partial work done
- 0.716 no esc character on last line '!' was being added
- to last menu item.
- 0.717 mono card colour selections and detection
- it was giving underlines for many items (blue background)
- 0.718 padded time with 0's
- only display esc from main menu in help if avail
-
- initial implementation will be only for advertised RPC's
- no downloaded code only resident code
- just download and upload data
- so all resident RPC's use a single pointer to a structure
- in the interface of the RPCUnit
- 0.719 adding in netbios hooks
- also boosted intcalc to get 1 on pc 4.77mhz
- 0.720 tuned mouse response in SYSSUP
- 0.721 little bug with lack of key buffering in SYSSUP
- 0.722 little bug in not displaying exit errors
- 0.723 adjust netbios detect to compare for unused vectors as well
- 0.724 move blank interval to 3 minutes and blank move to 5 sec
- 0.725 put move interval onto regular interval start ie 0 5 10 15etc
- 0.726 switched from alt255.bat to X.bat to allow novell to flag
- file x.bat when deleting others in directory.
-
- should add total temp convert to upper case in menu match
- testing in getinfo. currently wont match Hello and hello
- 0.727 more mouse tuneing
- 0.728 ""
- 0.729 added mcmenu ver to blanker screen
- 0.800 reduced program heap size to prevent command.com
- transient portion being forced out
- added extended last line controls not just no escape
- ! or !! is no escape
- !R is enable RPC
- !!R no escape + enable RPC
-
- 0.801 turned off rpcstatus if not rpcok
- 0.900 multi nested menus 4000 lines and 200 menus 20 items/menu
- 0.901 recurseive menu structures
- widened menus to 76 characters with error trimming
- 0.902 integrated menu and sub menu execution into single function
- 0.910 added support for 21 items / menu and alpha keying of menu selection
- better error trapping on file r/w
- improved error messages
- 0.911 bug in sub menus, they are displaying locator info: fixed
- 0.930 RPC monitor removed, debug code removed
- no functional changes
- 1.000 First release with source code.
- RPC interface describe in docs but not implemented here.
- 1.001 alpha keying bug fixed
- 1.002 dos 5.0 reading past end of X.bat fixed
- 1.010 use dos param(0) to figure name and path of menu program
- to write to batch file. Also search program directory
- first for menu data file. If not found turn over to DOS
- search mechanism.
- 1.011 Internal Malaspina College mod with 'tuesday'
- spelling fix and change to noise with error
- in input file.
-
- 1.1 - 1.4 reserved for public mods
-
-
- 1.500 Addeed Launch Logger hard coded to S:\LOG\LOG>TXT
- with reference to USRN env variable and with the ability
- to log program launches. Uses the !L control
-
- 1.510 Ability to not include menu
- rerun line at end of batch file.
- IF !MC! is at begining of line then that plus
- one space are stripped and final line of bat
- file is not the menu name etc. This is usefull
- for switching between multiple menus as it
- does not let leftover batch file parts interfere
- with the transfer.
-
- 1.520 added a space to right side of menu items for better
- viewing. Change blank start time to 5 minutes.
- and added !M to allow menu to return to last item
- ' SEE DOCS '
- }
- { Public Domain, Absolutly NO liability accepted! }
- { Processes Novell type menu using 0k with Hard drive menu ability}
- { and hooks to Remote Procedure Calls }
- { Uses Novell menu script but ignores colours, menu locators }
- { need more features, you have the source. }
- { NOTE uses Env Var MN to name menu to use or Command Line overide }
-
- USES Crt,Dos,Win,SysSup,TextMenu;
-
- {L Win }
- {L SysSup}
- {L TextMenu }
- { 0.800 }
- {$M 32768,100000,100000}
-
- CONST
- verstr = '1.520';
- blanks = ' ';
- { 0.900 }
- maxdata= 4000;
- maxmenu=200;
- { 0.726 }
- fnamechar='X';
-
- TYPE
- menunumtype= 0..maxmenu;
- mcmenutype= RECORD
- num: 1..mxonmenu;
- strs: ARRAY[0..mxonmenu+1] OF 1..maxdata; { +1 to find end of item }
- issub: ARRAY[1..mxonmenu] OF BOOLEAN;
- menuidx: ARRAY[1..mxonmenu] OF menunumtype;
- END;
-
- VAR
- escapeok,escaped: BOOLEAN;
-
-
- ch: CHAR;
- ttlscr: winrecptr;
- curhelp: STRING;
- reg: REGISTERS;
- oldhelpvec,oldhk2vec: POINTER;
- cnt,maxcnt: INTEGER;
- filestr: STRING;
- mdatastr: ARRAY[1..maxdata] OF ^STRING;
- numdata: 1..maxdata;
- menus: ARRAY[0..maxmenu] OF mcmenutype;
- cl: BOOLEAN;
- dosverstr: STRING[10];
- totmenu: menunumtype;
-
- { 0.800 }
- rpcok: BOOLEAN;
- { 1.500 }
- logon: BOOLEAN;
- { 1.520 }
- memoryon: BOOLEAN; { put out info to return to same menu position }
- outputmemorystr: STRING;
- memorystr: STRING;
- { format for locating on menu is 2 chars per menu,
- with drops to lower menus indicated until end of
- string. Hence 100503 would be 10 on first menu
- 5 on second menu and 3 on third menu which is
- where it would stay.. IF memorystr<>'' THEN
- input is taken from the file 2 chars at a time }
- { Just a hack , IF memorystr contains invalid
- values for a menu level it is cleared. }
-
-
- PROCEDURE stufkeyp(codekey: INTEGER); EXTERNAL;
- {$L STUFKEYP.OBJ}
-
- PROCEDURE titlemsg(title: STRING;VAR wn: winrecptr);
- VAR
- attr: INTEGER;
- BEGIN {titlemsg}
- openwindow(2,2,79,2,wn);
- IF lastmode=mono THEN
- attr:=darkgray+lightgray*16
- ELSE
- attr:= blue+cyan*16;
-
- fillwin(#32,attr);
- writestr(1,1,title,attr);
- END; { titlemsg }
-
-
- PROCEDURE error(str: STRING);
- VAR
- i: INTEGER;
- BEGIN { error }
- window(1,1,80,25);
- textbackground(black);
- textcolor(lightgray);
- clrscr;
- SETINTVEC(250,oldhelpvec);
- SETINTVEC(251,oldhk2vec);
- textmode(lastmode);
- { 0.910 }
- WRITELN;
- WRITELN(CONCAT('MC Menu Ver ',verstr,' E R R O R.'));
- WRITELN;
- WRITE(' ');
- WRITELN(str);
- WRITELN;
- WRITELN;
-
- { 0.910 }
- {
- FOR i:= 1 TO 8 DO
- BEGIN
- sound(100);
- delay(200);
- sound(500);
- delay(200);
- END;
- }
- { 1.011 }
- sound(500);
- delay(300);
- nosound;
- HALT(1);
- END; { error }
-
- PROCEDURE help; INTERRUPT; { vector 250 }
- CONST
- helpattr= black+lightgray*16;
-
- VAR
- helpwin: winrecptr;
- oldwin: winstate;
- i: INTEGER;
- key: CHAR;
- helphack: INTEGER;
- BEGIN { help }
- inhelp:= TRUE;
- savewin(oldwin);
- openwindow(1,4,80,25,helpwin);
- tframewin('MC Menu Help',singleframe,helpattr,helpattr);
- fillwin(#32, helpattr);
- textattr:=helpattr;
- gotoxy(1,1);
- savewin(helpwin^.state);
- GOTOXY(1,2);
-
- IF (curhelp='General') THEN helphack:=1;
-
- CASE helphack OF
-
- 1: BEGIN
- WRITELN;
- WRITELN(' Items with a » have a sub menu.');
- WRITELN;
- WRITELN(' Select an item or a submenu by pressing the ENTER key.');
- WRITELN;
- WRITELN(' Choose different items using arrow or alpha keys. ');
- WRITELN;
- IF hasmouse THEN
- BEGIN
- WRITELN(' Mouse Active... left button = RETURN, right = ESC.');
- WRITELN;
- END; { hasmouse }
- WRITELN(' Exit a submenu with the ESC key.');
- WRITELN;
- { 0.716 }
- IF escapeok THEN
- WRITELN(' Exit the Main Menu with the ESC key.');
- WriteStr(16,17,
- 'Public Domain by Tony Bigras August 24 1992',
- helpattr);
- END { 1 };
-
- END; { CASE }
- WriteSTr(26,19,'Press <ESC> to leave Help.',helpattr);
- key:= allowkey([CHAR(esc)],-1);
- restorewin(helpwin^.state);
- unframewin;
- closewindow(helpwin);
- restorewin(oldwin);
- inhelp:= FALSE;
- END; { help }
-
- PROCEDURE titlescreen;
- VAR
- attr: INTEGER;
- attrf1: INTEGER;
- BEGIN { titlescreen }
- openwindow(1,1,80,3,ttlscr);
- IF lastmode=mono THEN
- BEGIN
- attr:= black+lightgray*16;
- attrf1:=darkgray+black*16;
- END
- ELSE
- BEGIN
- attr:= blue+cyan*16;
- attrf1:=white+blue*16;
- END;
- framewin(singleframe,attr);
- WriteStr(1,1,'M C Menu Ver '+verstr+' '
- ,attr);
- window(1,4,80,25);
- fillwin(#177,attr);
- WriteStr(1,22,
- '<F1>-Help '
- ,attrf1);
- END; { titlescreen }
-
- PROCEDURE domainmenu;
-
- CONST
- fname= fnamechar+'.bat';
-
- VAR
- f: TEXT;
- i,choice: INTEGER;
- menu: menutype;
- selected: BOOLEAN;
-
-
- { 1.500 }
- PROCEDURE Writelog(application: STRING);
-
- CONST
- trycount= 30;
- flogname='S:\LOG\LOG.TXT';
- maxtrydelay= 100;
- mintrydelay= 20;
-
- VAR
- f: TEXT;
- delvar: INTEGER;
- count: INTEGER;
- logstr: STRING;
- year,month,day,dayofweek: WORD;
- s: STRING;
- hour,minute,second,sec100: WORD;
- i: INTEGER;
- iores: INTEGER;
-
- BEGIN { Writelog }
- logstr:=application;
- IF LENGTH(logstr)<30 THEN
- logstr:=CONCAT(logstr,COPY(blanks,1,30-LENGTH(logstr)))
- ELSE
- logstr:=COPY(logstr,1,30);
-
- logstr:= CONCAT(logstr,' ',getenv('USRN'));
- IF LENGTH(logstr)<40 THEN
- logstr:=CONCAT(logstr,COPY(blanks,1,40-LENGTH(logstr)))
- ELSE
- logstr:=COPY(logstr,1,40);
-
- logstr:=CONCAT(logstr,' ');
-
- GetDate(year,month,day,dayofweek);
- CASE dayofweek OF
- 0: logstr:=CONCAT(logstr,'Sun');
- 1: logstr:=CONCAT(logstr,'Mon');
- 2: logstr:=CONCAT(logstr,'Tue');
- 3: logstr:=CONCAT(logstr,'Wed');
- 4: logstr:=CONCAT(logstr,'Thu');
- 5: logstr:=CONCAT(logstr,'Fri');
- 6: logstr:=CONCAT(logstr,'Sat');
- END; { CASE }
-
- CASE month OF
- 1: logstr:= CONCAT(logstr,' Jan');
- 2: logstr:= CONCAT(logstr,' Feb');
- 3: logstr:= CONCAT(logstr,' Mar');
- 4: logstr:= CONCAT(logstr,' Apr');
- 5: logstr:= CONCAT(logstr,' May');
- 6: logstr:= CONCAT(logstr,' Jun');
- 7: logstr:= CONCAT(logstr,' Jul');
- 8: logstr:= CONCAT(logstr,' Aug');
- 9: logstr:= CONCAT(logstr,' Sep');
- 10: logstr:= CONCAT(logstr,' Oct');
- 11: logstr:= CONCAT(logstr,' Nov');
- 12: logstr:= CONCAT(logstr,' Dec');
- END; { CASE }
-
- STR(day:2,s);
- logstr:= CONCAT(logstr,' ',s);
- STR(year:4,s);
- logstr:= CONCAT(logstr,' ',s);
- GetTime(hour,minute,second,sec100);
- STR(hour:2,s);
- FOR i:= 1 TO LENGTH(s) DO
- IF s[i]= ' ' THEN
- s[i]:='0';
- logstr:= CONCAT(logstr,' ',s);
- STR(minute:2,s);
- FOR i:= 1 TO LENGTH(s) DO
- IF s[i]= ' ' THEN
- s[i]:='0';
- logstr:= CONCAT(logstr,':',s);
- STR(second:2,s);
- FOR i:= 1 TO LENGTH(s) DO
- IF s[i]= ' ' THEN
- s[i]:='0';
- logstr:= CONCAT(logstr,':',s);
-
- {$I-}
- count:= 0;
- REPEAT
- ASSIGN(f,flogname);
- delay(mintrydelay+Random(maxtrydelay-mintrydelay));
- count:= count+1;
- APPEND(f);
- iores:=ioresult;
-
- { debug
- writeln(iores,' ',flogname);
- }
-
- UNTIL (iores=0) OR (count>trycount);
-
- { debug
- IF count >trycount then
- begin
- writeln(trycount);
- readln;
- end;
- }
-
-
- WRITELN(f,logstr);
- CLOSE(f);
- {$I+}
-
- END; { Writelog }
-
-
- PROCEDURE checkforparms(cnt: INTEGER);
- CONST
- maxparm= 9;
- VAR
- i,k: INTEGER;
- tstr,tstr2: STRING[80];
- parm: ARRAY[1..maxparm] OF STRING[80];
- parmactive: ARRAY[1..maxparm] OF BOOLEAN;
- parpos: INTEGER;
-
-
- PROCEDURE winedit(wn: winrecptr; edbuf: pointer;
- size: WORD; keys: keysettype;noscroll: BOOLEAN; exitchr: CHAR);
- TYPE
- tbuftype= ARRAY[0..65000] OF CHAR;
- VAR
- key: CHAR;
- keysallowed: keysettype;
- minx,miny,maxx,maxy: INTEGER;
- curx,cury: INTEGER;
- tptr: ^tbuftype;
- BEGIN { edit }
- tptr:=edbuf;
- restorewin(wn^.state);
- minx:=1;
- miny:=1;
- maxx:=(Lo(WindMax)-Lo(WindMin))+1;
- maxy:=(Hi(WindMax)-Hi(WindMin))+1;
- curx:=minx;
- cury:=miny;
- gotoxy(minx,miny);
- keys:=keys+[CHR(up),CHR(down),CHR(left),CHR(right),
- CHR(esc),CHR(bs),CHR(return)];
- REPEAT
- key:= allowkey(keys,-1);
- CASE key OF
- CHR(32)..CHR(126):
- BEGIN
- GOTOXY(curx,cury);
- IF (curx<>maxx) AND (cury<>maxy) THEN
- Write(key)
- ELSE
- WriteChar(curx,cury,1,key, textattr);
- tptr^[((cury-1)*(maxx+1))+curx-1]:=key;
- IF curx<>maxx THEN
- INC(curx)
- ELSE
- IF cury<>maxy THEN
- BEGIN
- INC(cury);
- curx:=minx;
- END; { IF }
- GOTOXY(curx,cury);
- END; { 32..126 }
-
- CHR(bs):
- BEGIN
- IF curx<>minx THEN
- BEGIN
- DEC(curx);
- GOTOXY(curx,cury);
- write(CHR(space));
- GOTOXY(curx,cury);
- END;
- END; { bs }
-
- CHR(return):
- BEGIN
- IF cury<>maxy THEN
- BEGIN
- INC(cury);
- curx:=minx;
- GOTOXY(curx,cury);
- END;
- END; { return }
-
- CHR(up):
- BEGIN
- IF cury<>miny THEN
- BEGIN
- DEC(cury);
- GOTOXY(curx,cury);
- END;
- END; { up }
-
- CHR(down):
- BEGIN
- IF cury<>maxy THEN
- BEGIN
- INC(cury);
- GOTOXY(curx,cury);
- END;
- END; { down }
-
- CHR(left):
- BEGIN
- IF curx<>minx THEN
- BEGIN
- DEC(curx);
- GOTOXY(curx,cury);
- END;
- END; { left }
-
- CHR(right):
- BEGIN
- IF curx<>maxx THEN
- BEGIN
- INC(curx);
- GOTOXY(curx,cury);
- END;
- END; { right }
-
- END; { CASE }
- until key=exitchr;
- savewin(wn^.state);
- END; { winedit }
-
- FUNCTION getparm(str: STRING): STRING;
- CONST
- cgetattr= white+cyan*16;
- mgetattr= white+black*16;
- depth=3;
- width=60;
- TYPE
- edbuftype= ARRAY[0..width-2] OF BYTE;
- VAR
- wn: winrecptr;
- oldwin: winstate;
- edbuf: ^edbuftype;
- size: WORD;
- i: INTEGER;
- tstr: STRING;
- attr: INTEGER;
-
- BEGIN { getparms }
- IF lastmode=mono THEN
- attr:=mgetattr
- ELSE
- attr:=cgetattr;
- tstr:='';
- curhelp:= 'Enter Parameter';
- savewin(oldwin);
- openwindow(10,10,10+width-1,10+depth-1,wn);
- tframewin(str,doubleframe,attr,attr);
- fillwin(#32,attr);
- IF lastmode=mono THEN
- textattr:=mgetattr
- ELSE
- textattr:=cgetattr;
- gotoxy(1,1);
- savewin(wn^.state);
- size:=width*(depth-2);
- getmem(edbuf,size);
- FillChar(edbuf^,size,CHR(32));
- winedit(wn,edbuf,size,[CHR(32)..CHR(126)],TRUE,CHR(return));
- Move(edbuf^,tstr[1],width-2);
- tstr[0]:=CHR(width-2);
- WHILE tstr[LENGTH(tstr)]=' ' DO { strip trailing spaces }
- tstr[0]:= CHR(ORD(tstr[0])-1);
- getparm:= tstr;
- freemem(edbuf,size);
- restorewin(wn^.state);
- unframewin;
- closewindow(wn);
- restorewin(oldwin);
- END; { getparm }
-
- BEGIN { checkforparms }
- { parms take format stuf @1"Enter value" @2"enter drive" @2
- { would produce stuf value drive drive }
-
- FOR i:= 1 TO maxparm DO
- parmactive[i]:=FALSE;
- tstr:= mdatastr[cnt]^;
- { kill leading spaces }
- WHILE (tstr[1]=' ') DO
- tstr:= COPY(tstr,2,LENGTH(tstr)-1);
- tstr2:='';
- WHILE POS('@',tstr)<>0 DO
- BEGIN
- IF POS('@',tstr)>1 THEN
- BEGIN
- tstr2:=CONCAT(tstr2,COPY(tstr,1,POS('@',tstr)-1));
- tstr:=COPY(tstr,POS('@',tstr),LENGTH(tstr));
- END; { use up leading stuff }
- parpos:= POS('@',tstr);
- IF parpos<>0 THEN
- BEGIN
- IF tstr[parpos+1] IN ['1'..'9'] THEN { really a parameter }
- BEGIN
- IF parmactive[ORD(tstr[parpos+1])-48] THEN
- BEGIN { old parameter }
- tstr2:=CONCAT(tstr2,parm[ORD(tstr[parpos+1])-48]);
- tstr:=COPY(tstr,3,LENGTH(tstr)-2);
- END
- ELSE { new parameter }
- BEGIN
- parmactive[ORD(tstr[parpos+1])-48]:= TRUE;
- parm[ORD(tstr[parpos+1])-48]:=
- getparm(CONCAT(' ',COPY
- (tstr,parpos+3,POS('"',COPY(tstr,parpos+3,LENGTH(tstr)))-1),' '));
- tstr2:=CONCAT(tstr2,parm[ORD(tstr[parpos+1])-48]);
- tstr:= COPY(tstr,
- POS('"',COPY(tstr,parpos+3,LENGTH(tstr)))+4,LENGTH(tstr));
- END; { ELSE }
- END { really a parameter }
- ELSE
- BEGIN
- tstr2:=CONCAT(tstr2,'@');
- tstr:=COPY(tstr,2,LENGTH(tstr)-1);
- END; { not a parameter }
- END; { posible parameter }
- END; { WHILE }
- { now get tail of string }
- tstr2:=CONCAT(tstr2,tstr);
- FOR k:= 1 TO LENGTH(tstr2) DO
- tstr2[k]:=upcase(tstr2[k]); { convert to upper case }
-
- { its bigger now so re-get space }
-
- FREEMEM(mdatastr[cnt],LENGTH(mdatastr[cnt]^)+2);
- GETMEM(mdatastr[cnt],LENGTH(tstr2)+2);
- mdatastr[cnt]^:= tstr2;
- END; { checkforparms }
-
- PROCEDURE dosubmenu(smen: integer);
- VAR
- i: INTEGER;
- menu: menutype;
- restartmenu: BOOLEAN;
- { 1.520 }
- tstr: STRING;
- v1,v2: INTEGER;
- doingmemory: BOOLEAN;
-
- BEGIN { dosubmenu }
- menu.title:= mdatastr[menus[smen].strs[0]]^;
- menu.titlehelp:='';
- { 1.520 }
- doingmemory:= memorystr<>'';
- IF doingmemory THEN
- BEGIN
- VAL(COPY(memorystr,1,2),v1,v2);
- memorystr:=COPY(memorystr,3,LENGTH(memorystr)-2);
- IF v2<>0 THEN
- BEGIN
- doingmemory:= FALSE;
- memorystr:= '';
- END { error in memorystr }
- ELSE
- BEGIN { maybe a valid conversion }
- IF (v1 < 1) OR (v1>menus[smen].num) THEN
- BEGIN
- doingmemory:= FALSE;
- memorystr:= '';
- END;
- END; { else maybe valid }
- END; { memorystr being processed }
- FOR i:= 1 TO menus[smen].num DO
- BEGIN
- menu.item[i]:= mdatastr[menus[smen].strs[i]]^;
- menu.itemhelp[i]:='';
- END;
- WITH menu DO
- BEGIN
- numitem:=menus[smen].num;
-
- { 1.520 }
- IF doingmemory THEN
- oldselect:= v1
- ELSE
- oldselect:=1;
- mode:=replace;
- ctrl.sort:= FALSE;
- ctrl.wrap:= TRUE;
- ctrl.escape:= TRUE;
- ctrl.alphakey:= TRUE;
- END; { WITH }
- txtmenuinit(menu,0,0);
- REPEAT
- curhelp:='General';
-
- { 1.520 }
- IF doingmemory AND (memorystr<>'') THEN
- choice:= v1
- ELSE
- choice:= txtmenu(menu);
- savewin(menu.wn^.state);
- IF (choice<>0) THEN
- BEGIN
- STR(choice:2,tstr);
- outputmemorystr:=CONCAT(outputmemorystr,tstr);
-
-
- IF menus[smen].issub[choice] THEN
- dosubmenu(menus[smen].menuidx[choice])
- ELSE
- BEGIN
- {$I-}
- FOR i:= menus[smen].strs[choice]+1 TO menus[smen].strs[choice+1]-1 DO
- checkforparms(i);
- ASSIGN(f,fname);
- IF ioresult<>0 THEN
- error(CONCAT('Unable to Write to: > ',fname));
- REWRITE(f);
- IF ioresult<>0 THEN
- error(CONCAT('Unable to Write to: > ',fname));
-
- restartmenu:= TRUE;
- FOR i:= menus[smen].strs[choice]+1 TO menus[smen].strs[choice+1]-1 DO
- BEGIN { 1.510 }
- IF POS('!MC!',mdatastr[i]^)=1 THEN
- BEGIN
- restartmenu:= FALSE;
- mdatastr[i]^:= COPY(mdatastr[i]^,5,LENGTH(mdatastr[i]^)-4);
- END;
- IF (NOT restartmenu) AND (i=menus[smen].strs[choice+1]-1) THEN
- WRITE(f,mdatastr[i]^)
- ELSE
- WRITELN(f,mdatastr[i]^);
- END; { 1.510 }
-
- { 1.010 use parmastr(0) to get program name and path }
- { 1.002 from WRITELN as dos 5.0 kept on reading in new X.bat }
-
- { 1.520 }
- IF memoryon THEN
- BEGIN
- FOR i:= 1 TO LENGTH(outputmemorystr) DO
- IF outputmemorystr[i]=' ' THEN
- outputmemorystr[i]:='0';
- filestr:= CONCAT(filestr,' ',outputmemorystr);
- END;
-
- { 1.510 }
- IF restartmenu THEN
- WRITE(f,CONCAT('@',paramstr(0),' '),filestr);
-
- CLOSE(f);
- IF ioresult<>0 THEN
- error(CONCAT('Unable to Write to > ',fname));
-
-
- { 1.500 }
- IF logon THEN
- Writelog(mdatastr[menus[smen].strs[choice]]^);
-
-
-
- {$I+}
- selected:= TRUE;
- END;
- END; { choice<>0 }
- restorewin(menu.wn^.state);
- UNTIL (choice=0) OR selected;
- IF choice=0 THEN
- BEGIN
- choice:= smen;
- { 1.520 }
- outputmemorystr:= COPY(outputmemorystr,1,
- LENGTH(outputmemorystr)-2);
- choice:=smen;
- END;
- txtmenukill(menu);
- END; { dosubmenu }
-
- PROCEDURE confirmexit;
-
- VAR
- exitmenu: menutype;
- pick: INTEGER;
-
- BEGIN { confirmexit }
- WITH exitmenu DO
- BEGIN
- title:='Exit';
- titlehelp:='';
- item[2]:='Yes';
- itemhelp[2]:='';
- item[1]:='No';
- itemhelp[1]:='';
-
- numitem:=2;
- oldselect:=2;
- mode:=replace;
- ctrl.sort:= FALSE;
- ctrl.wrap:= FALSE;
- ctrl.escape:= TRUE;
- ctrl.alphakey:= TRUE;
- END; { WITH }
- txtmenuinit(exitmenu,0,0);
- pick:=txtmenu(exitmenu);
- txtmenukill(exitmenu);
- IF (pick=0) OR (pick=1) THEN { cancel escape }
- choice:=1; { menu.oldselect; }
- END; { confirmexit }
-
- BEGIN { domainmenu }
- selected:=FALSE;
- REPEAT
- dosubmenu(0);
- IF ((choice=0) AND escapeok) THEN
- confirmexit;
- UNTIL ((choice=0) AND escapeok) OR selected;
- escaped:= (choice=0);
- END; { domainmenu }
-
- {$I- }
- PROCEDURE getinfo;
- VAR
- f: TEXT;
- i,cnt,j,k: INTEGER;
- w: INTEGER;
- tstr,tstr2:STRING;
- ctrlline: BOOLEAN;
-
- PROCEDURE getsubs(menunum: menunumtype);
- VAR
- i,j,k,cnt,tcnt: INTEGER;
- tstr,tstr2,tstr3: STRING;
- notfound: BOOLEAN;
- BEGIN { getsubs }
- cnt:= menus[menunum].strs[0]+1;
- WHILE (cnt<=numdata) AND (mdatastr[cnt]^[1]<>'%') DO
- BEGIN { find all menu items }
- IF (mdatastr[cnt]^[1]<>' ') THEN { must be a menu item }
- BEGIN
- menus[menunum].strs[menus[menunum].num]:=cnt;
- WHILE (mdatastr[cnt+1]^[1]=' ') DO
- mdatastr[cnt+1]^:= COPY(mdatastr[cnt+1]^,2,LENGTH(mdatastr[cnt+1]^)-1);
- menus[menunum].issub[menus[menunum].num]:=(mdatastr[cnt+1]^[1]='%');
- IF menus[menunum].issub[menus[menunum].num] THEN
- BEGIN
- menus[menunum].menuidx[menus[menunum].num]:= totmenu+1;
- { find start of this submenu items menu }
- tcnt:=cnt+2;
- tstr:=mdatastr[menus[menunum].strs[menus[menunum].num]+1]^;
- FOR k:= 1 TO LENGTH(tstr) DO
- tstr[k]:=upcase(tstr[k]); { convert to all upper case }
- notfound:=TRUE;
- WHILE ((tcnt<=numdata) AND notfound) DO
- IF mdatastr[tcnt]^[1]<>'%' THEN
- tcnt:=tcnt+1
- ELSE
- BEGIN
- tstr3:=mdatastr[tcnt]^;
- FOR k:= 1 TO LENGTH(tstr3) DO
- tstr3[k]:=upcase(tstr3[k]); { convert to all upper case }
- notfound:=(POS(tstr,tstr3)=0);
- IF notfound THEN
- tcnt:=tcnt+1;
- END; { WHILE }
- IF tcnt>numdata THEN error(CONCAT('Invalid menu structure: > ',
- mdatastr[menus[menunum].strs[menus[menunum].num]+1]^));
- totmenu:=totmenu+1;
- menus[totmenu].strs[0]:=tcnt;
- menus[totmenu].num:=1;
-
- { strip location info from menu title}
- IF POS(',',mdatastr[menus[totmenu].strs[0]]^)<>0 THEN
- mdatastr[menus[totmenu].strs[0]]^:=
- COPY(mdatastr[menus[totmenu].strs[0]]^,
- 1,POS(',',mdatastr[menus[totmenu].strs[0]]^)-1);
- getsubs(totmenu);
- END; { is sub menu }
- menus[menunum].num:=menus[menunum].num+1;
- menus[menunum].strs[menus[menunum].num]:=cnt;
-
- cnt:=cnt+1; { was menu item and next item was de spaced }
- END; { IF valid item for menu }
- cnt:=cnt+1;
- END; { While cnt }
- menus[menunum].strs[menus[menunum].num]:=cnt;
- IF cnt=numdata THEN
- inc(menus[menunum].strs[menus[menunum].num]);
- menus[menunum].num:=menus[menunum].num-1;
- END; { getsubs }
-
- BEGIN { getinfo }
- ASSIGN(f,filestr); { let DOS try to find it }
- RESET(f);
- IF (IORESULT<>0) THEN
- BEGIN
- { 1.010 DOS could not find it, now check program directory }
- tstr:=paramstr(0); { get full path and program name }
- i:= LENGTH(tstr)+1;
- REPEAT
- i:= i-1;
- UNTIL (tstr[i]='\');
- tstr:= COPY(tstr,1,i); { now it is just the full path }
- tstr:= CONCAT(tstr,filestr);
- ASSIGN(f,tstr);
- RESET(f);
- IF (IORESULT<>0) THEN
- error(CONCAT('Unable to open menu file: > ',filestr));
- END;
- { read em all into mdatastr array }
- numdata:=1;
- REPEAT
- READLN(f,tstr);
- FOR i:= 1 TO LENGTH(tstr) DO
- IF (tstr[i]=CHR(09))OR
- (tstr[i]=CHR(175)) THEN { strip double arrow chr }
- { left over due to old menus }
- { that used it to indicate subs }
- tstr[i]:= CHR(32); { convert tab to 1 space }
- numdata:=numdata+1;
- { .711 did not handle lines of blanks correctly }
- IF POS(tstr,blanks)<>0 THEN { it is just blanks }
- numdata:= numdata-1
- ELSE
- BEGIN
- { ptrupdate
- get some space size of string }
-
- GETMEM(mdatastr[numdata-1],LENGTH(tstr)+2);
- mdatastr[numdata-1]^:=tstr;
-
- END; { add item }
-
- UNTIL EOF(f);
- numdata:=numdata-1;
- CLOSE(F);
- { 0.716 }
- { 0.800 }
- ctrlline:= (mdatastr[numdata]^[1]='!');
- escapeok:= TRUE;
- rpcok:= FALSE;
- logon:= FALSE;
- memoryon:= FALSE;
- IF ctrlline THEN
- BEGIN
- IF mdatastr[numdata]^='!' THEN
- escapeok:= FALSE
- { retain for old escape method '!' is no escape }
- ELSE
- escapeok:= (0=POS('!',mdatastr[numdata]^[2])); { !! is escape }
- rpcok:= (0<>POS('R',mdatastr[numdata]^)); { !R is do rpc }
-
- { 1.500 }
- logon:= (0<>POS('L',mdatastr[numdata]^)); { log program launches }
-
- { 1.520 }
- memoryon:= (0<>POS('M',mdatastr[numdata]^)); { menu remembers place }
-
- numdata:=numdata-1;
- END;
- menus[0].num:=1;
- menus[0].strs[0]:=1;
- IF (mdatastr[menus[0].strs[0]]^[1]<>'%') THEN
- error(CONCAT('First line must be menu: > ',mdatastr[menus[0].strs[0]]^));
-
- { strip % and location info from menu title}
- mdatastr[menus[0].strs[0]]^:= COPY(mdatastr[menus[0].strs[0]]^,2,
- LENGTH(mdatastr[menus[0].strs[0]]^));
- IF POS(',',mdatastr[menus[0].strs[0]]^)<>0 THEN
- mdatastr[menus[0].strs[0]]^:=COPY(mdatastr[menus[0].strs[0]]^,
- 1,POS(',',mdatastr[menus[0].strs[0]]^)-1);
- menus[0].strs[0]:=1;
- getsubs(0);
-
- FOR i:= 1 to numdata DO { strip leading % from all strings }
- IF mdatastr[i]^[1]='%' THEN
- mdatastr[i]^:= COPY(mdatastr[i]^,2,LENGTH(mdatastr[i]^)-1);
- FOR i:= 0 to totmenu DO
- BEGIN
- w:=1;
- { now put markers on end of items with submenus. }
- FOR k:= 0 TO menus[i].num DO
- w:=max(w,LENGTH(mdatastr[menus[i].strs[k]]^));
- FOR k:= 1 TO menus[i].num DO
- BEGIN
- IF menus[i].issub[k] THEN
- BEGIN
- tstr2:=mdatastr[menus[i].strs[k]]^;
- FREEMEM(mdatastr[menus[i].strs[k]],
- LENGTH(mdatastr[menus[i].strs[k]]^)+2);
- tstr2:=CONCAT(tstr2,COPY(blanks,1,w-LENGTH(tstr2)),' »');
- GETMEM(mdatastr[menus[i].strs[k]],LENGTH(tstr2)+2);
- mdatastr[menus[i].strs[k]]^:=tstr2;
- END; { is sub }
- END; { K }
- END; { I }
- END; { getinfo }
- {$I+ }
-
- PROCEDURE initalize;
- VAR
- i: INTEGER;
- s1: STRING;
-
- BEGIN { initalize }
- GETINTVEC(250,oldhelpvec);
- SETINTVEC(250,@help);
- helpon:= TRUE;
- delay(10);
-
- { .712 }
- reg.AH:= 01;
- reg.CH:= $20;
- reg.CL:= 08;
- INTR($10,reg); { Turn cursor off }
-
- { 0.713 }
- reg.AX:= 00;
- INTR($33,reg); { check for mouse and reset }
- hasmouse:= (reg.ax=$FFFF);
-
- { 0.714 }
- reg.AX:=$3000;
- INTR($21,reg); { get dos version }
- IF reg.AL<03 THEN
- error('Requires DOS version 3.00 or greater.');
-
- STR(reg.AL:1,dosverstr);
- STR(reg.AH:2,s1);
- FOR i:= 1 TO LENGTH(s1) DO
- IF s1[i]=' ' THEN
- s1[i]:='0';
- dosverstr:=CONCAT(dosverstr,'.',s1);
- { 0.715 } { find PSP and figure out this programs name. }
- reg.AH:=$62;
- INTR($21,reg);
- { reg.BX = segment of psp which is at offset 0 }
- { more needed to figure out the program name }
-
- clrscr;
- checkbreak := FALSE;
- IF lastmode=mono THEN
- textattr:=lightgray+black*16
- ELSE
- textattr := lightgray+blue * 16;
- RANDOMIZE;
- { get filename from command line or if none on cl then from env var MN }
- cl:= FALSE;
- IF paramcount<1 THEN
- filestr:=getenv('MN')
- ELSE
- BEGIN
- cl:= TRUE;
- filestr:= paramstr(1);
- END;
- { 1.520 }
- memorystr:= '';
- IF paramcount>1 THEN
- memorystr:= paramstr(2);
- outputmemorystr:= '';
-
- { now extend file if it dosent have an extension , use .MNU }
- IF (POS('.',filestr)=0)AND (filestr<>'') THEN
- filestr:=CONCAT(filestr,'.MNU');
- IF (filestr='') THEN
- filestr:= 'No MN environment';
-
- totmenu:=0;
- getinfo;
-
- { 0.729 }
- blankerstr:=CONCAT(' M C Menu Ver ',verstr,' ');
-
-
-
- END; { initalize }
-
-
- BEGIN { MCMenu }
-
- initalize;
- titlescreen;
- window(1,1,80,25);
- curhelp:='General';
- escaped:= FALSE;
-
- domainmenu;
-
- window(1,1,80,25);
- textbackground(black);
- textcolor(lightgray);
- clrscr;
- SETINTVEC(250,oldhelpvec);
-
- IF NOT escaped THEN
- BEGIN
- { now clear keyboard buffer }
- WHILE keypressed DO
- ch:=READKEY;
- stufkeyp(ORD(fnamechar));
- stufkeyp(13); { run batch (fnamechar).bat which runs mcmenu when done. }
- END; { NOT escaped }
- { .712 }
- textmode(lastmode); { turn cursor on }
- END . { MCMenu }