Contributor: SWAG SUPPORT TEAM 
unit MiscLib;
interface
uses crt,dos;
const
 MaxFiles = 30;
 MaxChoices = 8;
type
 STRING79 = string[79];
 TOGGLE_REC = record
 NUM_CHOICES: integer;
 STRINGS : array [0..8] of STRING79;
 LOCATIONS : array [0..8] of integer;
 end;
 RESPONSE_TYPE = (NO_RESPONSE, ARROW, KEYBOARD, RETURN);
 MOVEMENT = (NONE, LEFT, RIGHT, UP, DOWN);
 FnameType = string[12];
 FileListType = array[1..MaxFiles] of FnameType;
 ScrMenuRec = record
 Selection : array[1..MaxChoices] of STRING79;
 Descripts : array[1..MaxChoices,1..3] of STRING79;
 end;
 ScrMenuType = object
 NumChoices : integer;
 Last : integer;
 Line, Col : integer;
 MenuData : ScrMenuRec;
 procedure Setup(MData: ScrMenuRec);
 function GetChoice : integer;
 end;
procedure Set_Video (ATTRIBUTE: integer);
procedure Put_String (OUT_STRING: STRING79; LINE, COL, ATTRIB: integer);
procedure Put_Text (OUT_STRING: STRING79; LINE, COL: integer);
procedure Put_Colored_Text (OUT_STRING: STRING79;
 LINE, COL, TXTCLR, BKGCLR: integer);
procedure Put_Centered_String (OUT_STRING: STRING79; LINE, ATTRIB: integer);
procedure Put_Centered_Text (OUT_STRING: STRING79; LINE: integer);
procedure Put_Error (OUT_STRING: STRING79; LINE, COL: integer);
procedure End_Erase (LINE, COL: integer);
procedure Put_Prompt (OUT_STRING: STRING79; LINE, COL: integer);
procedure Get_Response (var RESPONSE : RESPONSE_TYPE;
 var DIRECTION : MOVEMENT;
 var KEY_RESPONSE: char);
procedure Get_String (var IN_STRING: STRING79;
 LINE, COL, ATTRIB, STR_LENGTH: integer);
procedure Get_Integer (var NUMBER: integer;
 LINE, COL, ATTRIB, NUM_LENGTH: integer);
procedure Get_Prompted_String (var IN_STRING: STRING79;
 INATTR, STR_LENGTH: integer;
 STRDESC: STRING79;
 DESCLINE, DESCCOL: integer;
 PROMPT: STRING79;
 PRLINE, PRCOL: integer);
procedure Put_1col_Toggle (TOGGLE: TOGGLE_REC; COL, CHOICE: integer);
procedure Get_1col_Toggle ( TOGGLE: TOGGLE_REC;
 COL: integer;
 var CHOICE: integer;
 PROMPT: STRING79;
 PRLINE, PRCOL: integer);
procedure Box_Text (TopX, TopY, BotX, BotY, BoxColor: integer);
procedure Solid_Box (TopX, TopY, BotX, BotY, BoxColor: integer);
procedure swap_fnames(var A,B: FnameType);
procedure FileSort(var fname: FileListType; NumFiles: integer);
function Get_Files_Toggle (choices: FileListType;
 NumChoices,NumRows,row,col:integer): FnameType;
function Get_File_Menu(mask: string;NumRows,Row,Col: integer): FnameType;
{-------------------------------------------------------------------------}
implementation
procedure Set_Video (ATTRIBUTE: integer);
{
NOTES:
 The attribute code, based on bits, is as follows:
 0 - normal video 1 - reverse video
 2 - bold video 3 - reverse and bold
 4 - blinking video 5 - reverse and blinking
 6 - bold and blinking 7 - reverse, bold, and blinking
}
var
 BLINKING,
 BOLD: integer;
begin
 BLINKING := (ATTRIBUTE AND 4)*4;
 if (ATTRIBUTE AND 1) = 1 then
 begin
 BOLD := (ATTRIBUTE AND 2)*7;
 Textcolor (1 + BLINKING + BOLD);
 TextBackground (3);
 end
 else
 begin
 BOLD := (ATTRIBUTE AND 2)*5 DIV 2;
 Textcolor (7 + BLINKING + BOLD);
 TextBackground (0);
 end;
