I.T. Discussion Community!
-Collapse +Expand
C++
Search C++ Group:

Advanced
-Collapse +Expand C++ To/From
To/FromCODEGuides
-Collapse +Expand C++ Study Test
PRESTWOODCERTIFIED
-Collapse +Expand C++ Store
PRESTWOODSTORE

Prestwood eMagazine

October Edition
Subscribe now! It's Free!
Enter your email:

   ► KBProgrammingC++Classic C La...   Print This     
 
C++ Classic C Language:
Old MS DOS Based Borland Turbo C For Scrolling Through A Binary Text File Of Fixed Width Records
 
Posted 89 days ago on 7/25/2017
Take Away:

This article describes the procedural C programming for an old MS-DOS based application to scroll and page rows of records in a list retrieved from a binary text file.

KB102798



INTRODUCTION

The list scrolling technology we take for granted today on our computers, smart phones and tablets was still a fleeting idea in the programming world about 25 years ago. Back then, nothing was pre-programmed for you, no Windows form controls, no software plug-ins...nothing. You had to code it all by hand one line at a time.





Here I will present a glimpse into the type of coding that was required to survive in this rough and tumble era of line-by-line programming code development. Below I have illustrated an example of a Borland Turbo C 3.0 program I made for scrolling up and down one record at a time and  for paging up and down 22 records at a time.

KEYS USED TO FACILITATE LIST NAVIGATION

  • Upward scrolling {UP ARROW KEY}; ascii code sequence: 0, 72
  • Downward scrolling {DOWN ARROW KEY}; ascii code sequence: 0, 80
  • Upward paging {PAGE UP KEY}; ascii code sequence: 0, 73
  • Downward paging {PAGE DOWN KEY}; ascii code sequence: 0, 81

HOW KEYBOARD INPUT WAS HANDLED

The scrolling and paging is encapsulated in a "do while loop". I use two chars I call "char_receive1" and " char_receive2" to receive and process keyboard input. More specifically:



// trap the key strokes for the keys pressed. The

// keys used here will send ascii code 0 to be trapped

// by the char “char_receive1” and then the specific ascii code that

// follows will be trapped by the char “char_receive2” if the char “char_receive1”

// has previously trapped ascii code 0.

char_receive2 = 0;

char_receive1 = getch();

if( char_receive1 == 0 ) char_receive2 = getch();



If the char "char_receive1" receives the null character "0", then the char "char_receive2" will receive the character that comes right after it (72, 80, 73 or 81) as specified in the previous section. The "do while loop" stays active until the user presses either the escape or the return key on the keyboard. After the "do while loop" is exited, further processing will take place. I generally used the escape character to denote an "abort" and the return character to be interpreted as a "selection of a record".



// exit the "do while loop" if a name has been selected with

// the ascii code 13 (return) or cancelled with the ascii code 27 (escape).

} while( char_receive1 != 13 && char_receive1 != 27 );





PRESENTING THE ENTIRE CODE

This is the Turbo C code in its entirety. I have tried to use descriptive names for the different variables that make the program work. As complex as it is, I thought this would be the best way to foster a better understanding of it. Pictures of how it works follow the code readout to give you a visual idea of what it does.



// declare C headers.

#include "conio.h"

#include "stdio.h"

main()

