home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / box / example2.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1980-01-01  |  13.4 KB  |  436 lines

  1. USES CRT,DOS;
  2.  
  3. CONST
  4.    MaxPicks   = 9;       {increase for more menu items}
  5.  
  6. TYPE
  7.    Map     = Record
  8.              ScrCh : Char;
  9.              ScrAt : Byte;
  10.              End;
  11.    Screen  = Array[1..25,1..80] of Map;
  12.    AnyStr  = String[80];
  13.    FileName= String[12];
  14.  
  15. VAR
  16.     R          : Registers;
  17.     FilevarM   : File;
  18.     CS         : Screen absolute $B800:0000;
  19.     MS         : Screen absolute $B000:0000;
  20.     LoadScr    : Screen;
  21.     Scr        : Array[1..2] of Screen;
  22.     HelpContext: Integer;
  23.     FunctKey   : Boolean;
  24.     Color      : Boolean;
  25.     BigExit    : Boolean;
  26.     Ch         : Char;
  27.     NPicks     : Integer;
  28.     MP         : Integer;
  29.     LastMP     : Integer;
  30.     XBeg       : Array[1..MaxPicks] of Integer;
  31.     YBeg       : Array[1..MaxPicks] of Integer;
  32.     Len        : Array[1..MaxPicks] of Integer;
  33.     Attr       : Array[1..MaxPicks] of Byte;
  34.     CapCh      : Array[1..MaxPicks] of Char;
  35. {=====================================================}
  36. {                                                     }
  37. {  This Procedure produces a sound on the speaker     }
  38. {                                                     }
  39. PROCEDURE Beep(Freq:Integer);
  40. BEGIN
  41.      Sound(Freq);Delay(200);Nosound;
  42. END;
  43.  
  44. {=====================================================}
  45. {                                                     }
  46. {  This Procedure returns Color = True if the PC      }
  47. {  has a color graphics adapter.                      }
  48. {                                                     }
  49. PROCEDURE CheckColor;
  50. BEGIN
  51.      If (Mem[0000:1040] and 48) <> 48
  52.         then Color := True
  53.         else Color := False;
  54. END;
  55.  
  56. {=====================================================}
  57. {                                                     }
  58. {  This Procedure hides the cursor by moving it off   }
  59. {  the screen.                                        }
  60. {                                                     }
  61. PROCEDURE HideCursor;
  62.   Begin
  63.     R.AX := $0200;
  64.     R.DX := $1900;
  65.     R.BX := $0000;
  66.     Intr($10,R);
  67.   End;
  68.  
  69. {=====================================================}
  70. {                                                     }
  71. {  This Procedure Saves the current screen so         }
  72. {  that it can be restored later.                     }
  73. {                                                     }
  74. PROCEDURE SaveScreen(NS:Integer);
  75. BEGIN
  76.  If Color then Move(CS,Scr[NS],4000)
  77.           else Move(MS,Scr[NS],4000);
  78. END;
  79.  
  80. {=====================================================}
  81. {                                                     }
  82. {  This Procedure restores the screen  saved          }
  83. {  in Procedure SaveScreen.                           }
  84. {                                                     }
  85. PROCEDURE RestoreScreen(NS:Integer);
  86. BEGIN
  87.  If Color then Move(Scr[NS],CS,4000)
  88.           else Move(Scr[NS],MS,4000);
  89. END;
  90.  
  91. {=====================================================}
  92. PROCEDURE MemoryLoad(MFile : AnyStr);
  93. {                                                     }
  94. { This procedure displays a memory format screen      }
  95. { image produced by BOX by reading in the file and    }
  96. { loading the image directly into the video buffer    }
  97. {                                                     }
  98. BEGIN
  99.       Assign(FilevarM,MFile);
  100.       {$I-} Reset(FilevarM,4000); {$I+}
  101.       If IOresult = 0 then       {found good file name}
  102.         Begin
  103.         BlockRead(FilevarM,LoadScr,1);
  104.           If Color then CS := LoadScr
  105.                    else MS := LoadScr;
  106.           Close(FilevarM);
  107.         End
  108.       Else                         {couldn't find file}
  109.         Begin
  110.           GoToXY(1,24);
  111.           Write('ERROR - Could not find file');
  112.         End;
  113. END; {MemoryLoad}
  114.  
  115. {=====================================================}
  116. PROCEDURE HelpMsg;
  117. {                                                     }
  118. {  This procedure displays a Help screen depending    }
  119. {  on the value of HelpContext, a variable set by     }
  120. {  programmer to different values in different places }
  121. {  depending on the Help screen needed.  EXHELP       }
  122. {  files are used only for an example.  You need to   }
  123. {  substitute your own help files.                    }
  124. {                                                     }
  125. VAR
  126.    SaveX,SaveY : Integer;
  127. BEGIN
  128.     SaveScreen(2);     {Save the current screen}
  129.     SaveX := WhereX; SaveY := WhereY;
  130.     Case HelpContext of
  131.      1 : MemoryLoad('EXHELP.1');
  132.      2 : MemoryLoad('EXHELP.2');
  133. {    3 : MemoryLoad('EXHELP.3');   add more help      }
  134. {    4 : MemoryLoad('EXHELP.4');   screens here       }
  135.     End; {case}
  136.     GoToXY(1,25);Write('Hit any key to continue');
  137.     Ch := ReadKey;
  138.     RestoreScreen(2);  {Restore the screen as it was}
  139.     GoToXY(SaveX,SaveY);
  140. END;
  141.  
  142. {=====================================================}
  143. FUNCTION NextKey:Char;
  144. {                                                     }
  145. {  This Function reads in a keystroke.  If the key is }
  146. {  F1 the function flashes a Help screen.  If the key }
  147. {  is any other character the function passes it on.  }
  148. {                                                     }
  149. CONST
  150.     Help = #59;
  151. VAR
  152.     NKey : Char;
  153. LABEL
  154.     Start;
  155. BEGIN
  156. Start:NKey := ReadKey;
  157.       If NKey <> #0 then FunctKey := False else
  158.         Begin
  159.           NKey := ReadKey;
  160.           If(NKey = Help) then
  161.           Begin
  162.            HelpMsg;
  163.            GoTo Start;
  164.           End;
  165.           FunctKey := True;
  166.         End;
  167.       NextKey := NKey;
  168. END;
  169.  
  170. {=====================================================}
  171. {                                                     }
  172. {   This function finds and returns the first         }
  173. {   Capital letter in a string                        }
  174. {                                                     }
  175. FUNCTION FirstCap(St : AnyStr; Len : Integer): Char;
  176. VAR
  177.    II : Integer;
  178. BEGIN
  179.  FirstCap := '?';
  180.  For II := 1 to Len Do
  181.   Begin
  182.    If St[II] in ['A'..'Z','0'..'9'] then
  183.      Begin
  184.        FirstCap := St[II];
  185.        Exit;
  186.      End;
  187.   End;
  188. END;
  189.  
  190. {=====================================================}
  191. {                                                     }
  192. {  This Procedure finds the menu picks on LoadScr     }
  193. {                                                     }
  194. PROCEDURE FindPicks;
  195. VAR
  196.       YY,II,XT,LT      : Integer;
  197.       MenuLine         : AnyStr;
  198.  
  199. BEGIN
  200.      For II := 1 to MaxPicks do begin
  201.        XBeg[II] := 0;
  202.        YBeg[II] := 0;
  203.        Len[II]  := 0;
  204.        CapCh[II] := '?';
  205.      End;
  206.      YY := 1;
  207.      NPicks := 0;
  208.      Repeat
  209.          For II := 1 to 80 do
  210.           MenuLine[II] := LoadScr[YY,II].ScrCh;
  211.          MenuLine[0] := chr(80);
  212.          XT := pos('[',MenuLine);
  213.          If XT > 0 then begin
  214.            If NPicks < MaxPicks
  215.             then NPicks := NPicks + 1;
  216.            XBeg[NPicks] := XT;
  217.            YBeg[NPicks] := YY;
  218.            If Color
  219.              then Attr[NPicks] := LoadScr[YY,XT].ScrAt
  220.              else Attr[NPicks] := 7;
  221.  
  222.            LT := pos(']',copy(Menuline,XT+1,80-XT));
  223.            If LT > 0 then Len[NPicks] := LT+1
  224.                      else Len[NPicks] := 80-XT+1;
  225.            MenuLine[XT] := ' ';
  226.            MenuLine[XT+LT] := ' ';
  227.            CapCh[NPicks] :=
  228.              FirstCap(Copy(Menuline,XT+1,LT),LT);
  229.            LoadScr[YY,XT].ScrCh := ' ';
  230.            LoadScr[YY,XT+LT].ScrCh := ' ';
  231.          End
  232.         else YY := YY + 1;
  233.      Until YY = 26;
  234. END;
  235.  
  236. {=====================================================}
  237. {                                                     }
  238. {  This procedure displays the menu.  See file        }
  239. {  EXMENU.MEM to see how this procedure works.        }
  240. {                                                     }
  241. PROCEDURE ShowMenu(MenuFile:FileName);
  242. BEGIN
  243.       CheckColor;
  244.       MP := 1;              {initialize Menu Pick}
  245.       LastMP := 1;          {initialize last Menu Pick}
  246.       Assign(FilevarM,MenuFile);
  247.       {$I-} Reset(FilevarM,4000); {$I+}
  248.       If IOresult = 0 then
  249.        Begin
  250.         BlockRead(FilevarM,LoadScr,1);
  251.         FindPicks;
  252.         If Color then CS := LoadScr
  253.                  else MS := LoadScr;
  254.         Close(FilevarM);
  255.        End
  256.  
  257.       Else
  258.        Begin
  259.          GoToXY(1,24);
  260.          Write('Could not find file ',MenuFile);
  261.          Ch := ReadKey;
  262.        End;
  263. END; {ShowMenu}
  264.  
  265. {=====================================================}
  266. {                                                     }
  267. {  Changes the color attribute at X,Y for Length Len  }
  268. {  to attribute Att.  Useful for making a bar cursor  }
  269. {                                                     }
  270. PROCEDURE ColorChange(X,Y,Len:Integer;Att:Byte);
  271. VAR
  272.    II      : Integer;
  273. BEGIN
  274.  
  275.    For II := 1 to Len do begin
  276.      If color then
  277.       begin
  278.        while ((port[$3DA] and 8) = 8) do;
  279.        {wait for vertical retrace}
  280.        CS[Y,X-1+II].ScrAT := Att;
  281.        {change the color attribute}
  282.       end
  283.      else MS[Y,X-1+II].ScrAT := Att;
  284.    End;
  285. END;
  286.  
  287. {=====================================================}
  288. {                                                     }
  289. {  Displays menu pick P in reverse video.             }
  290. {                                                     }
  291. PROCEDURE Reverse(P:Integer);
  292. VAR
  293.    RAttr   : Byte;
  294. BEGIN
  295.  
  296.    {Flip flop the first and last 8 bits of }
  297.    {the color attribute byte to produce    }
  298.    {reverse video of the menu line's original color}
  299.  
  300.    RAttr := (Attr[P] shr 4) or ((Attr[P] and 7) shl 4);
  301.    ColorChange(XBeg[P],YBeg[P],Len[P],RAttr);
  302. END;
  303.  
  304. {=====================================================}
  305. {                                                     }
  306. {  Restores menu pick P to original video color.      }
  307. {                                                     }
  308. PROCEDURE Restore(P:Integer);
  309. BEGIN
  310.    ColorChange(XBeg[P],YBeg[P],Len[P],Attr[P]);
  311. END;
  312.  
  313. {=====================================================}
  314. {                                                     }
  315. {  This function lets the user play with the menu     }
  316. {  and returns a character indicating the menu pick   }
  317. {  he selected.                                       }
  318. {                                                     }
  319. FUNCTION MenuPick:Char;
  320. CONST
  321.    Enter      = #13;
  322.    Escape     = #27;
  323.    DownArrow  = #80;
  324.    UpArrow    = #72;
  325.    RightArrow = #77;
  326.    LeftArrow  = #75;
  327.    Home       = #71;
  328.    EndKey     = #79;
  329. VAR
  330.       ExitMenuPick,NoMatch : Boolean;
  331.       Ytemp                : Integer;
  332.       ErrCode,II           : Integer;
  333. BEGIN;
  334.        ExitMenuPick := False;
  335.   Repeat
  336.        HideCursor;
  337.        If MP > NPicks then MP := 1;
  338.        If MP < 1 then MP := NPicks;
  339.        Reverse(MP);
  340.         {Paint new pick in reverse video}
  341.        If LastMP <> MP then Restore(LastMP);
  342.         {Restore last pick to original color}
  343.        LastMP := MP;
  344.  
  345.        Ch := NextKey;
  346.         {read a character}
  347.  
  348.        If not FunctKey then
  349.         Case Ch of
  350.            Enter  : ExitMenuPick := True;
  351.            Escape : Begin
  352.                      ExitMenuPick := True;
  353.                      MP := NPicks;
  354.                       {set Pick to last, exit}
  355.                     End;
  356.            '1'..'9',
  357.            'a'..'z',
  358.            'A'..'Z':Begin
  359.                      NoMatch := true;
  360.                      For II := 1 to NPicks do
  361.                        If Upcase(Ch) = Capch[II] then
  362.                        begin
  363.                         MP := II;
  364.                         Reverse(MP);
  365.                         If LastMP <> MP
  366.                          then Restore(LastMP);
  367.                         LastMP := MP;
  368.                         NoMatch := false;
  369.                         ExitMenuPick := true;
  370.                        end;
  371.                      If NoMatch then beep(440);
  372.                     End;
  373.            Else Beep(440);
  374.         End; {case ch}
  375.  
  376.        If FunctKey then
  377.         Case Ch of
  378.           RightArrow : MP := MP + 1;
  379.           LeftArrow  : MP := MP - 1;
  380.           DownArrow  : MP := MP + 1;
  381.           UpArrow    : MP := MP - 1;
  382.           Home       : MP := 1;
  383.           EndKey     : MP := NPicks;
  384.           Else Beep(440);
  385.         End; {Case}
  386.  
  387.      Until ExitMenuPick;
  388.    MenuPick := CapCh[MP];
  389. END;
  390. {=====================================================}
  391. {                                                     }
  392. {  Dummy procedure. Do not include in real            }
  393. {  application.                                       }
  394. {                                                     }
  395. PROCEDURE TypeOnScreen;
  396. VAR TCh : Char;
  397. BEGIN
  398.      SaveScreen(1);
  399.      HelpContext := 2; {switch help screen}
  400.      ClrScr;
  401.      GoToXY(1,25);
  402.      Write('Type stuff on screen, '+
  403.      'hit F1 for help, Hit Esc. to Exit');
  404.      GoToXY(1,1);
  405.    Repeat
  406.      TCh := NextKey;
  407.      Write(TCh);
  408.    Until TCh = #27;
  409.      RestoreScreen(1);
  410. END;
  411.  
  412. {=====================================================}
  413. {                                                     }
  414. {  Example main program                               }
  415. {                                                     }
  416. BEGIN
  417.  BigExit := false;
  418.  ShowMenu('EXMENU.MEM');
  419.  HelpContext := 1;         {set help screen}
  420.  Repeat Case MenuPick of
  421.   'T' : Begin
  422.          TypeOnScreen;
  423.          HelpContext := 1; {switch back help screen}
  424.         End;
  425.   'L' : Beep(50);
  426.   'H' : Beep(1000);
  427.   'M' : Beep(300);
  428.   '1' : Begin End;
  429.   '2' : Begin End;
  430.   'D' : Begin End;
  431.   'E' : Begin End;
  432.   'X' : BigExit := True;
  433.    End; {case}
  434.  Until BigExit;
  435.  Clrscr;
  436. END.