home *** CD-ROM | disk | FTP | other *** search
/ ftp.update.uu.se / ftp.update.uu.se.2014.03.zip / ftp.update.uu.se / pub / rainbow / msdos / misc / messages.lzh / MESSAGES.PAS < prev    next >
Pascal/Delphi Source File  |  1984-08-31  |  20KB  |  679 lines

  1. PROGRAM Messages(input,output);    { Hold messages for people by name. }
  2.  
  3.    { Written by Stew Stryker for the DEC Rainbow under CP/M  - 7/84 }
  4.    { Made more generic                 under MSDOS - 7/85 }
  5.  
  6.    { Functions:  Display names of message holders on screen
  7.             and optionally on comm port terminal
  8.          Add new messages to list and save to file
  9.          Print messages + mark deleted in file
  10.          Allow user to define title and printout message
  11.          Provide menu of above functions          }
  12.  
  13. {$C-}           { Set up so ^C not allowed, which helps KEYPRESSED }
  14.  
  15.    CONST
  16.       ProgramVersion = '1.0';
  17.       MaxNumOfHolders = 1200;
  18.       MaxNumOfDeleted = 500;
  19.       ProgramTitle = 'Telephone Message System';
  20.       BottomTitle = 'Telephone Messages';
  21.       DHTH = ^['#3';
  22.       DHBH = ^['#4';
  23.       DW   = ^['#6';
  24.       Reverse = ^['[7m';
  25.       Bold = ^['[1m';
  26.       Norm = ^['[0m';
  27.       LenLast = 20;
  28.       LenFirst = 20;
  29.       LenFrom = 40;
  30.       LenName = 40;  { Length of full name }
  31.       LenPhone = 13;
  32.       LenDate = 20;
  33.       LenMessage = 60;
  34.  
  35.       Const
  36.          GrOn = ^['(0';
  37.          GrOff = ^['(B';
  38.          Vln = 'x';
  39.          Hln = 'q';
  40.          Ulc = 'l';
  41.          Urc = 'k';
  42.          llc = 'm';
  43.          lrc = 'j';
  44.         
  45. {$I FASTVID.INC }  { Fast Video used by new data input routines }
  46.  
  47.    TYPE
  48.       Message = RECORD
  49.         LName     : STRING[LenLast];
  50.         FName     : STRING[LenFirst];
  51.         From     : STRING[LenFrom];
  52.         Phone     : STRING[LenPhone];
  53.         DateTime : STRING[LenDate];
  54.         Message1 : STRING[LenMessage];
  55.         Message2 : STRING[LenMessage];
  56.         Deleted  : BOOLEAN;
  57.         END;
  58.       Holder = RECORD
  59.            LName     : STRING[LenLast];
  60.            FName     : STRING[LenFirst];
  61.            RecordNum : INTEGER;
  62.            END;
  63.       STR80   = String[80];
  64.       LString = String[80];
  65.       NameString = STRING[LenName];
  66.  
  67.    VAR
  68.       MessageFile : FILE OF MESSAGE;
  69.       MessageHolder : ARRAY[1..MaxNumOfHolders] OF HOLDER;
  70.       DeletedRecNum : ARRAY[1..MaxNumOfDeleted] OF INTEGER;
  71.       CommPort, ToggleFormLength : BOOLEAN;
  72.       InputChar : CHAR;
  73.       NumFileRecs, CurrDisp, Row, Col, NumOfDeleted, FileRecNum,
  74.      FormLength, NumOfHolders : INTEGER;
  75.       MiscTitle, TopTitle, SysMessage : STR;
  76.       NewMessage : MESSAGE;
  77.      I : Integer;
  78.      HBar : Str;
  79.  
  80. {$I EXIST.INC }    { Function to determine if file exists }
  81. {$I MESSADD.INC }  { Data entry screen for adding new messages }
  82. {$I MESSMORE.INC } { Data entry screen for adding more recipients }
  83. {$I STRING.INC }   { String manipulation functions }
  84.  
  85.    FUNCTION FnMove(Col,Row : INTEGER) : STR;
  86.       VAR
  87.      RowText, ColText : STRING[2];
  88.       BEGIN
  89.      IF Row >= 10 THEN STR(Row:2,RowText)
  90.         ELSE STR(Row:1,RowText);
  91.      IF Col >= 10 THEN STR(Col:2,ColText)
  92.         ELSE STR(Col:1,ColText);
  93.      FnMove := ^[ + '[' + RowText + ';' + ColText + 'H';
  94.      END; { FnMove }
  95.  
  96.    FUNCTION FindNextHolder(MatchString : NAMESTRING) : INTEGER;
  97.       { Search the list of holders for the record # with a key after
  98.     that in the new message }
  99.       VAR
  100.      HolderString : STRING[41];
  101.      Counter : INTEGER;
  102.       BEGIN
  103.      Counter := 0;
  104.      HolderString := ' ';
  105.      MatchString := UpperCase(MatchString);
  106.      REPEAT
  107.         Counter := Counter + 1;
  108.         IF Counter <= NumOfHolders THEN
  109.            HolderString := UpperCase(TrimR(MessageHolder[Counter].LName) +
  110.                    TrimR(MessageHolder[Counter].FName));
  111.         UNTIL (Counter > NumOfHolders) OR (MatchString <= HolderString);
  112.      FindNextHolder := Counter;
  113.      END; { FindNextHolder }
  114.  
  115.  
  116.    PROCEDURE DisplayMessageHolders;
  117.       LABEL StopDisplay;
  118.  
  119.       CONST
  120.      RegionOn = ^['[3;22r';
  121.      RegionOff = ^['[1;24r';
  122.      ClrHome = ^['[H'^['[2J';
  123.      Flash = ^['[5m';
  124.      TopLine = 3;
  125.      BottomLine = 22;
  126.       VAR
  127.      InputChar : CHAR;
  128.      HolderName,DummyString : STRING[42];
  129.       BEGIN
  130.      { If there are no messages, don't display anything. }
  131.      If NumOfHolders = 0
  132.         Then Begin
  133.            GotoXY(10,24);
  134.            NormVideo;
  135.            Write(^G,^G,'There are no messages to display.');
  136.            LowVideo;
  137.            Delay(4000);
  138.            Goto StopDisplay;
  139.            End; { If there are no messages to display. }
  140.  
  141.      { Set up scroll region, and display titles, first for screen,
  142.        then for comm port, if necessary }
  143.      ClrScr;
  144.      WRITE(RegionOn);
  145.      GOTOXY(1,1);
  146. {      NormVideo;         }
  147.      WRITE(Reverse,DHTH,PadR(Center(TopTitle,40),40));
  148.      GOTOXY(1,2);
  149.      WRITE(DHBH,PadR(Center(TopTitle,40),40));
  150.      GOTOXY(1,23);
  151.      WRITE(DHTH,PadR(Center(BottomTitle,40),40));
  152.      GOTOXY(1,24);
  153.      WRITE(DHBH,PadR(Center(BottomTitle,40),40),Norm);
  154.      NormVideo;
  155.  
  156.      { Send same to comm port, if necessary }
  157.      IF CommPort THEN BEGIN
  158.         WRITE(Aux,ClrHome);
  159.         WRITE(Aux,RegionOn);
  160.         WRITE(Aux,FnMove(1,1));
  161.  {         WRITE(Aux,Norm); }
  162.         WRITE(Aux,Reverse,DHTH,PadR(Center(TopTitle,40),40));
  163.         WRITE(Aux,FnMove(1,2));
  164.         WRITE(Aux,DHBH,PadR(Center(TopTitle,40),40));
  165.         WRITE(Aux,FnMove(1,23));
  166.         WRITE(Aux,DHTH,PadR(Center(BottomTitle,40),40));
  167.         WRITE(Aux,FnMove(1,24));
  168.         WRITE(Aux,DHBH,PadR(Center(BottomTitle,40),40));
  169.         WRITE(Aux,Bold);
  170.         END; { Sending titles to the comm port }
  171.  
  172.  
  173.      { You've just turned off reverse video, and turned bold on }
  174.      IF (CurrDisp < 1) Or (CurrDisp > NumOfHolders)
  175.         THEN CurrDisp := 1;
  176.      { Until a key is pressed, Display the names of the message holders }
  177.      REPEAT
  178.         WITH MessageHolder[CurrDisp] DO
  179.            HolderName := LName + ', ' + FName;
  180.         GOTOXY(1,BottomLine);
  181.         IF CommPort THEN WRITE(Aux,FnMove(1,BottomLine));
  182.         WRITELN(DHTH,HolderName);
  183.         IF CommPort THEN WRITELN(Aux,DHTH,HolderName);
  184.         WRITELN(DHBH,HolderName);
  185.         IF CommPort THEN WRITELN(Aux,DHBH,HolderName);
  186.         CurrDisp := (CurrDisp + 1) MOD (NumOfHolders + 1);
  187.         IF CurrDisp = 0 THEN CurrDisp := 1;
  188.         UNTIL Keypressed;
  189.  
  190.      StopDisplay:
  191.      WRITE(RegionOff,Norm);
  192.  
  193.      { Set up comm port with "Updating" message, if necessary }
  194.      IF CommPort THEN BEGIN
  195.         WRITE(Aux,RegionOff,Flash);
  196.         WRITE(Aux,FnMove(1,23));
  197.         WRITE(Aux,DHTH,Center('Updating Telephone Messages',40));
  198.         WRITE(Aux,FnMove(1,24));
  199.         WRITE(Aux,DHBH,Center('Updating Telephone Messages',40));
  200.         WRITE(Aux,FnMove(1,24),' ',^H);
  201.         END; { Stopping display to comm port }
  202.  
  203.      ClrScr;
  204.      END;    { DisplayMessageHolders }
  205.  
  206.  
  207.    PROCEDURE AddHolder;
  208.      { Add new name and record number to Message Holder array }
  209.       VAR
  210.      Counter, PositionToInsertHolder : INTEGER;
  211.       BEGIN
  212.      PositionToInsertHolder := FindNextHolder(NewMessage.LName +
  213.                           NewMessage.FName);
  214.      NumOfHolders := NumOfHolders + 1;
  215.      { Move all subsequent holders down list }
  216.      FOR Counter := NumOfHolders DOWNTO PositionToInsertHolder + 1 DO
  217.         MessageHolder[Counter] := MessageHolder[Counter - 1];
  218.      { Add new Holder to list }
  219.      WITH MessageHolder[PositionToInsertHolder] DO BEGIN
  220.         LName := NewMessage.LName;
  221.         FName := NewMessage.FName;
  222.         RecordNum := FileRecNum;
  223.         END;
  224.      END; { AddHolder }
  225.  
  226.  
  227.    Procedure SetSystemTitles;
  228.       { Set and save system titles }
  229.       Var
  230.      SaveMessage : Char;
  231.      TempLength : Integer;
  232.      TitleFile : Text;
  233.      TempToggle, TempTitle, TempMessage : STR80;
  234.  
  235. {$I MESSSET.INC }  { Data entry screen for entering system titles }
  236.  
  237.       Begin
  238.      { Get titles and ask if they want to save them }
  239.      SaveMessage := ' ';
  240.      If (FormLength < 33) Or (FormLength > 66)
  241.         Then FormLength := 33;
  242.      TempLength := FormLength;
  243.  
  244.      Repeat
  245.         ClrScr;
  246.         MessSet;  { Get input for new message titles }
  247.         Until (TempLength > 32) And (TempLength < 67);
  248.  
  249.      GotoXY(1,24);
  250.      MiscTitle := 'Do you want to save these titles to the disk? (Y/N)';
  251.      Write(TrimR(Center(MiscTitle,80)));
  252.      Read(Kbd,SaveMessage);
  253.      If TrimR(TempTitle) > ''         { Only save these if   }
  254.         Then TopTitle := TempTitle;
  255.      If TrimR(TempMessage) > ''         { they've been changed }
  256.         Then SysMessage := TempMessage;
  257.      FormLength := TempLength;
  258.  
  259.      If UpCase(SaveMessage) = 'Y'
  260.         Then
  261.            Begin
  262.           Writeln;
  263.           Writeln('Saving titles.');
  264.           { Save to file }
  265.           Assign(TitleFile,'MESSAGES.MAS');
  266.           Rewrite(TitleFile);
  267.           Writeln(TitleFile,TopTitle);
  268.           Writeln(TitleFile,SysMessage);
  269.           Writeln(TitleFile,FormLength);
  270.           Close(TitleFile);
  271.           End; { If they wanted to save the titles }
  272.  
  273.      End; { Procedure SetSystemTitles }
  274.  
  275.  
  276.  
  277.    PROCEDURE InitializeProgram;
  278.       { Set up files and things }
  279.       VAR
  280.      OK : BOOLEAN;
  281.      TitleFile : Text;
  282.  
  283.       BEGIN
  284.      { Initialize variables }
  285.      NumFileRecs := 0;
  286.      NumOfDeleted := 0;
  287.      NumOfHolders := 0;
  288.      TopTitle := ' ';     { Initialize these to blanks }
  289.      SysMessage := ' ';
  290.  
  291.      { Read in system's title and message }
  292.      If Exist('MESSAGES.MAS') Then
  293.         Begin
  294.            Assign(TitleFile,'MESSAGES.MAS');
  295.            Reset(TitleFile);
  296.            Readln(TitleFile,TopTitle);
  297.            Readln(TitleFile,SysMessage);
  298.            Readln(TitleFile,FormLength);
  299.            Close(TitleFile);
  300.            End
  301.         Else SetSystemTitles;  { Get user's title inputs }
  302.  
  303.      { Open message data file, or create if necessary }
  304.      Writeln;
  305.      Writeln('Checking for messages...');
  306.      ASSIGN(MessageFile,'MESSAGES.DAT');
  307.      {$I-} RESET(MessageFile) {$I+};
  308.      OK := (IOresult = 0);
  309.      IF NOT OK
  310.         THEN REWRITE(MessageFile)       { Create a new file }
  311.         Else Write('Reading messages');
  312.  
  313.      { If OK, you should read the file of old messages, and set up
  314.        your arrays and counters again. }
  315.      IF OK THEN
  316.         WHILE NOT EOF(MessageFile) DO BEGIN
  317.            READ(MessageFile,NewMessage);
  318.            IF NewMessage.Deleted = TRUE THEN
  319.           BEGIN
  320.              NumOfDeleted := NumOfDeleted + 1;
  321.              DeletedRecNum[NumOfDeleted] := NumFileRecs;
  322.              END  { If message has been deleted }
  323.           ELSE
  324.              BEGIN
  325.              FileRecNum := NumFileRecs;
  326.              AddHolder;   { Add this name to sorted holder list }
  327.              WRITE('.');
  328.              END;
  329.            NumFileRecs := NumFileRecs + 1;
  330.  
  331.            END; { While there are messages to be read }
  332.      NumOfHolders := NumFileRecs - NumOfDeleted;
  333.  
  334.      { Check if they have a terminal on the comm port }
  335.      ClrScr;
  336.      NormVideo;
  337.         { Draw program title }
  338.         Hbar := '';
  339.         For I := 1 to 26 Do Hbar := Hbar + Hln;
  340.         GOTOXY(6,1);
  341.         Write(GrOn,DW,Ulc);
  342.         Write(Hbar,Urc);
  343.         GOTOXY(6,2);
  344.         Write(DHTH,Vln,GrOff,' ',ProgramTitle,' ',GrOn,Vln);
  345.         GOTOXY(6,3);
  346.         Write(DHBH,Vln,GrOff,' ',ProgramTitle,' ',GrOn,Vln);
  347.         GOTOXY(6,4);
  348.         Write(DW,Llc,HBar,Lrc,GrOff);
  349.  
  350.          LowVideo;
  351.          GOTOXY(1,5);
  352.      Writeln(Center('Version '+ProgramVersion+' by Stew Stryker',80));
  353.      GOTOXY(1,12);
  354.      LowVideo;
  355.      WRITELN(Center('Do you have a terminal',80));
  356.      WRITE(Center('attached to the communications port? (Y/N) ',
  357.         80));
  358.      NormVideo;
  359.      Repeat
  360.         READ(Kbd,InputChar);
  361.         Until InputChar In ['Y','y','N','n'];
  362.      IF UpCase(InputChar) = 'Y' THEN CommPort := TRUE
  363.         ELSE CommPort := FALSE;
  364.  
  365.      END; { Initialize Program }
  366.  
  367.  
  368.  
  369.    FUNCTION FindThisHolder(MatchString : NAMESTRING) : INTEGER;
  370.       { Search the list of holders for the record # with a key after
  371.     that in the new message }
  372.       VAR
  373.      HolderString : STRING[41];
  374.      Counter : INTEGER;
  375.       BEGIN
  376.      Counter := 0;
  377.      HolderString := ' ';
  378.      MatchString := UpperCase(MatchString);
  379.      REPEAT
  380.         Counter := Counter + 1;
  381.         IF Counter <= NumOfHolders THEN
  382.            HolderString := UpperCase(MessageHolder[Counter].LName +
  383.                    MessageHolder[Counter].FName);
  384.         UNTIL (Counter > NumOfHolders) OR (MatchString >= HolderString);
  385.      FindThisHolder := Counter;
  386.      END; { FindThisHolder }
  387.  
  388.    PROCEDURE SaveMsg;
  389.       { Save the new message to the holder array, and to the file }
  390.       BEGIN
  391.      NewMessage.Deleted := False;
  392.      { Save message to file }
  393.      IF NumOfDeleted > 0 THEN
  394.         BEGIN
  395.            FileRecNum := DeletedRecNum[NumOfDeleted];
  396.            NumOfDeleted := NumOfDeleted - 1;
  397.            END
  398.      ELSE BEGIN
  399.         FileRecNum := NumFileRecs;
  400.         NumFileRecs := NumFileRecs + 1;
  401.         END;
  402.      { Save new message to disk, and ensure it was written }
  403.      SEEK(MessageFile,FileRecNum);
  404.      WRITE(MessageFile,NewMessage);
  405.      FLUSH(MessageFile);
  406.  
  407.      AddHolder;
  408.      WRITE('Saved.');
  409.      END; { SaveMsg }
  410.  
  411.    PROCEDURE CarbonCopy;
  412.       { Send a copy of a message to another recipient }
  413.       VAR
  414.      SendThisCopy : CHAR;
  415.       BEGIN
  416.  
  417.         MessMore; { Get name of next recipient }
  418.         GOTOXY(1,22);
  419.         CLREOL;
  420.        MiscTitle := 'Do you want to send this copy? (Y/N) ';
  421.         Write(TrimR(Center(MiscTitle,80)));
  422.         Read(Kbd,SendThisCopy);
  423.         GOTOXY(1,22);
  424.         ClrEol;
  425.         GOTOXY(38,22);
  426.         If UpCase(SendThisCopy) = 'Y' Then
  427.            SaveMsg;
  428.  
  429.      End; { Procedure CarbonCopy }
  430.  
  431.  
  432.    PROCEDURE AddNewMessages;
  433.       { Keep adding new messages until they say no to another }
  434.       VAR
  435.      AnotherMessage, AnotherCopy, SaveThisMessage : CHAR;
  436.       BEGIN
  437.      AnotherMessage := 'Y';
  438.      WHILE AnotherMessage = 'Y' DO BEGIN
  439.         MessAdd; { Get the input from the included routine }
  440.  
  441.         GOTOXY(1,22);
  442.         { Check to see if they want to save this message }
  443.         SaveThisMessage := 'N';
  444.         MiscTitle := 'Do you want to save this message? (Y/N) ';
  445.         WRITE(TrimR(Center(MiscTitle,80)));
  446.         READ(Kbd,SaveThisMessage);
  447.         GOTOXY(1,22);
  448.         ClrEol;
  449.         GOTOXY(38,22);
  450.         IF UpCase(SaveThisMessage) = 'Y' THEN
  451.            SaveMsg;
  452.  
  453.         { Allow user to send carbon copy to another person }
  454.         AnotherCopy := 'Y';
  455.         While UpCase(AnotherCopy) = 'Y' Do Begin
  456.            GOTOXY(1,23);
  457.            CLREOL;
  458.           MiscTitle :=
  459.          'Do you wish to send another copy of this message? (Y/N) ';
  460.            Write(TrimR(Center(MiscTitle,80)));
  461.            Read(Kbd,AnotherCopy);
  462.            GOTOXY(1,23);
  463.            ClrEol;
  464.            If UpCase(AnotherCopy) = 'Y'
  465.           Then CarbonCopy;
  466.            End; { While they want to send another copy }
  467.  
  468.         { Allow user to add another message }
  469.         GOTOXY(1,24);
  470.         CLREOL;
  471.        MiscTitle := 'Do you want to add another message? (Y/N) ';
  472.        WRITE(TrimR(Center(MiscTitle,80)));
  473.        READ(Kbd,AnotherMessage);
  474.        AnotherMessage := UpCase(AnotherMessage);
  475.        END; { While AnotherMessage }
  476.     END; { AddNewMessages }
  477.  
  478.    PROCEDURE DeleteMessage(HolderNum : INTEGER);
  479.       { Add record to deleted list, mark message in file deleted,
  480.     Remove from holder list }
  481.       VAR
  482.      FileRecNum, Counter : INTEGER;
  483.       BEGIN
  484.      { Add to deleted list }
  485.      FileRecNum := MessageHolder[HolderNum].RecordNum;
  486.      NumOfDeleted := NumOfDeleted + 1;
  487.      DeletedRecNum[NumOfDeleted] := FileRecNum;
  488.  
  489.      { Mark file message as deleted }
  490.      SEEK(MessageFile, FileRecNum);
  491.      READ(MessageFile, NewMessage);
  492.      NewMessage.Deleted := TRUE;
  493.      SEEK(MessageFile, FileRecNum);
  494.      WRITE(MessageFile, NewMessage);
  495.      FLUSH(MessageFile);
  496.  
  497.      { Remove holder from holder list }
  498.      NumOfHolders := NumOfHolders - 1;
  499.      FOR Counter := HolderNum TO NumOfHolders DO
  500.         MessageHolder[Counter] := MessageHolder[Counter + 1];
  501.  
  502.      END; { DeleteMessage }
  503.  
  504.    PROCEDURE PrintMessage(HolderNum : INTEGER);
  505.       { Print message on the printer }
  506.       CONST
  507.      FormOffset = 21;
  508.      Margin = '    ';
  509.       VAR
  510.      TabStop, Counter : INTEGER;
  511.       BEGIN
  512.      Writeln(Lst,Bold,TrimR(Center('Telephone Message System',80)),Norm);
  513.      Writeln(Lst,TrimR(Center('(Provided by RONNIE Support Group)',80)));
  514.      Writeln(Lst);
  515.      WRITELN(Lst,Bold,TrimR(Center(TopTitle,80)),Norm);
  516.      WRITELN(Lst);
  517.      WRITELN(Lst);
  518.      WRITELN(Lst);
  519.      FileRecNum := MessageHolder[HolderNum].RecordNum;
  520.      SEEK(MessageFile,FileRecNum);
  521.      READ(MessageFile,NewMessage);
  522.      WITH NewMessage DO BEGIN
  523.         WRITELN(Lst,Margin,PadR('TO:  '+LName+', '+FName,50),
  524.            'D/T: ',DateTime);
  525.         WRITELN(Lst);
  526.         WRITELN(Lst,Margin,PadR('FROM:  '+From,50),
  527.            'TEL:  ', Phone);
  528.         WRITELN(Lst);
  529.         WRITELN(Lst);
  530.         Writeln(Lst,Margin,'------------------------------------',
  531.            ' Message ',    '------------------------------------');
  532.         WRITELN(Lst,Margin,Message1);
  533.         WRITELN(Lst,Margin,'      ',Message2);
  534.         END;
  535.  
  536.      { Insert spaces to fill out form }
  537.      FOR Counter := 1 to (FormLength - FormOffset) DO WRITELN(Lst);
  538.  
  539.      { Print footer }
  540.      WRITELN(Lst,TrimR(Center('DIGITAL EQUIPMENT CORPORATION',80)));
  541.      WRITELN(Lst,TrimR(Center(SysMessage,80)));
  542.      WRITELN(Lst);
  543.      WRITELN(Lst);
  544.      WRITELN(Lst);
  545.      WRITELN(Lst);
  546.      END; { Print Messages }
  547.  
  548. PROCEDURE FindMessages;
  549.    { Let the user search the list for a message holder }
  550.    VAR
  551.       Found, SearchAgain : CHAR;
  552.       SearchFirst : STRING[LenFirst];
  553.       SearchLast  : STRING[LenLast];
  554.       SearchNum   : INTEGER;
  555.    {$I MESSSEAR.INC } { Include file to enter search name }
  556.  
  557.    BEGIN
  558.       SearchAgain := 'Y';
  559.       WHILE SearchAgain = 'Y' DO BEGIN
  560.      ClrScr;
  561.      MessSear;   {Get input of the name to search for from Include }
  562.      SearchNum := FindNextHolder(TrimR(SearchLast) +
  563.         TrimR(SearchFirst));
  564.      GOTOXY(20,20);
  565.      IF (SearchNum < 1) OR (SearchNum > NumOfHolders) THEN
  566.         WRITELN('I can''t find anyone by that name!')
  567.         ELSE BEGIN
  568.           WRITE('Is ',MessageHolder[SearchNum].FName,
  569.              ' ',MessageHolder[SearchNum].LName,
  570.              ' the one you want? (Y/N) ');
  571.           READ(Kbd,Found);
  572.            IF UpCase(Found) = 'Y' THEN
  573.           BEGIN
  574.              Writeln;
  575.              Writeln('Printing message...');
  576.              PrintMessage(SearchNum);
  577.              Writeln('Deleting message...');
  578.              DeleteMessage(SearchNum);
  579.              END; { This is the right one }
  580.            END; { There was some sort of match }
  581.      GOTOXY(20,24);
  582.      WRITE('Do you want to search again? (Y/N) ');
  583.      READ(Kbd,SearchAgain);
  584.      SearchAgain := UpCase(SearchAgain);
  585.      END; { Search until they don't want to search again }
  586.       END; { FindMessages }
  587.  
  588.  
  589.    PROCEDURE Menu;
  590.       BEGIN
  591.      InputChar := ' ';
  592.         ClrScr;
  593.         NormVideo;
  594.  
  595.         { Draw program title }
  596.         Hbar := '';
  597.         For I := 1 to 26 Do Hbar := Hbar + Hln;
  598.         GOTOXY(6,1);
  599.         Write(GrOn,DW,Ulc);
  600.         Write(Hbar,Urc);
  601.         GOTOXY(6,2);
  602.         Write(DHTH,Vln,GrOff,' ',ProgramTitle,' ',GrOn,Vln);
  603.         GOTOXY(6,3);
  604.         Write(DHBH,Vln,GrOff,' ',ProgramTitle,' ',GrOn,Vln);
  605.         GOTOXY(6,4);
  606.         Write(DW,Llc,HBar,Lrc,GrOff);
  607.  
  608.         LowVideo;
  609.         GOTOXY(20 - (Length(TopTitle) Div 2),5);
  610.         WRITE(DW,Reverse,TrimL(TrimR(Center(TopTitle,40))),Norm);
  611.  
  612.  
  613.         GOTOXY(14,8);
  614.         WRITE(DW);
  615.         NormVideo;
  616.         WRITE('A');
  617.         LowVideo;
  618.         WRITE('dd New Messages');
  619.  
  620.         GOTOXY(14,10);
  621.         WRITE(DW);
  622.         NormVideo;
  623.         WRITE('D');
  624.         LowVideo;
  625.         WRITE('isplay Messages');
  626.  
  627.         GOTOXY(14,12);
  628.         WRITE(DW);
  629.         NormVideo;
  630.         Write('C');
  631.         LowVideo;
  632.         Write('hange System Titles');
  633.  
  634.         GOTOXY(14,14);
  635.         WRITE(DW);
  636.         NormVideo;
  637.         WRITE('F');
  638.         LowVideo;
  639.         WRITE('ind Messages');
  640.  
  641.         GOTOXY(14,16);
  642.         WRITE(DW);
  643.         Normvideo;
  644.         WRITE('Q');
  645.         LowVideo;
  646.         WRITE('uit program');
  647.  
  648.         GOTOXY(50,24);
  649.         WRITE('There are ',NumOfHolders,' messages.');
  650.  
  651.         GOTOXY(1,21);
  652.         WRITE(DW);
  653.         NormVideo;
  654.         WRITE('PLEASE ENTER CHOICE (A,D,C,F,Q): ');
  655.         LowVideo;
  656.      InputChar := ' ';
  657.      WHILE NOT (InputChar IN ['A','D','C','F','Q']) DO
  658.         BEGIN
  659.            GOTOXY(33,21);
  660.            Read(Kbd,InputChar);
  661.            InputChar := UpCase(InputChar);
  662.            END; { Getting input until it is one of the choices }
  663.         END; { Menu }
  664.  
  665.    BEGIN { Main program }
  666.       InitializeProgram;
  667.       REPEAT
  668.      Menu;
  669.      CASE InputChar OF
  670.         'A' : AddNewMessages;
  671.         'D' : DisplayMessageHolders;
  672.         'C' : SetSystemTitles;
  673.         'F' : FindMessages;
  674.         END; { CASE statement }
  675.      UNTIL InputChar = 'Q';
  676.       CLOSE(MessageFile);
  677.       END.
  678.  
  679.