{

FILE       *fp;

int           a,view_port_row_cntr,loop_cntr;

long int   offset_next_22_records,internal_record_cntr,file_posit_offset,  start_next_22_records;

char       char_receive1,char_receive2;

// open a “read only” file stream to a binary file text. there

// are a maximum of 100 records in this fixed width binary data

// file. each "name" record is 27 characters in length. the exit(1)

// directive will abort the file open if a NULL is returned for a

// non-existent file by the specified name.

if (( fp = fopen("namefile.txt", "rb")) == NULL ) exit(1);

// set the on screen view port dimensions, colors

// and title for the MS-DOS scrolling/paging screen.

window(1,1,80,25);

  // text color is yellow.

  textcolor(14);

    // border background color is magenta.

    textbackground(5);

      // clear the screen.

      clrscr();

       gotoxy(37, 1);

        cputs("NAME");

         window(1,2,80,23);

           // midscreen background color is blue.

           textbackground(9);

             clrscr();

// display the first 22 records in the view port window.

loop_cntr = 0;

 file_posit_offset = 0;

    do {

     gotoxy(37, loop_cntr + 1);

      fseek( fp, file_posit_offset, 0 );

         for ( a = 0; a < 20; a++ ) putch(getc(fp));

          loop_cntr ++;

           file_posit_offset = file_posit_offset + 27;

    } while ( loop_cntr < 22 );

// set the view port row counter to 1.

view_port_row_cntr = 1;

  // set the internal record counter to 0.

  internal_record_cntr = 0;

   // set the data file position offset to 0.

   file_posit_offset = 0;

     // position the highlighted cursor bar on the first row of the 22 displayed records.

     textbackground(15);

      textcolor(0);

       gotoxy(37, 1);

        fseek( fp, file_posit_offset, 0 );

            for( a = 0; a < 20; a++ ) putch(getc(fp));

             gotoxy(5, 1);

              textbackground(9);

               textcolor(14);

// begin the "do while loop" for navigating

// through the binary fixed width data file, "namefile.txt".

do {

// trap the key strokes for the keys pressed. The

// keys used here will send ascii code 0 to be trapped

// by the char “char_receive1” and then the specific ascii code that

// follows will be trapped by the char “char_receive2” if the char “char_receive1”

// has previously trapped ascii code 0.

char_receive2 = 0;

char_receive1 = getch();

if( char_receive1 == 0 ) char_receive2 = getch();

// this will process the mechanics of scrolling up one record.

if ( char_receive2 == 72 ) {

 // decrement view port row counter by 1.

 view_port_row_cntr--;

  // decrement internal record counter by 1.

  internal_record_cntr--;

   // decrement the file position offset by 1 record.

   file_posit_offset = file_posit_offset - 27;

// if the view port row counter is greater than or equal to 1

// then set the next record to the view port colors and set the

// current record to be highlighted.

if ( view_port_row_cntr >= 1 ) {

 textbackground(9);

  textcolor(14);

   gotoxy(37, view_port_row_cntr +1);

    fseek( fp, file_posit_offset + 27, 0 );

       for ( a = 0; a < 20; a++ ) putch(getc(fp));

        textbackground(15);

         textcolor(0);

          gotoxy(37, view_port_row_cntr);

           fseek( fp, file_posit_offset, 0 );

               for ( a = 0; a < 20; a++ ) putch(getc(fp));

                textbackground(9);

                 textcolor(14);

                  gotoxy(5, view_port_row_cntr);

}

// if the view port row counter is less than 1 and

// the internal record counter is greater than -1

// then set the view port row counter to 1 and

// then clear the bottom row on the view port and

// insert a new line at the very top of the view port

// and then set the top row to be highlighted.

if ( view_port_row_cntr < 1 && internal_record_cntr > -1 ) {

 view_port_row_cntr = 1;

  gotoxy(5, 22);

   // clear to end of line.

   clreol();

    gotoxy(5, 1);

// insert a line here.

insline();

 textbackground(15);

  textcolor(0);

   gotoxy(37, 1);

    fseek( fp, file_posit_offset, 0 );

       for ( a = 0; a < 20; a++ ) putch(getc(fp));

        textbackground(9);

         textcolor(14);

          gotoxy(37, view_port_row_cntr + 1);

            fseek( fp, file_posit_offset + 27, 0 );

               for ( a = 0; a < 20; a++ ) putch(getc(fp));

                textbackground(15);

                 textcolor(0);

                  gotoxy(37, view_port_row_cntr);

                    fseek( fp, file_posit_offset, 0 );

                       for ( a = 0; a < 20; a++ ) putch(getc(fp));

                        textbackground(9);

                         textcolor(14);

                          gotoxy(5, 1);

}

// if the view port row counter is less than 1 and

// the internal record counter is less than 0 then

// set the view port row counter to 1 and set the

// internal row counter to 0. increment the data file

// position offset by 1 record length and position the

// cursor at the top row in the view port.

if ( view_port_row_cntr < 1 && internal_record_cntr < 0 ) {

 view_port_row_cntr = 1;

  internal_record_cntr = 0;

   gotoxy(5, 1);

    file_posit_offset = file_posit_offset + 27;

}

}

// this will process the mechanics of scrolling down one record.

if( char_receive2 == 80 ) {

 // increment view port row counter by 1.

 view_port_row_cntr++;

  // increment internal record counter by 1.

  internal_record_cntr++;

   // increment the file position offset by 1 record.

   file_posit_offset = file_posit_offset + 27;

// if the view port row counter is less than 23 then set

// the prior record to the view port colors and set the

// current record to be highlighted.

if ( view_port_row_cntr < 23 ) {

 textbackground(9);

  textcolor(14);

   gotoxy(37, view_port_row_cntr - 1);

    fseek( fp, file_posit_offset - 27, 0 );

       for ( a = 0; a < 20; a++ ) putch(getc(fp));

        textbackground(15);

         textcolor(0);

          gotoxy(37, view_port_row_cntr);

           fseek( fp, file_posit_offset, 0 );

              for ( a = 0; a < 20; a++ ) putch(getc(fp));

               textbackground(9);

                textcolor(14);

                 gotoxy(5, view_port_row_cntr);

}

// if the view port row counter is greater than 22 and

// the internal record counter is less than 100

// then set the view port row counter to 22 and

// then delete the top row on the view port and then set

// the bottom row to be highlighted.

if ( view_port_row_cntr > 22 && internal_record_cntr < 100 ) {

 view_port_row_cntr = 22;

  gotoxy(5, 1);

   // delete a line here.

   delline();

    textbackground(15);

     textcolor(0);

      gotoxy(37, 22);

       fseek( fp, file_posit_offset, 0 );

          for ( a = 0; a < 20; a++ ) putch(getc(fp));

           textbackground(9);

            textcolor(14);

             gotoxy(37, view_port_row_cntr - 1);

              fseek( fp, file_posit_offset - 27, 0 );

                 for ( a = 0; a < 20; a++ ) putch(getc(fp));

                  textbackground(15);

                   textcolor(0);

                    gotoxy(37, view_port_row_cntr);

                     fseek( fp, file_posit_offset, 0 );

                        for ( a = 0; a < 20; a++ ) putch(getc(fp));

                         textbackground(9);

                          textcolor(14);

                           gotoxy(5, 22);

}

// if the view port row counter is greater than 22 and

// the internal record counter is greater than 99 then

// set the view port row counter to 22 and set the

// internal row counter to 99. decrement the data file

// position offset by 1 record length and position the

// cursor at the bottom row in the view port.

if ( view_port_row_cntr > 22 && internal_record_cntr > 99 ) {

 view_port_row_cntr = 22;

  internal_record_cntr = 99;

   gotoxy(5, 22);

    file_posit_offset = file_posit_offset - 27;

}

}

// this will process the mechanics of paging up or down 22 records.

if( char_receive2 == 73 || char_receive2 == 81 ) {

// this pages up 22 records.

if ( char_receive2 == 73 ) {

// 594 = "22 records" X "27 character length" of record

// move the file position offset backward by 22 records.

 file_posit_offset = file_posit_offset - 594;

  // move the internal record counter back by 22.

  internal_record_cntr = internal_record_cntr - 22;

   // start_next_22_records is the sequential starting position for the

   // beginning of the 22 records to be displayed.

   start_next_22_records = internal_record_cntr - view_port_row_cntr + 1;

    // "offset_next_22_records = start_next_22_records * 27" is the file

    // position offset for the new starting point to list the 22 records.

    offset_next_22_records = start_next_22_records * 27;

// if the new sequential starting position is less than 0 in

// the 100 item file then set the start position at the

// beginning of the data file to display the first 22 records.

if ( start_next_22_records < 0 ) {

 offset_next_22_records = 0;

  file_posit_offset = (view_port_row_cntr - 1 ) * 27;

   // ' start_next_22_records ' is the starting file position offset in the file

   // for the beginning of the 22 records to be displayed.

   // also adjust file_posit_offset, start_next_22_records and

   // internal_record_cntr to reflect this.

   start_next_22_records = 0;

    internal_record_cntr = view_port_row_cntr - 1;

}

}

// this pages down 22 records.

if ( char_receive2 == 81 ) {

// 594 = "22 records" X "27 character length" of record

// move the file position offset forward by 22 records.

 file_posit_offset = file_posit_offset + 594;

  // move the internal record counter forward by 22.

  internal_record_cntr = internal_record_cntr + 22;

   // start_next_22_records is the sequential starting position for the

   // beginning of the 22 records to be displayed.

   start_next_22_records = internal_record_cntr - view_port_row_cntr + 1;

    // "offset_next_22_records = start_next_22_records * 27" is the file

    // position offset for the new starting point to list the 22 records.

    offset_next_22_records = start_next_22_records * 27;

// if the new sequential starting position is greater than

// 78 in the 100 item file, then set the start position at

// record #78 to display the last 22 records.

if ( start_next_22_records > 78 ) {

 offset_next_22_records = 78 * 27;

  file_posit_offset = ( 77 + view_port_row_cntr ) * 27;

   // offset_next_22_records is the starting file position offset in the file

   // for the beginning of the 22 records to be displayed.

   // also adjust file_posit_offset, start_next_22_records and

   // internal_record_cntr to reflect this.

   start_next_22_records = 78;

    internal_record_cntr = 77 + view_port_row_cntr;

}

}

// display 22 records starting from the file position

// offset in the data file after having paged up or down.

loop_cntr = 1;

 do {

  gotoxy(37, loop_cntr);

   fseek( fp, offset_next_22_records, 0 );

      for ( a = 0; a < 20; a++ ) putch(getc(fp));

       start_next_22_records ++;

        loop_cntr ++;

         offset_next_22_records = offset_next_22_records + 27;

 } while( loop_cntr  < 23 );

// position the highlighted cursor bar on the first row

// of the 22 displayed records in the view port.

 textbackground(15);

  textcolor(0);

   gotoxy(37, view_port_row_cntr);

    fseek(fp, file_posit_offset, 0);

       for (a=0; a<20; a++) putch(getc(fp));

        textbackground(9);

         textcolor(14);

          gotoxy(5, view_port_row_cntr);

}

// exit the "do while loop" if a name has been selected with

// the ascii code 13 (return) or if a cancel operation has been indicated

// with the ascii code 27 (escape).

} while( char_receive1 != 13 && char_receive1 != 27 );

// close the file stream.

fclose(fp);

// supplemental processing code goes here for

// when the operator presses the return key. the

// file position offset, "file_posit_cntr", will be used

// here to retrieve the file contents at the specified

// offset in the file stream for further processing in

// the application.

}



