home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / 552 / XTRASTUF.PAS < prev   
Pascal/Delphi Source File  |  1993-10-07  |  25KB  |  791 lines

  1. UNIT XtraStuf;
  2. {-----------------------------------------------------------------------------
  3.                              Item Selection Routines
  4.  
  5.        XtraStuf Copyright (c)  Richard F. Griffin
  6.  
  7.        14 April 1993
  8.  
  9.        102 Molded Stone Pl
  10.        Warner Robins, GA  31088
  11.  
  12.        -------------------------------------------------------------
  13.        This unit handles routines to allow display of lists and selection
  14.        of items from the list.  These routines are provided to show how
  15.        GS_dBase units can be used in an application.  They are offered
  16.        with no guarantee or technical support.
  17.  
  18.              -----   NOT FOR USE IN A WINDOWS ENVIRONMENT   -----
  19.  
  20.    Changes:
  21.  
  22. -----------------------------------------------------------------------------}
  23.  
  24. INTERFACE
  25.  
  26. USES
  27.    Crt,
  28.    Dos,
  29.    GSOB_Inx,
  30.    GSOB_Edt,
  31.    GSOB_Str,
  32.    GSOB_Dte,
  33.    GSOB_Var,
  34.    SmplStuf,
  35.    GSXT_Bro,
  36.    GSOBShel;
  37.  
  38. var
  39.    RecChanged   : boolean;         {Flag for record changed}
  40.  
  41. Function  FieldAccept(st,Titl : string; x,y : integer) : string;
  42. Procedure FieldDisplay(st,Titl : string; x,y : integer);
  43. Function  FieldDisplayScreen : boolean;
  44. Function  FieldUpdateScreen : boolean;
  45. Function  FieldAppendScreen(empty : boolean) : boolean;
  46. Procedure FieldBrowseScreen;
  47.  
  48.  
  49. implementation
  50.  
  51. var
  52.    BrowseOn     : boolean;
  53.    TopLine      : integer;
  54.    EndLine      : integer;
  55.    ActivLin     : integer;
  56.    ActivFld     : integer;
  57.    LastLine     : integer;
  58.    FldLth       : integer;
  59.    EditOn       : boolean;
  60.    DeleteOnF9   : boolean;         {Flag to permit F9 to delete/undelete}
  61.  
  62.    MyShow  : GSO_ShowView;
  63.    MyEdit  : GSO_EditView;
  64.    MemoChg : boolean;
  65.  
  66. Procedure DrawScreen; Forward;
  67.  
  68. procedure EditTheMemo;
  69. begin
  70.    ClrScr;
  71.    MyEdit.Init(DBFActive^.MemoFile^.MemoCollect,
  72.                DBFActive^.MemoFile^.Edit_Lgth);
  73.    GS_KeyI_Esc := not MyEdit.WorkView;
  74.    MemoChg := MyEdit.Modified;
  75. end;
  76.  
  77. procedure ShowTheMemo;
  78. begin
  79.    ClrScr;
  80.    MyShow.Init(DBFActive^.MemoFile^.MemoCollect);
  81.    GS_KeyI_Esc := not MyShow.WorkView;
  82.    MemoChg := false;
  83. end;
  84.  
  85. Function UpdateOnEsc: boolean;
  86. var
  87.    aw : string[2];
  88. begin
  89. {
  90.    window(25,10,54,15);
  91.    SetScreenColors(Black,Yellow,Green,White,Green);
  92.    SetNmMode;
  93.    ClrScr;
  94.    MakeABox('');
  95.    gotoxy(1,1);
  96. }
  97.    Window(1,1,80,24);
  98.    SetNmMode;
  99.    ClrScr;
  100.    gotoxy(27,11);
  101.    writeln('Record has been modified!');
  102.    gotoxy(27,12);
  103.    write('Save before exit? ');
  104.    AdditionalKeys := Kbd_F1+Kbd_F9+Kbd_F10;
  105.    aw := EditString('Y',45,12,1);
  106.    UpdateOnEsc := aw[1] in ['T','t','Y','y'];
  107.    Window(1,1,80,25);
  108. end;
  109.  
  110. Function FieldAccept(st,Titl : string; x,y : integer) : string;
  111. var
  112.    txtatrb,
  113.    i,
  114.    v         :  integer;              {Counter variables}
  115.    t         :  string[255];          {Work string to hold default (old) value}
  116.    f         : string[2];
  117.    FNum      : integer;
  118.  
  119.    Procedure AcceptC;
  120.    var
  121.       r_c : string;
  122.    begin
  123.       SetIVMode;
  124.       if EditOn then        {If edit permitted, then go edit string}
  125.       begin
  126.          r_c := t;
  127.          AdditionalKeys := Kbd_F1+Kbd_F9+Kbd_F10;
  128.          t := EditString(t, v, y, FldLth);
  129.          if (GS_KeyI_Chr = Kbd_Esc) and (r_c <> EscStrSave) then
  130.          begin
  131.             if UpdateOnEsc then t := EscStrSave;
  132.             GS_KeyI_Chr := Kbd_Esc;
  133.          end;
  134.          if t <> r_c then RecChanged := true;
  135.       end
  136.       else
  137.       begin
  138.          gotoxy(v,y);       {Go to start of field screen position}
  139.          write(t,'':FldLth-length(t));
  140.                             {Rewrite the string on screen inverted}
  141.          WaitForKey;
  142.       end;
  143.       SetNmMode;
  144.       gotoxy(v,y);          {Go to start of field screen position}
  145.       write(t,'':FldLth-length(t));
  146.                             {Rewrite the string on screen in the original color}
  147.    end;
  148.  
  149.    Procedure AcceptD;
  150.    var
  151.       okDate : boolean;
  152.       v1,
  153.       v2     : longint;
  154.       h1     : string[10];
  155.    begin
  156.       t := TrimR(t);
  157.       v1 := CTOD(t);
  158.       t := DTOC(v1);
  159.       h1 := t;
  160.       FldLth := length(t);
  161.       okDate := false;
  162.       repeat
  163.          EditADate := true;
  164.          AcceptC;
  165.          EditADate := false;
  166.          if EditOn then
  167.          begin
  168.             if GS_KeyI_Esc then v2 := v1
  169.                else v2 := CTOD(t);
  170.             if v2 >= 0 then
  171.             begin
  172.                okDate := true;
  173.                t := DTOC(v2);
  174.             end
  175.             else
  176.             begin
  177.                if t = h1 then
  178.                begin
  179.                   t := FieldGet(st);
  180.                   okDate := true;
  181.                end;
  182.             end;
  183.          end else okDate := true;
  184.          if not okDate then SoundBell(BeepTime,BeepFreq);
  185.       until okDate;
  186.    end;
  187.  
  188.    Procedure AcceptL;
  189.    var
  190.       data : string[1];
  191.    begin
  192. {
  193.                     ┌─────────────────────────────────────┐
  194.                     │  Accept keyboard entry.  Loop until │
  195.                     │  value is T,t,Y,y,F,f,N,n.          │
  196.                     └─────────────────────────────────────┘
  197. }
  198.       repeat
  199.          if t = '' then t := 'F';
  200.          AcceptC;
  201.          if not EditOn then exit;
  202.          if t[1] in ['T','t','Y','y','F','f','N','n'] then
  203.          begin end else SoundBell(BeepTime,BeepFreq);
  204.       until t[1] in ['T','t','Y','y','F','f','N','n'];
  205.       if t[1] in ['T','t','Y','y'] then t[1] := 'T' else t[1] := 'F';
  206.    end;
  207.  
  208.    procedure AcceptM;
  209.    var
  210.       ans       :  string[10];        {Work string to hold edit value}
  211.       r_c       :  string[10];        {Work string for memo block number}
  212.       lbl       :  string[10];
  213.    begin
  214.       if t = '0' then t := '';
  215.       SetIvMode;
  216.       ans := 'N';                     {Initialize ans to false}
  217.       GotoXy(v,y);
  218.       if EditOn then Write('  Edit ? ') else Write('  View ? ');
  219.       repeat
  220.          AdditionalKeys := Kbd_F1+Kbd_F9+Kbd_F10;
  221.          ans := EditString(ans,v+9,y,1);
  222.                                       {Go edit string t for 1 character}
  223.                                       {at cursor position v,y}
  224.          if ans[1] in ['T','t','Y','y','F','f','N','n'] then
  225.             begin end else SoundBell(BeepTime,BeepFreq);
  226.       until ans[1] in ['T','t','Y','y','F','f','N','n'];
  227.       SetNmMode;              {Restore original text attribute}
  228.       if t = '' then lbl := '---memo---' else lbl := '---MEMO---';
  229.       GotoXY(v,y);
  230.       Write(lbl);
  231.       if ans[1] in ['T','t','Y','y'] then
  232.       begin
  233.          r_c := t;
  234.          MemoGet(st);
  235.          If EditOn then EditTheMemo else ShowTheMemo;
  236.          if (EditOn) and (GS_KeyI_Esc) and (MemoChg) and
  237.             (not UpdateOnEsc) then
  238.          begin
  239.             ClrScr;
  240.             GS_KeyI_Esc := false;     {Reset Escape flag so its not used}
  241.                                       {elsewhere}
  242.             GS_KeyI_Chr := ' ';
  243.             MemoGet(st);
  244.          end
  245.          else
  246.          begin
  247.             ClrScr;
  248.             GS_KeyI_Chr := ' ';       {Clear character last entered}
  249.             if EditOn and MemoChg then
  250.             begin
  251.                MemoPut(st);
  252.                t := FieldGet(st);
  253.                RecChanged := true;
  254.             end;
  255.          end;
  256.          window(1,1,80,25);
  257.          SetScreenColors(Yellow,LightCyan,Blue,Blue,LightGray);
  258.          SetNmMode;
  259.          ClrScr;
  260.          DrawScreen;
  261.          if t = '' then lbl := '---memo---' else lbl := '---MEMO---';
  262.          GoToXY(v,y);
  263.          Write(lbl);
  264.          MemoChg := false;
  265.       end;
  266.    end;
  267.  
  268.    Procedure AcceptN;
  269.    var
  270.       data : string;
  271.       i   : integer;
  272.       r   : real;
  273.    begin
  274. {
  275.                     ┌─────────────────────────────────────┐
  276.                     │  Accept keyboard entry.  Loop until │
  277.                     │  value is Numeric.                  │
  278.                     └─────────────────────────────────────┘
  279. }
  280.       repeat
  281.          if t = '' then Str(0.0:FldLth:FieldDec(FNum),t);
  282.          AcceptC;
  283.          if not EditOn then exit;
  284.          val(t, r, i);
  285.          if i = 0 then
  286.          begin
  287.             Str(r:FldLth:FieldDec(FNum),t);
  288.             if length(t) > FldLth then i := 999;
  289.          end;
  290.          if i <> 0 then
  291.          begin
  292.             SoundBell(BeepTime,BeepFreq);
  293.             t := '';
  294.          end;
  295.       until i = 0;                    {i will be 0 when data is a valid number}
  296.       gotoxy(v,y);          {Go to start of field screen position}
  297.       write(t,'':FldLth-length(t));
  298.                             {Rewrite the string on screen in the original color}
  299.    end;
  300.  
  301. begin
  302.    Wait_Cr := false;
  303.    GotoXY(x,y);                       {Go to position on screen}
  304.    write(Titl);                       {Write the title of field}
  305.    v := WhereX;                       {Save the position after writing title}
  306.    t := TrimR(FieldGet(st));          {Get the field in the work string}
  307.    FNum := FieldNo(st);
  308.    FldLth := FieldLen(FNum);
  309.    case FieldType(FNum) of
  310.       'C'  : begin
  311.                 AcceptC;
  312.                 FieldAccept := t;     {Return the string to calling routine}
  313.              end;
  314.       'D'  : begin
  315.                 AcceptD;
  316.                 FieldAccept := t;
  317.              end;
  318.       'L'  : begin
  319.                 AcceptL;
  320.                 FieldAccept := t;
  321.              end;
  322.       'M'  : begin
  323.                 AcceptM;
  324.                 FieldAccept := t;
  325.              end;
  326.       'N'  : begin
  327.                 AcceptN;
  328.                 FieldAccept := t;
  329.              end;
  330.    end;
  331.    Wait_Cr := true;
  332. end;
  333.  
  334. Procedure FieldDisplay(st,Titl : string; x,y : integer);
  335. var
  336.    i,
  337.    v         :  integer;              {Counter variables}
  338.    t         :  string[255];          {Work string to hold default (old) value}
  339.    data      :  string[10];
  340.    FNum      :  integer;
  341. begin
  342.    GotoXY(x,y);                       {Go to position on screen}
  343.    write(Titl);                       {Write the title of field}
  344.    v := WhereX;                       {Save the position after writing title}
  345.    t := TrimR(FieldGet(st));          {Get the field in the work string}
  346.    FNum := FieldNo(st);
  347.    FldLth := FieldLen(FNum);
  348.    case FieldType(FNum) of
  349.       'C',
  350.       'L'  : begin
  351.                 gotoxy(v,y);          {Go to start of field screen position}
  352.                 write(t,'':FldLth-length(t));
  353.                                       {Write the string on screen }
  354.              end;
  355.       'D'  : begin
  356.                 t := DTOC(CTOD(t));;
  357.                 write(t);
  358.              end;
  359.       'N'  : begin
  360.                 if t = '' then t := '0';
  361.                 gotoxy(v,y);          {Go to start of field screen position}
  362.                 write(t:FldLth);
  363.              end;
  364.       'M'  : begin
  365.                 t := TrimR(t);
  366.                 if t = '' then t := '---memo---' else t := '---MEMO---';
  367.                 GotoXY(v,y);
  368.                 Write(t);
  369.              end;
  370.    end;
  371. end;
  372.  
  373.  
  374. Procedure DrawScreen;
  375. var
  376.    i,
  377.    x,
  378.    y     : integer;
  379.    st,
  380.    s     : string[12];
  381.    t     : string;
  382. begin
  383.    SetIvMode;
  384.    gotoxy(2,LastLine);
  385.    write('':pred(lo(WindMax)-lo(WindMin)));
  386.    t := DBFActive^.dfFileName;
  387.    if length(t) > 36 then system.delete(t,1,length(t)-36);
  388.    gotoxy(40,LastLine);
  389.    write(t);
  390.    if EditOn then
  391.    begin
  392.       if RecNo < 0 then           {If Append, do the following}
  393.       begin
  394.          gotoxy(12,LastLine);
  395.          write('Append ');
  396.          write('EOF/',RecCount);
  397.       end
  398.       else
  399.       begin                           {If Update do the following}
  400.          gotoxy(12,LastLine);
  401.          write('Update ');
  402.          write(RecNo,'/',RecCount);
  403.       end;
  404.    end else
  405.    begin                              {If Display then do this}
  406.       gotoxy(12,LastLine);
  407.       write('Display ');
  408.       write(RecNo,'/',RecCount);
  409.    end;
  410.    if Deleted then
  411.    begin
  412.       gotoxy(3,LastLine);
  413.       write('Deleted');
  414.    end;
  415.    gotoxy(31,LastLine);
  416.    write(#179,'F1-Help',#179);
  417.    SetNmMode;
  418.    if BrowseOn then exit;
  419.    if FieldCount < EndLine then EndLine := FieldCount;
  420.    x := 1;
  421.    y := 1;
  422.    for i := TopLine to pred(TopLine+EndLine) do
  423.    begin
  424.       s := Field(i);
  425.       FillChar(st[1],12,' ');
  426.       move(s[1],st[11-length(s)],length(s));
  427.       st[11] := ':';
  428.       st[0] := #12;
  429.       FieldDisplay(s,st,x,y);
  430.       case FieldType(i) of
  431.         'M' : begin
  432.                  if RecNo < 0 then FieldPutN(i,' ');
  433.                                    {If Append, make sure memo field is not}
  434.                                    {pointing to a memo block              }
  435.               end;
  436.       end;
  437.       ClrEol;
  438.       inc(y);
  439.    end;
  440. end;
  441.  
  442. Function FieldDisplayScreen : boolean;
  443. var
  444.    f,
  445.    h     : boolean;
  446. begin
  447.    h := EditOn;
  448.    EditOn := false;
  449.    f := FieldUpdateScreen;
  450.    EditOn := h;
  451.    FieldDisplayScreen := f;
  452. end;
  453.  
  454. Function FieldAppendScreen(empty : boolean) : boolean;
  455. begin
  456.    if empty then ClearRecord;
  457.    DBFActive^.CurRecord^[0] := 32;         {Ensure delete flag is off}
  458.    DBFActive^.DelFlag := false;
  459.    DBFActive^.RecNumber := -1;
  460.    FieldAppendScreen := FieldUpdateScreen;
  461. end;
  462.  
  463. Function FieldUpdateScreen : boolean;
  464. var
  465.    i,
  466.    x,
  467.    y     : integer;
  468.    st,
  469.    s     : string[12];
  470.    t     : string;
  471.    udtd  : boolean;
  472.  
  473.    Procedure UpdatePage;
  474.    var
  475.       validcmd : boolean;
  476.    begin
  477.       validcmd := false;
  478.       if ActivFld < TopLine then ActivFld := TopLine;
  479.       if ActivFld >= TopLine+EndLine then ActivFld := pred(TopLine+EndLine);
  480.       ActivLin := succ(ActivFld - TopLine);
  481.       if (ActivLin < 1) or (ActivLin > EndLine) then ActivLin := 1;
  482.       repeat
  483.          t := FieldAccept(Field(ActivFld),'',13,ActivLin);
  484.          if (EditOn) and (not GS_KeyI_Esc) then FieldPutN(ActivFld,t);
  485.  
  486.          if (not GS_KeyI_Fuc) and (GS_KeyI_Chr >= #32) then
  487.             GS_KeyI_Chr := Kbd_Ret;
  488.  
  489.             case GS_KeyI_Chr of
  490.                Kbd_F1 :   begin
  491.                              ClrScr;
  492.                              gotoxy(22,10);
  493.                              writeln('The following commands are available:');
  494.                              writeln;
  495.                              writeln('':25,
  496.                                      'Cursor Keys  - Up, Down, PgUp, PgDn');
  497.                              writeln('':25,'Next Line    - Return, Tab');
  498.                              writeln('':25,'Quit         - F10');
  499.                              writeln('':25,'Quit-No Save - Escape');
  500.                              writeln('':25,'Delete/Undel - F9');
  501.                              WaitForKey;
  502.                              ClrScr;
  503.                              DrawScreen;
  504.                           end;
  505.                Kbd_F9 :   begin
  506.                              if DeleteOnF9 then
  507.                              begin
  508.                                 if RecNo < 0 then
  509.                                 begin
  510.                                    if Deleted then
  511.                                       DBFActive^.CurRecord^[0] :=  32
  512.                                    else DBFActive^.CurRecord^[0] := 42;
  513.                                    DBFActive^.DelFlag := not DBFActive^.DelFlag;
  514.                                 end
  515.                                 else if Deleted then RecallRec else DeleteRec;
  516.                              end;
  517.                              gotoxy(3,LastLine);
  518.                              SetIvMode;
  519.                              if Deleted then write('Deleted')
  520.                                 else write('':8);
  521.                              SetNmMode;
  522.                           end;
  523.                Kbd_PgUp : begin
  524.                              if ActivFld = TopLine then
  525.                              begin
  526.                                 TopLine := TopLine-EndLine;
  527.                                 if TopLine < 1 then TopLine := 1;
  528.                                 validcmd := true;
  529.                              end
  530.                              else ActivFld := TopLine;
  531.                           end;
  532.                Kbd_PgDn : begin
  533.                              if ActivFld = pred(TopLine+EndLine) then
  534.                              begin
  535.                                 TopLine := TopLine+EndLine;
  536.                                 if TopLine > FieldCount-EndLine then
  537.                                    TopLine := succ(FieldCount-EndLine);
  538.                                 if TopLine < 1 then TopLine := 1;
  539.                                 validcmd := true;
  540.                              end
  541.                              else ActivFld := pred(TopLine+EndLine);
  542.                           end;
  543.                Kbd_UpAr : begin
  544.                              dec(ActivFld);
  545.                              if ActivFld < TopLine then
  546.                              begin
  547.                                 dec(TopLine);
  548.                                 if TopLine < 1 then TopLine := 1;
  549.                                 validcmd := true;
  550.                              end;
  551.                           end;
  552.                Kbd_RtAr,
  553.                Kbd_Tab,
  554.                Kbd_Ret,
  555.                Kbd_DnAr : begin
  556.                              inc(ActivFld);
  557.                              if ActivFld > pred(TopLine+EndLine) then
  558.                              begin
  559.                                 if ActivFld > FieldCount then
  560.                                    ActivFld := FieldCount
  561.                                 else
  562.                                 begin
  563.                                    inc(TopLine);
  564.                                    if TopLine > FieldCount then
  565.                                       TopLine := succ(FieldCount-EndLine);
  566.                                    validcmd := true;
  567.                                 end;
  568.                              end;
  569.                           end;
  570.                Kbd_Esc,
  571.                Kbd_F10  : validcmd := true;
  572.             end;
  573.  
  574.          if ActivFld < TopLine then ActivFld := TopLine;
  575.          if ActivFld >= TopLine+EndLine then ActivFld := pred(TopLine+EndLine);
  576.          ActivLin := succ(ActivFld - TopLine);
  577.          if (ActivLin < 1) or (ActivLin > EndLine) then ActivLin := 1;
  578.       until validcmd;
  579.    end;
  580.  
  581. begin
  582.    SetNmMode;
  583.    ClrScr;
  584.    DeleteOnF9 := true;
  585.    RecChanged := false;
  586.    udtd := false;
  587.    TopLine := 1;
  588.    ActivFld := TopLine;
  589.    LastLine := succ(hi(WindMax)-hi(WindMin));
  590.    EndLine := pred(LastLine);
  591.    repeat
  592.       DrawScreen;
  593.       UpdatePage;
  594.    until (GS_KeyI_Chr in [Kbd_Esc,Kbd_F10]) or
  595.          ((GS_KeyI_Chr = Kbd_PgUp) and (ActivFld = 1)) or
  596.          ((GS_KeyI_Chr = Kbd_PgDn) and (ActivFld = FieldCount));
  597.    DeleteOnF9 := false;
  598.    if GS_KeyI_Chr in [Kbd_F10, Kbd_PgUp, Kbd_PgDn] then
  599.       FieldUpdateScreen := true
  600.    else FieldUpdateScreen := false;
  601. end;
  602.  
  603.  
  604.  
  605. Procedure FieldBrowseScreen;
  606. var
  607.    lnStart,
  608.    lnEnd    : word;
  609.    broCmd   : longint;
  610.    broLines : integer;
  611.    validcmd : boolean;
  612.    CurRow   : integer;
  613.    LastRec  : longint;
  614.  
  615.    Procedure ShoBrowse;
  616.    var
  617.       i        : integer;
  618.       j        : integer;
  619.       t        : string;
  620.       th       : string;
  621.       ch       : char;
  622.       ln       : longint;
  623.    begin
  624.       GoToXY(1,1);
  625.       th := GetBrowseHeader(lnStart);
  626.       writeln(th);
  627.       writeln(GetBrowseBar(lnStart));
  628.       j := 2;
  629.       for i := 1 to broLines do
  630.       begin
  631.          t := GetBrowseLine(i, lnStart);
  632.          ln := GetBrowseRecord(i);
  633.          gotoxy(1,i+2);
  634.          if t <> '' then
  635.          begin
  636.             write(t);
  637.             inc(j);
  638.          end
  639.          else ClrEOL;
  640.       end;
  641.       if CurRow > j then CurRow := j;
  642.  
  643.       ln := GetBrowseRecord(CurRow-2);
  644.       if LastRec <> ln then
  645.       begin
  646.          SetIvMode;
  647.          if Deleted then
  648.          begin
  649.             gotoxy(3,LastLine);
  650.             write('Deleted');
  651.          end;
  652.          gotoxy(12,LastLine);
  653.          write('Browse             ');
  654.          gotoxy(19,LastLine);
  655.          write(ln,'/',RecCount);
  656.          LastRec := ln;
  657.       end;
  658.       SetHiMode;
  659.       Gotoxy(1,CurRow);
  660.       write(GetBrowseLine(CurRow-2, lnStart));
  661.       SetNmMode;
  662.       ch := GetKey;
  663.  
  664.       if (not GS_KeyI_Fuc) and (GS_KeyI_Chr >= #32) then
  665.           GS_KeyI_Chr := Kbd_Ret;
  666.  
  667.       case GS_KeyI_Chr of
  668.  
  669.          Kbd_F1   : begin
  670.                        ClrScr;
  671.                        gotoxy(22,7);
  672.                        writeln('The following commands are available:');
  673.                        writeln;
  674.                        writeln('':25,
  675.                                'Cursor Keys  - PgUp, PgDn, Up, Down,');
  676.                        writeln('':25,'               Right, Left');
  677.                        writeLn('':25,'Next Field   - Tab');
  678.                        writeLn('':25,'Prev Field   - Shift-Tab');
  679.                        writeLn('':25,'Record Start - Home');
  680.                        writeLn('':25,'Record End   - End');
  681.                        writeLn('':25,'Top of File  - Ctrl-Home');
  682.                        writeln('':25,'End of File  - Ctrl-End');
  683.                        writeln('':25,'Edit Record  - F2');
  684.                        writeln('':25,'Quit         - F10, Escape');
  685.                        WaitForKey;
  686.                        ClrScr;
  687.                        DrawScreen;
  688.                        LastRec := -1;
  689.                     end;
  690.          Kbd_F2   : begin
  691.                        EditOn := true;
  692.                        BrowseOn := false;
  693.                        ln := GetBrowseRecord(CurRow-2);
  694.                        Go(ln);
  695.                        if FieldUpdateScreen then
  696.                        begin
  697.                           Replace;
  698.                           RenewBrowseLine(CurRow-2);
  699.                        end;
  700.                        ActivLin := 0;
  701.                        BrowseOn := true;
  702.                        EditOn := False;
  703.                        EndLine := pred(LastLine);
  704.                     end;
  705.          Kbd_Home : begin
  706.                        lnStart := 1;
  707.                     end;
  708.          Kbd_End  : begin
  709.                        lnStart := 16384;
  710.                        MoveBrowseRight(lnStart);
  711.                     end;
  712.          Kbd_CHom : begin
  713.                        UpdateBrowse(broTop);
  714.                     end;
  715.          Kbd_CEnd : begin
  716.                        UpdateBrowse(broBttm);
  717.                     end;
  718.          Kbd_PgUp : begin
  719.                        UpdateBrowse(broPgUp);
  720.                     end;
  721.          Kbd_PgDn : begin
  722.                        UpdateBrowse(broPgDn);
  723.                     end;
  724.          Kbd_UpAr : begin
  725.                        if CurRow = 3 then
  726.                           UpdateBrowse(broLnUp)
  727.                        else
  728.                           dec(CurRow);
  729.                     end;
  730.          Kbd_DnAr : begin
  731.                        if CurRow >= EndLine then
  732.                           UpdateBrowse(broLnDn)
  733.                        else
  734.                           inc(CurRow);
  735.                     end;
  736.          Kbd_RtAr : begin
  737.                        MoveBrowseRight(lnStart);
  738.                     end;
  739.          Kbd_LfAr : begin
  740.                        MoveBrowseLeft(lnStart);
  741.                     end;
  742.          Kbd_Tab  : begin
  743.                        TabBrowseRight(lnStart);
  744.                     end;
  745.          Kbd_RTb  : begin
  746.                        TabBrowseLeft(lnStart);
  747.                     end;
  748.          Kbd_Esc,
  749.          Kbd_F10  : validcmd := false;
  750.       end;
  751.    end;
  752.  
  753. begin
  754.    EditOn := false;
  755.    BrowseOn := true;
  756.    SetNmMode;
  757.    DeleteOnF9 := true;
  758.    RecChanged := false;
  759.    TopLine := 1;
  760.    ActivLin := 1;
  761.    LastLine := succ(hi(WindMax)-hi(WindMin));
  762.    EndLine := pred(LastLine);
  763.    CurRow := 3;
  764.    LastRec := -1;
  765.  
  766.    lnStart := 1;
  767.    lnEnd := 79;
  768.    validCmd := true;
  769.    broCmd := broTop;
  770.    broLines := EndLine-2;
  771.    ClrScr;
  772.    DrawScreen;
  773.    StartBrowse(broLines, lnEnd);
  774.    UpdateBrowse(broCmd);
  775.    repeat
  776.       ShoBrowse;
  777.    until not validCmd;
  778.    ResetBrowse;
  779.  
  780.    DeleteOnF9 := false;
  781.    EditOn := true;
  782.    BrowseOn := false;
  783. end;
  784.  
  785. begin
  786.    BrowseOn := false;
  787.    EditOn := true;
  788.    DeleteOnF9 := false;               {Turn off F9 for delete/undelete}
  789. end.
  790.  
  791.