end;
{-------------------------------------------------------------------------}
procedure Put_String (OUT_STRING: STRING79;
 LINE, COL, ATTRIB: integer);
begin
 Set_Video (ATTRIB);
 GotoXY (COL, LINE);
 write (OUT_STRING);
 Set_Video (0);
end;
{-------------------------------------------------------------------------}
procedure Put_Text (OUT_STRING: STRING79;
 LINE, COL: integer);
begin
 GotoXY (COL, LINE);
 write (OUT_STRING);
end;
{-------------------------------------------------------------------------}
procedure Put_Colored_Text (OUT_STRING: STRING79;
 LINE, COL, TXTCLR, BKGCLR: integer);
begin
 GotoXY (COL, LINE);
 TextColor (TXTCLR);
 TextBackground (BKGCLR);
 write (OUT_STRING);
end;
{-------------------------------------------------------------------------}
procedure Put_Centered_String (OUT_STRING: STRING79;
 LINE, ATTRIB: integer);
begin
 Put_String (OUT_STRING, LINE, 40-Length(OUT_STRING) div 2, ATTRIB);
end;
{-------------------------------------------------------------------------}
procedure Put_Centered_Text (OUT_STRING: STRING79;
 LINE: integer);
begin
 Put_Text (OUT_STRING, LINE, 40-Length(OUT_STRING) div 2);
end;
{-------------------------------------------------------------------------}
procedure Put_Error (OUT_STRING: STRING79;
 LINE, COL: integer);
var
 ANY_CHAR : char;
begin
repeat
 Put_String (OUT_STRING, LINE, COL, 6);
until keypressed = true;
end;
{-------------------------------------------------------------------------}
procedure End_Erase (LINE, COL: integer);
begin
 GotoXY (COL, LINE);
 ClrEol;
end;
{-------------------------------------------------------------------------}
procedure Put_Prompt (OUT_STRING: STRING79;
 LINE, COL: integer);
begin
 GotoXY (COL, LINE);
 ClrEol;
 Put_String (OUT_STRING, LINE, COL, 3);
end;
{-------------------------------------------------------------------------}
procedure Get_Response (var RESPONSE : RESPONSE_TYPE;
 var DIRECTION : MOVEMENT;
 var KEY_RESPONSE: char);
const
 BELL = 7;
 CARRIAGE_RETURN = 13;
 ESCAPE = 27;
 RIGHT_ARROW = 77;
 LEFT_ARROW = 75;
 DOWN_ARROW = 80;
 UP_ARROW = 72;
var
 IN_CHAR: char;
begin
 RESPONSE := NO_RESPONSE;
 DIRECTION := NONE;
 KEY_RESPONSE := ' ';
 repeat
 IN_CHAR := ReadKey;
 if IN_CHAR = #0 then
 begin
 RESPONSE := ARROW;
 IN_CHAR := ReadKey;
 if Ord(IN_CHAR) = LEFT_ARROW then
 DIRECTION := LEFT
 else if Ord(IN_CHAR) = RIGHT_ARROW then
 DIRECTION := RIGHT
 else if Ord(IN_CHAR) = DOWN_ARROW then
 DIRECTION := DOWN
 else if Ord(IN_CHAR) = UP_ARROW then
 DIRECTION := UP
 else
 begin
 RESPONSE := NO_RESPONSE;
 write (Chr(BELL));
 end
 end
 else if Ord(IN_CHAR) = CARRIAGE_RETURN then
 RESPONSE := RETURN
 else
 begin
 RESPONSE := KEYBOARD;
 KEY_RESPONSE := UpCase (IN_CHAR);
 end;
 until RESPONSE  NO_RESPONSE;
end;
{-------------------------------------------------------------------------}
procedure Get_String (var IN_STRING: STRING79;
 LINE, COL, ATTRIB, STR_LENGTH: integer);
var
 OLDSTR : STRING79;
 IN_CHAR: char;
 I : integer;
const
 BELL = 7;
 BACK_SPACE = 8;
 CARRIAGE_RETURN = 13;
 ESCAPE = 27;
 RIGHT_ARROW = 77;
