home *** CD-ROM | disk | FTP | other *** search
- { Turbo Menu program for IBM/IBM clones running MSDOS/PCDOS. This program
- implements a WANG PC style menu interface. This program can be not be
- sold or used commerically. You may give this program away for free to
- nayone who would like it as long as the source code is included.
-
- Gary Miller Perception Technology Corp.
- P.O. Box 176
- Waterford, NY 12188
-
- CompuServe ID [70127,3674]
-
- }
-
- Program Menu;
- {$C-,V-}
- {*Include File STRING.INC ***** START *****}
- {- Declare standard string types for function/procedure calling }
- {- sequence. }
-
- Type
- Str1=String[1]; { Turbo Pascal requires that }
- Str2=String[2]; { all parameters have a declared }
- Str3=String[3]; { type. Since strings of varying}
- Str4=String[4]; { length must have different type}
- Str5=String[5]; { this file exists to be included}
- Str6=String[6]; { to make sure that the string }
- Str7=String[7]; { types are declared. }
- Str8=String[8]; { .............................. }
- Str9=String[9]; { .............................. }
- Str10=String[10]; { .............................. }
- Str80=String[80]; { 80 char string }
- Str255=String[255]; { Maximum string }
-
-
- {*Include File End STRING.INC ***** END *****}
-
- Var
- Ok:Boolean;
- SwitchChar:Char;
- NormalCursor:Integer;
- NoCursor:Integer;
-
- {*Include File ATTKBD.CON ***** START *****}
-
- { ***************************************************************** }
- { ATT PC Keyboard definitions }
- { ***************************************************************** }
-
- Const
- RETURN_Key=#$0D;
- BACKSPACE_Key=#$08;
- ESCAPE_Key=#$1B;
- BEEP_Key=#$07;
- PREAMBLE_Key=#$00;
- PREAMBLE_Byte=$00;
- UP_Key=#$48;
- DOWN_Key=#$50;
- RIGHT_Key=#$4D;
- LEFT_Key=#$4B;
- HOME_Key=#$47;
- INSERT_Key=#$52;
- DELETE_Key=#$53;
- PageDwn_Key=#$51;
- PageUp_Key=#$49;
- END_Key=#$4F;
- TAB_Key=#$09;
- BACKTAB_Key=#$0F;
-
- CTRL_LEFT_Key=#$73;
- CTRL_RIGHT_Key=#$74;
- CTRL_END_Key=#$75;
- CTRL_PageDwn_Key=#$76;
- CTRL_HOME_Key=#$77;
- CTRL_PageUp_Key=#$84;
-
- SFKey01=#$3B;
- SFKey02=#$3C;
- SFKey03=#$3D;
- SFKey04=#$3E;
- SFKey05=#$3F;
- SFKey06=#$40;
- SFKey07=#$41;
- SFKey08=#$42;
- SFKey09=#$43;
- SFKey10=#$44;
-
- Shift_SFKey01=#$54;
- Shift_SFKey02=#$55;
- Shift_SFKey03=#$56;
- Shift_SFKey04=#$57;
- Shift_SFKey05=#$58;
- Shift_SFKey06=#$59;
- Shift_SFKey07=#$5A;
- Shift_SFKey08=#$5B;
- Shift_SFKey09=#$5C;
- Shift_SFKey10=#$5D;
-
- Alt_SFKey01=#$68;
- Alt_SFKey02=#$69;
- Alt_SFKey03=#$6A;
- Alt_SFKey04=#$6B;
- Alt_SFKey05=#$6C;
- Alt_SFKey06=#$6D;
- Alt_SFKey07=#$6E;
- Alt_SFKey08=#$6F;
- Alt_SFKey09=#$70;
- Alt_SFKey10=#$71;
-
- { ***************************************************************** }
-
-
- {*Include File End ATTKBD.CON ***** END *****}
- {*Include File CURSOR.INC ***** START *****}
- { Set Cursor Size : subfunction 01h of Intr 10h.
- The Documentation in the ATT Systems Programmers Guide did not
- describe what the actual call does, but after experimenting the
- meaning of start and end line is now clear.
- The cursor size in the ATT is saved at 0040:0060; and is lines 6 - 7.
-
- }
-
- Procedure CursorSize(NewCursor:Integer);
- { This procedure call the BIOS throught interrupt 10H to set
- the top and bottom line of the cursor. Scan Lines are
- hardware dependent so you will have to experiment to find
- what works on your system. }
-
- Type
- Register=Record Case Boolean Of
- True:(ax,bx,cx,dx,bp,si,di,ds,es,flags:Integer);
- False:(al,ah,bl,bh,cl,ch,dl,dh:Byte);
- End;
- Var
- Regs:Register;
-
- Begin
- With Regs Do
- Begin
- ah:=$01; {ah = 1 means set cursor type}
- bx:=$0; {bx = page number, zero for us}
- cx:=NewCursor; {ch bits 4 to 0 = start line for cursor}
- {*} {cl bits 4 to 0 = end line for cursor}
- cl:=(cl And $1F); {mask off all but low order 5 bits}
- ch:=(ch And $1F); {do the same for ch, in case of programmer}
- {*} {error. Can this happen? naw not a chance}
- Intr($10,Regs); {set cursor}
- End;
- End;
-
- Procedure ReadCursor(Var CurrentCursor:Integer);
- { This procedure call the BIOS throught interrupt 10H to read
- the top and bottom line of the cursor. }
-
- Type
- Register=Record Case Boolean Of
- True:(ax,bx,cx,dx,bp,si,di,ds,es,flags:Integer);
- False:(al,ah,bl,bh,cl,ch,dl,dh:Byte);
- End;
- Var
- Regs:Register;
-
- Begin
- With Regs Do
- Begin
- ah:=$03; {ah = 3 means read cursor }
- bx:=$0; {bx = page number, zero for us}
- Intr($10,Regs); {read cursor }
- CurrentCursor:=cx; {return current cursor lines }
- {*} {row and col are in dx }
- End;
- End;
-
- {*Include File End CURSOR.INC ***** END *****}
- {*Include File SCAN.INC ***** START *****}
- Function Read_Char(Var extend:Boolean):Char;
- Type
- Register=Record Case Boolean Of
- True:(ax,bx,cx,dx,bp,si,di,ds,es,flags:Integer);
- False:(al,ah,bl,bh,cl,ch,dl,dh:Byte);
- End;
- Var
- Regs:Register;
- Begin
- With Regs Do
- Begin
- ah:=$07;
- MsDos(Regs);
- If al=PREAMBLE_Byte Then
- Begin
- extend:=True;
- MsDos(Regs);
- End
- Else
- extend:=False;
- Read_Char:=Chr(al);
- End;
- End;
-
- {*Include File End SCAN.INC ***** END *****}
- {*Include File INPUTUTI.INC ***** START *****}
- Type
- CharSet=Set Of Char;
-
-
- { UpcaseStr converts a string to upper case }
-
- Function UpcaseStr(S:Str80):Str80;
- Var
- P:Integer;
- Begin
- For P:=1 To Length(S) Do
- S[P]:=UpCase(S[P]);
- UpcaseStr:=S;
- End;
-
- { ConstStr returns a string with N characters of value C }
-
- Function ConstStr(C:Char;N:Integer):Str80;
- Var
- S:String[80];
- Begin
- If N<0 Then
- N:=0;
- S[0]:=Chr(N);
- FillChar(S[1],N,C);
- ConstStr:=S;
- End;
-
- { Beep sounds the terminal bell or beeper }
-
- Procedure Beep;
- Begin
- Write(BEEP_Key);
- End;
-
-
- Procedure InputStr(Var S:Str255;
- L,x,y:Integer;
- Term:CharSet;
- Var TC:Char);
- Var
- P:Integer;
- ch:Char;
- Special:Boolean;
- InsertMode:Boolean;
- Begin
- NormVideo;
- If Length(S)>L Then
- S:=Copy(S,1,L);
- GoToXY(x,y);Write(S,ConstStr('_',L-Length(S)));
- InsertMode:=True;
- P:=0;
- Repeat
- GoToXY(x+P,y);ch:=Read_Char(Special);
- If Not Special Then
- Begin
- Case ch Of
- #32..#126:If P<L Then
- Begin
- Case InsertMode Of
- True:Begin
- If Length(S)=L Then
- Delete(S,L,1);
- P:=P+1;
- Insert(ch,S,P);
- Write(Copy(S,P,L));
- If P=L Then P:=P-1;
- End;
- False:Begin
- P:=P+1;
- If P<=Length(S) Then
- Delete(S,P,1);
- Insert(ch,S,P);
- Write(Copy(S,P,L));
- If P=L Then P:=P-1;
- End;
- End; { case Insert Mode }
- End;
-
- BACKSPACE_Key:If P>0 Then
- Begin
- Delete(S,P,1);
- Write(BACKSPACE_Key,Copy(S,P,L),'_':1);
- P:=P-1;
- End
- Else Beep;
- Else
- If Not(ch In Term) Then Beep;
- End; { of case }
- End
- Else
- Begin
- Case ch Of
- LEFT_Key:If P>0 Then
- P:=P-1
- Else Beep;
- RIGHT_Key:If P<Length(S) Then
- P:=P+1
- Else Beep;
- INSERT_Key:InsertMode:=Not InsertMode;
- HOME_Key:P:=0;
- END_Key:P:=Length(S);
- DELETE_Key:If P<Length(S) Then
- Begin
- Delete(S,P+1,1);
- Write(Copy(S,P+1,L),'_':1);
- End;
- CTRL_END_Key:Begin
- Write(ConstStr('_',Length(S)-P));
- Delete(S,P+1,L);
- End;
- Else
- Beep;
- End; {of case}
- End;
- Until ch In Term;
- P:=Length(S);
- GoToXY(x+P,y);
- If L>P Then Write(ConstStr('_',L-P));
- TC:=ch;
- LowVideo;
- End;
-
-
- Procedure Select(Prompt:Str80;
- Term:CharSet;
- Var TC:Char);
- Var
- ch:Char;
- Special:Boolean;
- Begin
- GoToXY(1,23);Write(Prompt,'? ');ClrEol;
- Repeat
- ch:=Read_Char(Special);
- TC:=UpCase(ch);
- If Not(TC In Term) Then
- Beep;
- Until TC In Term;
- Case ch Of
- #32..#126:Write(TC);
- End;
- End;
-
- Procedure ClearLines(F,L:Integer);
- Var
- I:Integer;
- Begin
- For I:=F To L Do
- Begin
- GoToXY(1,I);ClrEol;
- End;
- End;
-
-
- {*Include File End INPUTUTI.INC ***** END *****}
- {*Include File MESSAGE.INC ***** START *****}
- Procedure Message(S:Str80);
- Begin
- GoToXY(1,25);ClrEol;
- If Length(S)>0 Then
- Begin
- NormVideo;
- Write('ERROR: ',S);
- LowVideo;
- Beep;
- End;
- End;
-
- {*Include File End MESSAGE.INC ***** END *****}
- {*Include File BIOSDATE.INC ***** START *****}
- Type
- Bios=Record
- ax,bx,cx,dx,bp,si,di,ds,es,flags:Integer;
- End;
-
- BiosB=Record
- al,ah,bl,bh,cl,ch,dl,dh:Byte;
- End;
-
-
- Procedure GetDate(Var Year,Month,Day:Integer);
- Var
- Reg:Bios;
- RegB:BiosB Absolute Reg;
-
- Begin
- RegB.ah:=$2A;
- MsDos(Reg);
- Year:=Reg.cx;
- Month:=RegB.dh;
- Day:=RegB.dl;
- End;
-
- Procedure GetTime(Var Hrs,Min,Sec,HSec:Integer);
- Var
- Reg:Bios;
- RegB:BiosB Absolute Reg;
-
- Begin
- RegB.ah:=$2C;
- MsDos(Reg);
- Hrs:=RegB.ch;
- Min:=RegB.cl;
- Sec:=RegB.dh;
- HSec:=RegB.dl;
- End;
-
-
- {*Include File End BIOSDATE.INC ***** END *****}
- {*Include File GETSWITC.INC ***** START *****}
- { **************************************************************************
- WARNING ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING !
- -----------------------------------------------------------------------
-
- This function call is defined in the Program Development Guide on the
- WANG system. This function returns the switch character used by
- COMMAND.COM. On the WANG system this is '-', to try to make this
- program generic I used this call. In the IBM DOS Technical Ref 2.10
- this call was documented only by the line 'USED INTERNALLY'. If this
- does not work change this function to return your switch char which
- is probably '/' if you are on an IBM/IBM clone.
-
- }
-
- Function GetDOSswitch:Char;
- Type
- DosRegs=Record Case Integer Of
- 1:(ax,bx,cx,dx,bp,si,di,ds,es,flags:Integer);
- 2:(al,ah,bl,bh,cl,ch,dl,dh:Byte);
- End;
- Var
- Regs:DosRegs;
- Begin
- With Regs Do
- Begin
- ah:=$37;
- al:=0;
- End;
- MsDos(Regs);
- With Regs Do
- GetDOSswitch:=Chr(dl);
- End;
-
-
- {*Include File End GETSWITC.INC ***** END *****}
- {*Include File FILLZERO.INC ***** START *****}
- Procedure FillZero(Var S:Str255);
- Var
- I:Integer;
- Begin
- For I:=1 To Length(S) Do
- If S[I]=' ' Then
- S[I]:='0';
- End;
-
- {*Include File End FILLZERO.INC ***** END *****}
- {*Include File SPFUN.INC ***** START *****}
- { these routines use the MSDOS functions to get the date and time. The
- data is then converted into printable format. }
-
- Function CurrentDate:Str80;
- Var
- Month,
- Day,
- Year:Integer;
- S,T:Str255;
-
- Begin
- GetDate(Year,Month,Day);
- Str(Month:2,S);
- FillZero(S);
- T:=S+'/';
- Str(Day:2,S);
- FillZero(S);
- T:=T+S+'/';
- Str(Year,S);
- T:=T+S;
- CurrentDate:=T;
- End;
-
- Function Time:Str80;
- Var
- Hrs,
- Min,
- Sec,
- HSec:Integer;
- S,T:Str255;
-
- Begin
- GetTime(Hrs,Min,Sec,HSec);
- If Hrs>12 Then Str(Hrs-12:2,S)
- Else Str(Hrs:2,S);
- FillZero(S);
- T:=S+':';
- Str(Min:2,S);
- FillZero(S);
- T:=T+S+':';
- Str(Sec:2,S);
- FillZero(S);
- T:=T+S;
- If (Hrs=12) And (Min=0) Then T:=T+' M' Else
- If Hrs<12 Then T:=T+' AM' Else
- T:=T+' PM';
- Time:=T;
- End;
-
- {*Include File End SPFUN.INC ***** END *****}
- {*Include File EXEC16.INC ***** START *****}
- { EXEC.PAS version 1.6
- Copyright (C) 1986 by Bela Lubkin (1/21/86)
- Noncommercial use only EXCEPT with permission from Bela Lubkin; send
- EasyPlex to CompuServe ID 76703,3015 for permission.
-
- See "VERY IMPORTANT NOTES" below before using these functions. This is
- especially important if you are using Turbo version 1.0 or 2.0.
-
- Allows you to
- o Call MS-DOS programs
- o Get the return codes from those programs
- o Get strings from the MS-DOS environment
-
- Calling information
- -------------------
- Procedure FreeUpMemory;
- This procedure calls MS-DOS to free up memory that is not used by the
- running program. It is needed only under Turbo 1.0 or 2.0. It is
- commented out in this file. Uncomment it only if you are using a pre-
- 3.0 version of Turbo Pascal. It must be called once and ONLY ONCE
- before calling any of SubProcess, SubProcessViaCOMMAND, or Shell. It is
- a good idea to place this call early in the execution of the program.
-
- Function SubProcess(CommandLine: _Exec_Str255): Integer;
- Calls an executable image (.COM or .EXE file) using MS-DOS function
- 4Bh, Exec. The parameter CommandLine must contain both the name of the
- program to run and the arguments to be passed to it, seperated by a
- space. Path searching and other amenities are not performed; the passed
- in name must be specific enough to allow the file to be found, i.e.
- 'CHKDSK' will NOT work. At least 'CHKDSK.COM' must be specified, and a
- drive and path name will help even more. For example,
- 'C:\SYSTEM\CHKDSK.COM'
- 'A:\WS.COM DOCUMENT.1'
- 'C:\DOS\LINK.EXE TEST;'
- 'D:\ASSEM\MASM.EXE PROG1 PROG1.OBJ NUL PROG1.MAP'
- 'C:\COMMAND.COM /C COPY *.* B:\BACKUP >FILESCOP.IED'
- The last example uses COMMAND.COM to invoke a DOS internal command and
- to perform redirection. Only with the use of COMMAND.COM can the
- following be done: redirection; piping; path searching; searching for
- the extension of a program (.COM, .EXE, or .BAT); batch files; and
- internal DOS commands.
- Because the COMMAND-assisted Exec function is so useful, a seperate
- function, SubProcessViaCOMMAND, is provided for that purpose.
- The integer return value of SubProcess is the error value returned by
- DOS on completion of the Exec call. If it is nonzero, the call failed.
- Here is a list of likely error values:
- 0: Success
- 2: File/path not found
- 3: Path not found
- 4: Too many files open (no handles left)
- 5: Access denied
- 8: Not enough memory to load program
- 10: Illegal environment (greater than 32K)
- 11: Illegal .EXE file format
- 32: Sharing violation
- 33: Lock violation
- If you get any other result, consult an MS-DOS Technical Reference
- manual.
-
- Function GetEnvStr(SearchString: _Exec_Str255): _Exec_Str255;
- Gets a string from the MS-DOS environment. The parameter SearchString
- specifies the desired environment string. The function result returns
- the value of that string from the environment. If the string is not
- found, a null string is returned. SearchString may have one special
- value, '='. This returns garbage under MS-DOS 2.x. Under MS-DOS 3.x,
- it returns the pathname under which the currently running program was
- invoked. Examples:
- GetEnvStr('COMSPEC') might = 'C:\COMMAND.COM'
- GetEnvStr('PROMPT') might = '$p $g'
- GetEnvStr('REFLEX') might = 'Herc'
- GetEnvStr('=') might = 'C:\TURBO\exectest.COM'
- Only an exact match will succeed; case IS significant. Do not include
- an equal sign in the search string (GetEnvStr('COMSPEC=') will fail).
- Note: if you are wondering why there is no SetEnvStr procedure, read
- an MS-DOS Technical Reference manual.
-
- Function GetComSpec: _Exec_Str66;
- This is a special case of GetEnvStr and simply returns the COMSPEC
- environment string. It is included for compatability with previous
- EXEC.PAS versions.
-
- Function SubProcessViaCOMMAND(CommandLine: _Exec_Str255): Integer;
- This is a special case of SubProcess. The CommandLine is passed to
- COMMAND.COM, which does all further processing. Command lines invoked
- via this function can do redirection and piping; undergo the normal DOS
- PATH search; may be batch files; and may be internal DOS commands such
- as COPY and RENAME.
- Disadvantages of this approach are: a copy of COMMAND.COM must be
- present (not always true on a floppy-based system); a slight time and
- memory penalty is involved due to the loading of an extra copy of
- COMMAND.COM (about 3K under DOS 3.1); the subprocess return code
- (Errorlevel) is lost. In most cases the benefits will outweight the
- disadvantages.
- The integer return code is the same as for SubProcess.
- Note: you may be wondering why there is not
-
- Function Shell: Integer;
- This is a special case of SubProcess. It gives a DOS prompt to the
- user. Typing EXIT returns to the Turbo program. The integer return
- code is the same as for SubProcess.
-
- Function SubProcessReturnCode: Integer;
- This function calls MS-DOS function 4Dh, Get Return Code of a
- Sub-process. The integer return value is the return code set by the
- last subprocess you called. Like Turbo's IOResult, SubProcessReturnCode
- is only valid once after a SubProcess call, reverting to 0 on successive
- calls. The return code obtained after using SubProcessViaCOMMAND or
- Shell is the code returned by COMMAND.COM, not by any other program, and
- is not likely to be useful.
- Note: Turbo 3.0 programs can set the return code by using the Halt
- procedure with a parameter, e.g. Halt(20);. Other languages can call
- DOS function 4Ch (Terminate) with the return code in AL. Use Inline
- code or the MsDos procedure under Turbo 1.0 or 2.0.
-
- VERY IMPORTANT NOTES
- --------------------
- The Exec calls (SubProcess, SubProcessViaCOMMAND, Shell) will not work
- unless you restrict Turbo's heap. To do this, lower "mAximum dynamic free
- memory" on the compiler Options menu to a reasonable value. What is
- reasonable depends on your program's use of the heap and the stack, and must
- be determined by you. If you use neither the heap nor recursion, as low as
- 400h (16K bytes) is probably more than enough.
-
- The Exec calls CANNOT be called from within the interactive Turbo compiler
- system. They can only be called from .COM or .CHN files running outside of
- the Turbo environment.
-
- If you are using Turbo 1.0 or 2.0, you must call FreeUpMemory once and ONLY
- ONCE before making any calls to SubProcess, SubProcessViaCOMMAND, or Shell.
- Uncomment the FreeUpMemory procedure, remove the Exit statement from
- SubProcess, and make sure you call FreeUpMemory before attempting to do any
- Exec calls!!
-
- Revision history
- ----------------
- Version 1.6 1/21/86 re-adds support for Turbo 1.0, 2.0 by providing the
- procedure FreeUpMemory. Adds the Shell function that was
- inadvertantly left out of 1.5.
- Version 1.5 1/14/86 fixes the memory freeing bug by removing support for
- Turbo 2.0. String types changed to minimize chances of
- collision. General environment support added. Explicit calls
- for Exec-via-COMMAND.COM and Exec-to-DOS-prompt added. Support
- for getting the subprocess return code added. Major
- documentation overhaul. NOW REQUIRES TURBO 3.0!
- (Thanks to Stu Fuller 76703,501 for pointing out how easy it
- was to add full environment support).
- Version 1.4 attempts to fix a bug in the freeing of memory before the
- Exec call.
- Version 1.3 works with MS-DOS 2.0 and up, TURBO PASCAL version 1.0 and up.
- Version 1.2 had a subtle but dangerous bug: I set a variable that was
- addressed relative to BP, using a destroyed BP!
- Version 1.1 didn't work with Turbo 2.0 because I used Turbo 3.0 features
- Version 1.0 only worked with DOS 3.0 due to a subtle bug in DOS 2.x
-
- - Bela Lubkin
- CompuServe 76703,3015
- }
-
- Type
- _Exec_Str66=String[66];
- _Exec_Str255=String[255];
-
- Var
- _Exec_Regs:Record Case Integer Of
- 1:(ax,bx,cx,dx,bp,si,di,ds,es,flags:Integer);
- 2:(al,ah,bl,bh,cl,ch,dl,dh:Byte);
- End;
- { NOTE: the above variable is referenced in an Inline statement. It MUST
- be a global variable (not a local variable or a typed constant)!! }
-
- (* THIS PROCEDURE MUST BE CALLED ONCE AND ONLY ONCE, BEFORE ANY CALLS TO THE
- SUBPROCESS PROCEDURES, AND ONLY IF TURBO 1.0 OR 2.0 IS BEING USED!!!!!!!!
- Uncomment it only if necessary.
-
- Procedure FreeUpMemory;
- { Paraphrases part of Turbo 3.0's startup code:
- (CS:[101h]+106h) is the address of the compiler Options.
- Options[6] is the code segment size the program (paragraphs).
- Options[8] is the data segment size.
- (CS+Options[6]+Options[8]) is the highwater mark of the program, sans
- stack/heap.
- CS:[2] is supplied by DOS: the number of paragraphs available to the
- program.
- (CS:[2]-High water mark) is the number of paragraphs available to the
- stack/heap.
- Options[0Ch] is the maximum stack/heap size needed by the program.
- The heap size is taken as the lesser of Options[0Ch] and
- (CS:[2]-highwater mark).
- The highwater mark including the stack/heap is the no-heap highwater
- mark + the calculated heap size.
- The size in paragraphs of the program, including code, data, stack and
- heap, is the full highwater mark - the original CS.
- DOS function 4Ah, Set memory block, is called to adjust the size of the
- program's memory block to the calculated size of the entire program. }
- Begin
- InLine(
- $2E/$8B/$36/$01/$01/ { ADD SI,106h }
- $81/$C6/$06/$01/ { ADD SI,106h }
- $8C/$CB/ { MOV BX,CS }
- $2E/$03/$5C/$06/ { ADD BX,CS:[SI+6] }
- $2E/$03/$5C/$08/ { ADD BX,CS:[SI+8] }
- $2E/$8B/$16/$02/$00/ { MOV DX,CS:[2] }
- $29/$DA/ { SUB DX,BX }
- $2E/$3B/$54/$0C/ { CMP DX,CS:[SI+0Ch] }
- $72/$04/ { JB .1 }
- $2E/$8B/$54/$0C/ { MOV DX,CS:[SI+0Ch] }
- $8C/$C8/ { .1: MOV AX,CS }
- $8E/$C0/ { MOV ES,AX }
- $01/$D3/ { ADD BX,DX }
- $2B/$D8/ { SUB BX,AX }
- $B4/$4A/ { MOV AH,4Ah }
- $CD/$21); { INT 21h }
- End; *)
-
- Function SubProcess(CommandLine:_Exec_Str255):Integer;
- Const
- SSSave:Integer=0;
- SPSave:Integer=0;
-
- Var
- FCB1,FCB2:Array[0..36] Of Byte; {*}
- PathName:_Exec_Str66; {*}
- CommandTail:_Exec_Str255;
- ParmTable:Record {*}
- EnvSeg:Integer;
- ComLin:^Integer;
- FCB1Pr:^Integer;
- FCB2Pr:^Integer;
- End;
- RegsFlags:Integer; {*}
- {*: these variables are accessed in an Inline statement; their
- declarations must not be changed }
-
- Begin
- If Pos(' ',CommandLine)=0 Then
- Begin
- PathName:=CommandLine+#0;
- CommandTail:=^M;
- End
- Else
- Begin
- PathName:=Copy(CommandLine,1,Pred(Pos(' ',CommandLine)))+#0;
- CommandTail:=Copy(CommandLine,Pos(' ',CommandLine),255)+^M;
- End;
- CommandTail[0]:=Pred(CommandTail[0]);
- With _Exec_Regs Do
- Begin
- FillChar(FCB1,SizeOf(FCB1),0);
- ax:=$2901;
- ds:=Seg(CommandTail[1]);
- si:=Ofs(CommandTail[1]);
- es:=Seg(FCB1);
- di:=Ofs(FCB1);
- MsDos(_Exec_Regs); { Create FCB 1 }
- FillChar(FCB2,SizeOf(FCB2),0);
- ax:=$2901;
- es:=Seg(FCB2);
- di:=Ofs(FCB2);
- MsDos(_Exec_Regs); { Create FCB 2 }
- With ParmTable Do
- Begin
- EnvSeg:=MemW[CSeg:$002C];
- ComLin:=Addr(CommandTail);
- FCB1Pr:=Addr(FCB1);
- FCB2Pr:=Addr(FCB2);
- End;
- Inline($8D/$96/PathName/$42/ { <DX>:=Ofs(PathName[1]); }
- $8D/$9E/ParmTable/ { <BX>:=Ofs(ParmTable); }
- $B8/$00/$4B/ { <AX>:=$4B00; }
- $1E/$55/ { Save <DS>, <BP> }
- $16/$1F/ { <DS>:=Seg(PathName[1]); }
- $16/$07/ { <ES>:=Seg(ParmTable); }
- $2E/$8C/$16/SSSave/ { Save <SS> in SSSave }
- $2E/$89/$26/SPSave/ { Save <SP> in SPSave }
- $FA/ { Disable interrupts }
- $CD/$21/ { Call MS-DOS }
- $FA/ { Disable interrupts }
- $2E/$8B/$26/SPSave/ { Restore <SP> }
- $2E/$8E/$16/SSSave/ { Restore <SS> }
- $FB/ { Enable interrupts }
- $5D/$1F/ { Restore <BP>,<DS> }
- $9C/$8F/$86/RegsFlags/ { Flags:=<CPU flags> }
- $A3/_Exec_Regs); { _Exec_Regs.AX:=<AX>; }
- { The messing around with SS and SP is necessary because under DOS 2.x,
- after returning from an EXEC call, ALL registers are destroyed except
- CS and IP! I wish I'd known that before I released this package the
- first time... }
- If (RegsFlags And 1)<>0 Then SubProcess:=ax
- Else SubProcess:=0;
- End;
- Exit; { This line is here for one reason only: to cause compilation to
- fail under Turbo 1.0 or 2.0 and force you to read this comment.
- Go back and read the VERY IMPORTANT NOTES section. Then comment
- out this Exit, uncomment Procedure FreeUpMemory, and add a call to
- it to your code before attempting any calls to any of the Exec
- functions!! }
- End;
-
- Function GetEnvStr(SearchString:_Exec_Str255):_Exec_Str255;
- Type
- Env=Array[0..32767] Of Char;
- Var
- EPtr:^Env;
- EStr:_Exec_Str255;
- Done:Boolean;
- I:Integer;
-
- Begin
- GetEnvStr:='';
- If SearchString<>'' Then
- Begin
- EPtr:=Ptr(MemW[CSeg:$002C],0);
- I:=0;
- SearchString:=SearchString+'=';
- Done:=False;
- EStr:='';
- Repeat
- If EPtr^[I]=#0 Then
- Begin
- If EPtr^[Succ(I)]=#0 Then
- Begin
- Done:=True;
- If SearchString='==' Then
- Begin
- EStr:='';
- I:=I+4;
- While EPtr^[I]<>#0 Do
- Begin
- EStr:=EStr+EPtr^[I];
- I:=Succ(I);
- End;
- GetEnvStr:=EStr;
- End;
- End;
- If Copy(EStr,1,Length(SearchString))=SearchString Then
- Begin
- GetEnvStr:=Copy(EStr,Succ(Length(SearchString)),255);
- Done:=True;
- End;
- EStr:='';
- End
- Else EStr:=EStr+EPtr^[I];
- I:=Succ(I);
- Until Done;
- End;
- End;
-
- Function GetComSpec:_Exec_Str66;
- Begin
- GetComSpec:=GetEnvStr('COMSPEC');
- End;
-
- Function SubProcessViaCOMMAND(CommandLine:_Exec_Str255):Integer;
- Begin
- SubProcessViaCOMMAND:=SubProcess(GetComSpec+' /C '+CommandLine);
- End;
-
- Function Shell:Integer;
- Begin
- Shell:=SubProcess(GetComSpec);
- End;
-
- Function SubProcessReturnCode:Integer;
- Begin
- _Exec_Regs.ah:=$4D;
- MsDos(_Exec_Regs);
- SubProcessReturnCode:=_Exec_Regs.ax;
- End;
-
-
- {*Include File End EXEC16.INC ***** END *****}
- {*Include File SRCHPATH.INC ***** START *****}
- { File PATH.INC from DL1 of Borland SIG. Author is Jack Zucker }
-
- (*
- ZDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD?
- 3 This function returns substring n based on a string of data delimited by a 3
- 3 particular character of your choice. 3
- 3 Arguments: 3
- 3 A : Your string of data with delimiters 3
- 3 Delimiter : Your choice of character to use as a delimiter 3
- 3 Piece : The number of the "piece" in the string to return 3
- 3 RestOfStr : If True it returns the "piece" Piece through the end of the 3
- 3 str. If false the function returns just the "piece" piece 3
- 3 you asked for. 3
- 3 Ex. : S := 'Jack Zucker;10318 Broom Lane;Seabrook;Md;20706' 3
- 3 GetPiece(S,';',3,False) would return 'Seabrook' 3
- @DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDY
- *)
-
- Function GetPiece(A:Str255;Delimiter:Char;Piece:Byte;
- RestOfStr:Boolean):Str255;
- Var
- Temp:Str255;
- I,J:Integer;
- ch:Char;
-
- Begin
- J:=1;
- I:=1;
- Temp:=A;
- While (I<Length(A)+1) And (J<Piece) Do Begin
- If A[I]=Delimiter Then
- Begin
- Temp:=Copy(A,I+1,255);
- J:=J+1;
- End;
- I:=I+1;
- End;
- I:=Pos(Delimiter,Temp);
- If J=Piece Then
- Begin
- If I>0 Then If RestOfStr Then GetPiece:=Temp
- Else GetPiece:=Copy(Temp,1,I-1)
- Else If Temp<>A Then GetPiece:=Temp;
- End
- Else GetPiece:='';
- If (Pos(Delimiter,A)=0) And (Piece=1) Then GetPiece:=A;
- End;
-
- (*
- ZDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD?
- 3This routine gets the current path. It returns a string with all the paths 3
- 3and it's your job to do something with them. It is the copy of the dos path 3
- 3so see your dos manual if you have any questions about paths. 3
- 3The function is of the type Str255 which fits any string and is declared as 3
- 3Str255 = String[255]; 3
- @DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDY
- *)
-
- Function GetPath:Str255;
- Var
- P:^Byte;
- S:Str255;
- I:Integer;
- Begin
- P:=Ptr(MemW[CSeg:$2C],0); { Point to the Dos Comspec }
- Move(P^,S[1],255); { Move it to the string S }
- S[0]:=#$FF;
- I:=Pos('PATH=',S);
- If I=0 Then GetPath:=''
- Else
- Begin
- S:=Copy(S,I+5,$FF); { Move String[1] past the word "PATH=" }
- S:=Copy(S,1,Pos(#0,S)-1); { Dos uses Null char to terminate Strings}
- GetPath:=S;
- End;
- End;
-
- (*
- ZDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD?
- 3This function will find a file by looking through all the dos path specs 3
- 3until it either finds the file or the paths are exhausted. It will return 3
- 3either the path that the file is found in or '' if the file is not in any 3
- 3of the dos paths. It calls the routine getpath which reads in the dos path. 3
- 3It takes as it's argument, the name of the file for which it is looking. 3
- @DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDY
- *)
-
- Function FindFile(FName:Str255):Str255;
- Var
- I:Byte;
- Fd:File;
- FullPath,
- Path:Str255;
- Begin
- I:=0;
- FullPath:=GetPath;
- GetDir(0,Path);
- While Path<>'' Do
- Begin
- If Not(Path[Length(Path)]='\') Then
- Path:=Path+'\';
- Assign(Fd,Path+FName);
- {$I-}
- Reset(Fd);
- {$I+}
- If IOResult=0 Then
- Begin
- FindFile:=Path;
- Close(Fd);
- Exit;
- End
- Else
- Begin
- Close(Fd);
- I:=I+1;
- Path:=GetPiece(FullPath,';',I,False);
- End;
- End;
- FindFile:='';
- End;
-
- {*Include File End SRCHPATH.INC ***** END *****}
- {*Include File CURDRIVE.INC ***** START *****}
- Procedure CurrentDrive(Var S:Str2);
- Type
- DosRegs=Record Case Integer Of
- 1:(ax,bx,cx,dx,bp,si,di,ds,es,flags:Integer);
- 2:(al,ah,bl,bh,cl,ch,dl,dh:Byte);
- End;
- Var
- Regs:DosRegs;
- Begin
- Regs.ah:=$19; { Current Disk function code }
- MsDos(Regs); { do it , close your eyes }
- S:=Chr(Ord('A')+Regs.al)+':'; { Generate drive designation }
- End;
-
-
- {*Include File End CURDRIVE.INC ***** END *****}
- {*Include File MENUTYPE.INC ***** START *****}
- Type
- bytechar=Record Case Boolean Of
- True:(C:Char);
- False:(b:Byte);
- End;
- MenuPointer=^MenuBuffer;
- MenuBuffer=Record
- Buf:Array[1..5,0..255] Of bytechar;
- End;
- HelpPointer=^HelpBuffer;
- HelpBuffer=Record
- Buf:Array[1..187,0..255] Of bytechar;
- End;
-
- ByteFile=File;
-
- Const
- Special:Set Of Char=[#$09,#$08,#$0D,#$20,ESCAPE_Key];
-
- Var
- HBuffer:HelpBuffer;
- MBuffer:MenuBuffer;
- FilVar:ByteFile;
-
- {*Include File End MENUTYPE.INC ***** END *****}
- {*Include File HANDLE.INC ***** START *****}
- { The Following functions were written to take care of the ReadBlock
- bug in Turbo V3.0. The FileHandle function returns the MSDOS file
- handle to be used in reading from a file. The DosBlockRead function
- will attempt to read Recs number of bytes from a file with handle
- FileH. If no error occurs then the number of bytes read will be
- return in Result, otherwise Result will be -1.
-
- Gary W. Miller
- 70127,3674 Compuserve
-
- }
-
- Function FileHandle(Var FilVar):Integer;
- Var
- H:Integer Absolute FilVar;
- Begin
- FileHandle:=H;
- End;
-
-
- Procedure DosBlockRead(FileH:Integer;Var buffer;Recs:Integer;Var Result:Integer);
- Type
- DosRegs=Record Case Integer Of
- 1:(ax,bx,cx,dx,bp,si,di,ds,es,flags:Integer);
- 2:(al,ah,bl,bh,cl,ch,dl,dh:Byte);
- End;
- Var
- Regs:DosRegs;
- Begin
- With Regs Do
- Begin
- ds:=Seg(buffer); { location of Buffer segment }
- dx:=Ofs(buffer); { offset }
- cx:=Recs; { number of bytes to read }
- ah:=$3f; { Read File or Device Code }
- bx:=FileH; { Pass file handle }
- End;
- MsDos(Regs); { do it , close your eyes }
- With Regs Do
- Begin
- If (flags And 1)<>0 Then
- Result:=-1 { crap, we blew it }
- Else
- Result:=ax; { tell me what you read }
- End;
- End;
-
-
- Procedure DosBlockWrite(FileH:Integer;Var buffer;Recs:Integer;Var Result:Integer);
- Type
- DosRegs=Record Case Integer Of
- 1:(ax,bx,cx,dx,bp,si,di,ds,es,flags:Integer);
- 2:(al,ah,bl,bh,cl,ch,dl,dh:Byte);
- End;
- Var
- Regs:DosRegs;
- Begin
- With Regs Do
- Begin
- ds:=Seg(buffer); { location of Buffer segment }
- dx:=Ofs(buffer); { offset }
- cx:=Recs; { number of bytes to write }
- ah:=$40; { Write File or Device Code }
- bx:=FileH; { Pass file handle }
- End;
- MsDos(Regs); { do it , close your eyes }
- With Regs Do
- Begin
- If (flags And 1)<>0 Then
- Result:=-1 { crap, we blew it }
- Else
- Result:=ax; { tell me what you wrote }
- End;
- End;
-
-
- {*Include File End HANDLE.INC ***** END *****}
- {*Include File CHGDIR.INC ***** START *****}
- { This procedure changes the current logged directory or drive based
- on the string passed. To change the logged drive pass this function
- the drive you wish to change to. To change directory pass the complete
- path name of the directory to change to. If any error occurs while
- making the change an error flag will be returned. }
-
- Procedure CurrentDirectory(Var S:Str255);
- Begin
- GetDir(0,S);
- S:=Copy(S,Pos(':',S)+1,Length(S));
- End;
-
- Procedure ChangeDir(S:Str255;Var Ok:Boolean);
- Begin
- {$I-}
- ChDir(S);
- {$I+}
- Ok:=(IOResult=0);
- End;
-
- { This procedure makes the rather rash assumtion that what ever path you
- pass it exists. If it does not exist then the function will return
- without doing anything. }
-
- Procedure ReturnToPath(S:Str255);
- Var
- Ok:Boolean;
-
- Begin
- ChangeDir(S,Ok);
- End;
-
- {*Include File End CHGDIR.INC ***** END *****}
-
- {*Include File MENUPROC.INC ***** START *****}
- Procedure Display(Var buffer);
- Type
- LineRec=Record
- y:Byte;
- x:Byte;
- txt:String[255];
- End;
-
- Var
- MenuLine:LineRec Absolute buffer;
- I:Integer;
- flag:Boolean;
- Begin
- With MenuLine Do
- Begin
- If x=$FF Then
- Begin
- I:=1;
- While txt[I]<>#03 Do
- I:=I+1;
- x:=40-((I) Shr 1);
- End;
- GoToXY(x,y+1);
- If txt[0]=Chr(2) Then
- Begin
- I:=1;
- flag:=True;
- While txt[I]<>#03 Do
- Begin
- If flag And (txt[I]>#$20) Then
- flag:=False;
- I:=I+1;
- End;
- If Not flag Then
- txt[0]:=Chr(I-1)
- Else
- txt[0]:=Chr(0);
- End;
- If Length(txt)>0 Then
- Write(txt);
- End;
- End;
-
- Procedure Entry(I:Integer;Var b,o:Byte;Var buffer);
- Type
- OffRec=Record
- offset:Byte;
- blk:Byte;
- End;
- OffTable=Array[0..52] Of OffRec;
- Var
- table:OffTable Absolute buffer;
- Begin
- With table[I] Do
- Begin
- b:=blk;
- o:=offset;
- End;
- End;
-
- Procedure RunInfo(Var buffer;
- Var FName:Str80;
- Var Path:Str80;
- Var Drive:Str80;
- Var ParmStr:Str80;
- Var flag:Byte;
- Var help:Byte);
- Type
- RunRec=Record
- pflag:Byte;
- phelp:Byte;
- junk:Byte;
- pdisk:Byte;
- ptxt:Array[1..255] Of Char;
- End;
- Var
- prec:RunRec Absolute buffer;
- F,T:Integer;
- k,P:Integer;
- I:Integer;
- Begin
- With prec Do
- Begin
- flag:=pflag;
- help:=phelp;
- If pdisk=0 Then
- FName:=''
- Else
- FName:=Chr($40+pdisk)+':';
- Drive:=FName;
- Path:='';
- F:=Length(Path);
- k:=1;
- If (ptxt[k]='/') Or (ptxt[k]='\') Then
- Begin
- Repeat
- F:=F+1;
- Path[F]:=ptxt[k];
- k:=k+1;
- Until ptxt[k]=#$20;
- k:=k+1;
- Path[0]:=Chr(F-1);
- End;
- F:=Length(FName);
- P:=k+8;
- T:=0;
- For I:=k To k+10 Do
- Begin
- If ptxt[I]<>#$20 Then
- Begin
- If (I>=P) And (T=0) Then
- Begin
- T:=1;
- F:=F+1;
- FName[F]:='.';
- End;
- F:=F+1;
- FName[F]:=ptxt[I];
- End;
- End;
- FName[0]:=Chr(F);
- ParmStr:='';
- k:=0;
- I:=I+1;
- While ptxt[I]<>#$03 Do
- Begin
- k:=k+1;
- ParmStr[k]:=ptxt[I];
- I:=I+1;
- End;
- ParmStr[0]:=Chr(k);
- End;
- End;
-
-
- {*Include File End MENUPROC.INC ***** END *****}
- {*Include File DISPHELP.INC ***** START *****}
- Procedure DisplayHelp(I:Byte;Var HBuffer:HelpBuffer);
- Var
- k,L:Integer;
- b,o:Byte;
- T:Char;
- Begin
- ClrScr;
- LowVideo;
- L:=1+(I-1)*22;
- For k:=L To L+21 Do
- Begin
- Entry(k,b,o,HBuffer);
- Display(HBuffer.Buf[b,o]);
- End;
- NormVideo;
- GoToXY(1,24);Write('Press Any Key to Return');
- LowVideo;
- Read(Kbd,T);
- ClrScr;
- End;
-
- {*Include File End DISPHELP.INC ***** END *****}
- {*Include File DISPMENU.INC ***** START *****}
- Procedure DisplayMenu(UserSel:Integer;Var MBuffer:MenuBuffer);
- Var
- k:Integer;
- L:Integer;
- b,o:Byte;
- Begin
- ClrScr;
- NormVideo;
- GoToXY(5,5);Write('Select and then Proceed:');
- LowVideo;
- For k:=1 To 3 Do
- Begin
- Entry(k,b,o,MBuffer);
- Display(MBuffer.Buf[b,o]);
- End;
- Entry(0,b,o,MBuffer);
- L:=MBuffer.Buf[b,o+1].b-1;
- For k:=0 To L Do
- Begin
- If k=UserSel Then
- NormVideo
- Else
- LowVideo;
- Entry(k+4,b,o,MBuffer);
- Display(MBuffer.Buf[b,o]);
- LowVideo;
- End;
- GoToXY(50,21);Write('RETURN - Proceed');
- GoToXY(50,22);Write('TAB - Help');
- GoToXY(50,23);Write('SPACE - Select');
- GoToXY(50,24);Write('ESCAPE - Previous Menu');
- End;
-
- Procedure HighLight(Var Old:Byte;New:Byte;MBuffer:MenuBuffer);
- Var
- b,o:Byte;
- Begin
- LowVideo;
- Entry(Old+4,b,o,MBuffer);
- Display(MBuffer.Buf[b,o]);
- NormVideo;
- Old:=New;
- Entry(Old+4,b,o,MBuffer);
- Display(MBuffer.Buf[b,o]);
- LowVideo;
- End;
-
- Procedure ReadMenu(Var FName:Str80;Var Good:Boolean);
- Var
- k:Integer;
- FilVar:ByteFile;
- Result:Integer;
- Path:Str255;
-
- Begin
- Path:=FindFile(FName);
- Assign(FilVar,Path+FName);
- {$I-}Reset(FilVar); {$I+}
- Good:=(IOResult=0);
- If Good Then
- Begin
- k:=1;
- Repeat
- With MBuffer Do
- DosBlockRead(FileHandle(FilVar),Buf[k],4096,Result);
- k:=k+16;
- Until Result=0;
- Close(FilVar);
- End;
- End;
-
- Procedure ReadHelp(Var FName:Str80;Var Good:Boolean);
- Var
- k:Integer;
- FilVar:ByteFile;
- Result:Integer;
- Path:Str255;
-
- Begin
- Path:=FindFile(FName);
- Assign(FilVar,Path+FName);
- {$I-}Reset(FilVar); {$I+}
- Good:=(IOResult=0);
- If Good Then
- Begin
- k:=1;
- Repeat
- With HBuffer Do
- DosBlockRead(FileHandle(FilVar),Buf[k],4096,Result);
- k:=k+16;
- Until Result=0;
- Close(FilVar);
- End;
- End;
-
- Procedure Menu(FName,Path,Drive:Str80;Var Ok:Boolean);
- Var
- OkDir,
- HelpCheck,
- MenuOk,
- HelpAvailable:Boolean;
- UserSel:Byte;
- T,TC:Char;
- CDrive:Str2;
- CurrentDir:String[80];
- L:Byte;
- FirstLetter:String[24];
- b,o:Byte;
- k:Byte;
- HFname,
- Rname,
- Rpath,
- Rdrive,
- Rparm:Str80;
- Rflag,
- Rhelp:Byte;
- R:Integer;
- Begin
- Ok:=True;
- CurrentDirectory(CurrentDir);
- CurrentDrive(CDrive);
- If Length(Drive)>0 Then
- ChangeDir(Drive,Ok)
- Else
- Drive:=CDrive;
- If (Length(Path)>0) And Ok Then
- ChangeDir(Path,Ok)
- Else
- Path:=CurrentDir;
- If Ok Then ReadMenu(FName,Ok);
- HFname:=Copy(FName,1,Pos('.',FName))+'hlp';
- HelpCheck:=False;
- If Ok Then
- Begin
- Entry(0,b,o,MBuffer);
- L:=MBuffer.Buf[b,o+1].b;
- For k:=4 To L+3 Do
- Begin
- Entry(k,b,o,MBuffer);
- FirstLetter[k-3]:=MBuffer.Buf[b,o+3].C;
- End;
- FirstLetter[0]:=Chr(L);
- UserSel:=0;
- DisplayMenu(UserSel,MBuffer);
- T:=#0;
- Repeat
- If KeyPressed Then
- Begin
- Read(Kbd,T);
- T:=UpCase(T);
- Message('');
- If (T In Special) Then
- Case T Of
- RETURN_Key:Begin
- Entry(UserSel+4+L,b,o,MBuffer);
- RunInfo(MBuffer.Buf[b,o],Rname,Rpath,Rdrive,Rparm,Rflag,Rhelp);
- If Rflag=0 Then
- Begin
- Menu(Rname,Rpath,Rdrive,MenuOk);
- If MenuOk Then
- Begin
- ReadHelp(HFname,HelpAvailable);
- ReadMenu(FName,Ok);
- DisplayMenu(UserSel,MBuffer);
- End
- Else
- Message('Unable to access Menu '+Rname);
- End
- Else
- If (Rflag=1) Or (Rflag=3) Then
- Begin
- OkDir:=True;
- If Length(Rdrive)>0 Then
- ChangeDir(Rdrive,OkDir);
- If (Length(Rpath)>0) And OkDir Then
- ChangeDir(Rpath,OkDir);
- ClrScr;
- CursorSize(NormalCursor);
- If OkDir Then
- R:=SubProcess(GetComSpec+' '+
- SwitchChar+'C '+Rname+' '+
- Rparm)
- Else
- R:=1;
- CursorSize(NoCursor);
- If (R=0) And (Rflag=3) Then
- Begin
- NormVideo;GoToXY(1,25);ClrEol;
- Write('Press any Key to Return to Menu');
- Read(Kbd,T);
- LowVideo;
- End;
- ReturnToPath(Drive+Path);
- DisplayMenu(UserSel,MBuffer);
- If R<>0 Then
- Begin
- If OkDir Then
- Message('Unable to run '+Rname)
- Else
- Message('Unable to find '+Rdrive+Rpath);
- End;
- End
- Else
- If Rflag=2 Then
- Begin
- GoToXY(5,5);ClrEol;LowVideo;
- Write('File Spec: ');
- NormVideo;
- CursorSize(NormalCursor);
- Rname:='';
- InputStr(Rname,60,17,5,[RETURN_Key,ESCAPE_Key],TC);
- LowVideo;
- If (Length(Rname)>0) And (TC=RETURN_Key) Then
- Begin
- ClrScr;
- R:=SubProcess(GetComSpec+' '+SwitchChar+'C '+Rname);
- CursorSize(NoCursor);
- If (R=0) Then
- Begin
- NormVideo;GoToXY(1,25);ClrEol;
- Write('Press any Key to Return to Menu');
- Read(Kbd,T);
- LowVideo;
- End;
- ReturnToPath(Drive+Path);
- DisplayMenu(UserSel,MBuffer);
- If R<>0 Then
- Message('Unable to run '+Rname);
- End
- Else
- Begin
- CursorSize(NoCursor);
- DisplayMenu(UserSel,MBuffer)
- End;
- End
- Else
- If Rflag=4 Then
- Begin
- CursorSize(NormalCursor);
- ClrScr;
- NormVideo;
- WriteLn('Type EXIT to return to the Menu');
- LowVideo;
- R:=SubProcess(GetComSpec);
- ReturnToPath(Drive+Path);
- CursorSize(NoCursor);
- If R=0 Then
- DisplayMenu(UserSel,MBuffer)
- Else
- Message('Unable to run '+Rname);
- End
- Else
- If Rflag=5 Then
- Begin
- OkDir:=True;
- If Length(Rdrive)>0 Then
- ChangeDir(Rdrive,OkDir);
- If (Length(Rpath)>0) And OkDir Then
- ChangeDir(Rpath,OkDir);
- CursorSize(NormalCursor);
- LowVideo;
- ClrScr;
- If OkDir Then
- R:=SubProcess(GetComSpec+' '+SwitchChar+'C '+Rname)
- Else
- R:=1;
- CursorSize(NoCursor);
- ReturnToPath(Drive+Path);
- If (R=0) Then
- Begin
- NormVideo;GoToXY(1,25);ClrEol;
- Write('Press any Key to Return to Menu');
- Read(Kbd,T);
- LowVideo;
- End;
- DisplayMenu(UserSel,MBuffer);
- If R<>0 Then
- Begin
- If OkDir Then
- Message('Unable to run '+Rname)
- Else
- Message('Unable to find '+Rdrive+Rpath);
- End;
- End
- Else
- Beep;
- End;
-
- TAB_Key:Begin
- Entry(UserSel+4+L,b,o,MBuffer);
- RunInfo(MBuffer.Buf[b,o],Rname,Rpath,Rdrive,Rparm,Rflag,Rhelp);
- If Rhelp=0 Then
- Begin
- Beep;
- Message('Help not available');
- End
- Else
- Begin
- If Not HelpCheck Then
- ReadHelp(HFname,HelpAvailable);
- HelpCheck:=True;
- If HelpAvailable Then
- Begin
- DisplayHelp(Rhelp,HBuffer);
- DisplayMenu(UserSel,MBuffer);
- End
- Else
- Begin
- Beep;
- Message('Help not available');
- End;
- End;
- End;
-
- #$20:Begin
- k:=(UserSel+1) Mod L;
- HighLight(UserSel,k,MBuffer);
- End;
-
- BACKSPACE_Key:Begin
- If k>0 Then
- k:=UserSel-1
- Else
- k:=L-1;
- HighLight(UserSel,k,MBuffer);
- End;
- End
- Else
- If Pos(T,FirstLetter)<>0 Then
- Begin
- k:=Pos(T,Copy(FirstLetter,UserSel+2,L));
- If k=0 Then
- k:=Pos(T,Copy(FirstLetter,1,UserSel))
- Else
- k:=k+UserSel+1;
- If k=0 Then
- Beep
- Else
- HighLight(UserSel,k-1,MBuffer);
- End
- Else
- Beep;
- End;
- GoToXY(1,1);Write(Time);
- GoToXY(71,1);Write(CurrentDate);
- Until T=ESCAPE_Key;
- End;
- ReturnToPath(CDrive+CurrentDir);
- End;
-
-
-
- {*Include File End DISPMENU.INC ***** END *****}
-
- Begin
- NoCursor:=$1f1f;
- ReadCursor(NormalCursor);
- SwitchChar:=GetDOSswitch;
- CursorSize(NoCursor);
- (* REPEAT *)
- Menu('menu.dat','','',Ok);
- (* UNTIL NOT Ok; *)
- CursorSize(NormalCursor);
- End.