HAVE A LOOK AT HOW IT WORKS

These screen shots illustrate how the scrolling/paging program works:









CONCLUSION

As you have seen, programming this was quite tedious. I remember when I was getting started with Turbo C in 1990 I asked Borland technical support if there was preformatted code for creating scrolling lists and they said there wasn’t such a thing. I would have to code it myself. What you saw in this example was spawned from this reality long ago. It was hard, but constructive in the sense that it strengthened my resolve to become a capable software developer over the next two decades.


Comments

0 Comments.
Share a thought or comment...
 
Write a Comment...
...
Sign in...

If you are a member, Sign In. Or, you can Create a Free account now.


Anonymous Post (text-only, no HTML):

Enter your name and security key.

Your Name:
Security key = P1221A1
Enter key:
Article Contributed By Douglas.M:

Please visit my software developer website for more information about my services. I offer application development as well as Android app coding services. My developer skills are best suited to dealing with custom software projects. I can perform programming for Corel Paradox as well as C# Sharp and PHP.

In my local area of northeast Ohio, I can cater to computer repair and "fix my computer" issues.

Use my contact web page today to reach me about any software design ideas you have.

Be sure to check out my blog on Tumblr.

Visit Profile

 KB Article #102798 Counter
300
Since 7/25/2017
-
   Contact Us!
 
PrestwoodBoards.com was developed and is maintainted by me. Do you have a question or suggestion? Do you see a problem? Contact me now. My goal is to build an ad-free and spam-free source of I.T. information with many contributers (ok to promote your website/company in your bio). Yes, my company Prestwood IT Solutions is mentioned in my bio which shows with every post, but you can contribute and promote your pet project too!

1,530 People Online Now!!  
Sign In to see who's online now!  Not a member? Join now. It's free!
Show more stats...


©1995-2017 PrestwoodBoards  [Security & Privacy]
Professional IT Services: Coding | Websites | Computer Tech