begin
 OLDSTR := IN_STRING;
 Put_String (IN_STRING, LINE, COL, ATTRIB);
 for I := Length(IN_STRING) to STR_LENGTH-1 do
 Put_String (' ', LINE, COL + I, ATTRIB);
 GotoXY (COL, LINE);
 IN_CHAR := ReadKey;
 if Ord(IN_CHAR)  CARRIAGE_RETURN then
 IN_STRING := '';
 while Ord(IN_CHAR)  CARRIAGE_RETURN do
 begin
 if Ord(IN_CHAR) = BACK_SPACE then
 begin
 if Length(IN_STRING)> 0 then
 begin
 IN_STRING[0] := Chr(Length(IN_STRING)-1);
 write (Chr(BACK_SPACE));
 write (' ');
 write (Chr(BACK_SPACE));
 end;
 end { if BACK_SPACE }
 else if IN_CHAR = #0 then
 begin
 IN_CHAR := ReadKey;
 if Ord(IN_CHAR) = RIGHT_ARROW then
 begin
 if Length(OLDSTR)> Length(IN_STRING) then
 begin
 IN_STRING[0] := Chr(Length(IN_STRING) + 1);
 IN_CHAR := OLDSTR[Ord(IN_STRING[0])];
 IN_STRING[Ord(IN_STRING[0])] := IN_CHAR;
 write (IN_CHAR);
 end
 end { RIGHT_ARROW }
 else
 write (Chr(BELL));
 end { IN_CHAR = #0 }
 else if Length (IN_STRING) < STR_LENGTH then begin IN_STRING[0] := Chr(Length(IN_STRING) + 1); IN_STRING[Ord(IN_STRING[0])] := IN_CHAR; TextColor (15); TextBackGround (11); write (IN_CHAR); end else write (Chr(BELL)); IN_CHAR := ReadKey; end; Put_String (IN_STRING, LINE, COL, ATTRIB); for I := Length(IN_STRING) to STR_LENGTH - 1 do Put_String (' ', LINE, COL+I, ATTRIB); end; {-------------------------------------------------------------------------} procedure Get_Integer (var NUMBER: integer; LINE, COL, ATTRIB, NUM_LENGTH: integer); const BELL = 7; var VALCODE : integer; ORIGINAL_STR, TEMP_STR : STRING79; TEMP_INT : integer; begin Str (NUMBER:NUM_LENGTH, ORIGINAL_STR); repeat TEMP_STR := ORIGINAL_STR; Get_String (TEMP_STR, LINE, COL, ATTRIB, NUM_LENGTH); while TEMP_STR[1] = ' ' do TEMP_STR := Copy (TEMP_STR, 2, Length (TEMP_STR)); Val (TEMP_STR, TEMP_INT, VALCODE); if (VALCODE  0) then
 write (Chr(BELL));
 until VALCODE = 0;
 NUMBER := TEMP_INT;
 Str (NUMBER:NUM_LENGTH, TEMP_STR);
 Put_String (TEMP_STR, LINE, COL, ATTRIB);
end;
{-------------------------------------------------------------------------}
procedure Get_Prompted_String (var IN_STRING: STRING79;
 INATTR, STR_LENGTH: integer;
 STRDESC: STRING79;
 DESCLINE, DESCCOL: integer;
 PROMPT: STRING79;
 PRLINE, PRCOL: integer);
begin
 Put_String (STRDESC, DESCLINE, DESCCOL, 2);
 Put_Prompt (PROMPT, PRLINE, PRCOL);
 Get_String (IN_STRING, DESCLINE, DESCCOL + Length(STRDESC),
 INATTR, STR_LENGTH);
 Put_String (STRDESC, DESCLINE, DESCCOL, 0);
end;
{-------------------------------------------------------------------------}
procedure Put_1col_Toggle (TOGGLE: TOGGLE_REC;
 COL, CHOICE: integer);
var
 I: integer;
begin
 with TOGGLE do
 begin
 Put_String (STRINGS[0], LOCATIONS[0], COL, 0);
 for I := 1 to NUM_CHOICES do
 Put_String (STRINGS[I], LOCATIONS[I], COL, 0);
 if (CHOICE <1) or (CHOICE> NUM_CHOICES) then
 CHOICE := 1;
 Put_String (STRINGS[CHOICE], LOCATIONS[CHOICE], COL, 1);
 end;
end;
{-------------------------------------------------------------------------}
procedure Get_1col_Toggle ( TOGGLE: TOGGLE_REC;
 COL: integer;
 var CHOICE: integer;
 PROMPT: STRING79;
 PRLINE, PRCOL: integer);
var
 RESP : RESPONSE_TYPE;
 DIR : MOVEMENT;
 KEYCH: char;
begin
 Put_Colored_Text (PROMPT, PRLINE, PRCOL, 15, 0);
 with TOGGLE do
 begin
 Put_String (STRINGS[0], LOCATIONS[0], COL, 2);
 if (CHOICE < 1) or (CHOICE> NUM_CHOICES) then
 CHOICE := 1;
 Put_String (STRINGS[CHOICE], LOCATIONS[CHOICE], COL, 1);
 RESP := NO_RESPONSE;
 while RESP  RETURN do
 begin
 Get_Response (RESP, DIR, KEYCH);
 case RESP of
 ARROW:
 if DIR = UP then
 begin
 Put_String (STRINGS[CHOICE], LOCATIONS[CHOICE], COL, 0);
 if CHOICE = 1 then
 CHOICE := NUM_CHOICES
 else
 CHOICE := CHOICE - 1;
 Put_String (STRINGS[CHOICE], LOCATIONS[CHOICE], COL, 1);
 end
 else if DIR = DOWN then
 begin
 Put_String (STRINGS[CHOICE], LOCATIONS[CHOICE], COL, 0);
 if CHOICE = NUM_CHOICES then
 CHOICE := 1
 else
 CHOICE := CHOICE + 1;
 Put_String (STRINGS[CHOICE], LOCATIONS[CHOICE], COL, 1);
 end
 else
 write (Chr(7));
 KEYBOARD: write (Chr(7));
 RETURN: ;
 end;
 end; {while}
 Put_String (STRINGS[0], LOCATIONS[0], COL, 0);
 end;
end;
{-------------------------------------------------------------------------}
procedure Box_Text (TopX, TopY, BotX, BotY, BoxColor: integer);
var
 i : integer;
 width : integer;
 height: integer;
begin
 TextBackGround (BoxColor);
 height := BotY - TopY;
 width := BotX - TopX;
 GotoXY (TopX, TopY);
 for i := 1 to width do
 write (' ');
 for i := TopY to (TopY+height) do
 begin
 GotoXY (TopX, i);
 write (' ');
 GotoXY (BotX-1, i);
 write (' ');
 end;
 GotoXY (TopX, BotY);
 for i := 1 to width do
 write (' ');
end;
{-------------------------------------------------------------------------}
procedure Solid_Box (TopX, TopY, BotX, BotY, BoxColor: integer);
var
 i : integer;
 j : integer;
 width : integer;
begin
 TextBackGround (BoxColor);
 GotoXY (TopX, TopY);
 width := BotX - TopX;
 for i := TopY to BotY do
 begin
 for j := 1 to width do
 write (' ');
 GotoXY (TopX, i);
 end;
end;
procedure swap_fnames(var A,B: FnameType);
var
 Temp : FnameType;
begin
 Temp := A;
 A := B;
 B := Temp;
end;
procedure FileSort(var fname: FileListType;NumFiles: integer);
var
 i,j : integer;
begin
 for j := NumFiles downto 2 do
 for i := 1 to j-1 do
 if fname[i]>fname[j] then
 swap_fnames(fname[i],fname[j]);
end;
function Get_Files_Toggle (choices:FileListType;
 NumChoices,NumRows,row,col:integer): FnameType;
var
 i,r : integer;
 Resp : Response_Type;
 dir : movement;
 keych : char;
procedure Put_Files_Toggle (choices: FileListType; First,NumRows,row,col: integer);
var
 i : integer;
begin
 for i := 0 to NumRows-1 do
 Put_string (choices[First+i],row+i,col,0);
end;
procedure Padnames;
var
 i,p : integer;
begin
 for i := 1 to MaxFiles do
 begin
 p := 12-length(choices[i]);
 while p>0 do
 begin
 choices[i] := choices[i]+' ';
 p := p-1;
 end;
 end;
end;
begin
 Padnames;
 i := 1;
 r := 1;
 if NumChoices < NumRows then NumRows := NumChoices; Put_Files_Toggle (choices,1,NumRows,row,col); Get_Files_Toggle := choices[i]; Put_string(choices[i],row,col,1); resp := No_Response; while resp  Return do
 begin
 Get_response (resp,dir,keych);
 case resp of
 ARROW: if dir=UP then
 begin
 Put_string(choices[i],row+r-1,col,0);
 if i=1 then
 begin
 i := NumChoices;
 r := NumRows;
 Put_Files_Toggle(choices,i+1-NumRows,NumRows,row,col);
 end
 else if r=1 then
 begin
 i := i-1;
 Put_Files_Toggle(choices,i,NumRows,row,col);
 end
 else
 begin
 i := i-1;
 r := r-1;
 end;
 Put_string(choices[i],row+r-1,col,1);
 end
 else if dir=DOWN then
 begin
 Put_string(choices[i],row+r-1,col,0);
 if i=NumChoices then
 begin
 i := 1;
 r := 1;
 Put_Files_Toggle(choices,i,NumRows,row,col);
 end
 else if r=NumRows then
 begin
 i := i+1;
 Put_Files_Toggle(choices,i+1-NumRows,NumRows,row,col);
 end
 else
 begin
 i := i+1;
 r := r+1;
 end;
 Put_string(choices[i],row+r-1,col,1);
 end
 else
 write (chr(7));
 KEYBOARD: write (chr(7));
 end; { case }
 end;
 Get_Files_toggle := choices[i];
end;
function Get_File_Menu(mask: string;NumRows,Row,Col: integer): FnameType;
var
 i : integer;
 NumFiles : integer;
 FileList : FileListType;
 dirinfo : SearchRec;
begin
 i := 1;
 FindFirst(mask,Archive,dirinfo);
 while (DosError=0) AND (i Return do
 begin
 PutDescripts;
 Get_Response(Resp,Dir,KeyCh);
 case Resp of
 Arrow :
 if Dir = Up then
 begin
 Put_String(Selection[Last],Line+Last-1,Col,0);
 if Last = 1 then
 Last := NumChoices
 else
 Last := Last-1;
 Put_String(Selection[Last],Line+Last-1,Col,1);
 end
 else if Dir = Down then
 begin
 Put_String(Selection[Last],Line+Last-1,Col,0);
 if Last = NumChoices then
 Last := 1
 else
 Last := Last+1;
 Put_String(Selection[Last],Line+Last-1,Col,1);
 end;
 end;
 end;
end;
end;
{ Initialization Area }
begin
end.
{------------------------------------ TEST PROGRAM ------------------- }
program testdir;
{ program attempts to read directory }
{ shows filenames as column }
uses dos,crt,miscLib;
var
 Fchoice : FnameType;
 i,n : integer;
{ *************** MAIN PROGRAM *************** }
begin
 ClrScr;
 Fchoice := Get_File_Menu('*.*',8,10,30);
 Put_string(Fchoice,24,1,0);
 ReadLn;
end.
{------------------------------------ TEST PROGRAM ------------------- }
program TestMenu;
uses crt,MiscLib;
const
 ChoiceData : ScrMenuRec =
 (selection : ('Choice 1','Choice 2','Choice 3','Choice 4','','','','');
 Descripts : (('This is','No 1','The First Choice'),
 ('Number 2','The Second Choice and default',''),
 ('Number 3','Last Choice, for now...','Last Line'),
 ('Number 4','An added Selection','How bout that?'),
 ('','',''),
 ('','',''),
 ('','',''),
 ('','','')));
var
 ScrMenu : ScrMenuType;
 Choice : integer;
begin
 TextColor(white);
 TextBackGround(Blue);
 ClrScr;
 ScrMenu.NumChoices := 4;
 ScrMenu.Last := 2;
 ScrMenu.Line := 6;
 ScrMenu.Col := 30;
 ScrMenu.Setup(ChoiceData);
 Choice := ScrMenu.GetChoice;
 ReadLn;
end. 

AltStyle によって変換されたページ (->オリジナル) /