PRACTICE

Now that you've learned the essentials of conio programming, try writing these programs to practice. You should also refer to your compiler's C library reference guide for specific conio functions and how to use them. You should be able to complete these sample programs using OpenWatcom C:

Practice program 1.

Write a "visual" version of the FreeDOS PAUSE command. Set the background to blue, and draw a red pop-up message with black drop-shadow that says "Press any key to continue." Wait for the user to press a key on the keyboard, then clear the screen and exit.

This is a good demonstration of clearing the screen versus clearing a window. When you clear the screen, position 1,1 is at the top-left of the screen. When you clear a window, position 1,1 is at the top-left of that window. That makes window addresses easier to locate.

To write this program, set the background color to blue, then clear the screen. Draw a drop-shadow, and draw your pop-up window on top of that, offset by one row up and one column to the left. Print your prompt inside that window.

This sample program includes extra comments to help you figure out the center position for the pop-up window:

#include <conio.h>
#include <graph.h>

int
main()
{
   /* set video mode and hide cursor */

   _setvideomode(_TEXTC80);
   _displaycursor(_GCURSOROFF);

   /* clear screen */

   _setbkcolor(1);                     /* blue */
   _clearscreen(_GCLEARSCREEN);

   /* draw a pop-up window */

   /* note: "Press any key to continue..." is 28 character long */
   /* add a space on either side ... that's 30 cols wide */
   /* 80-30 = 50 ... half that is 25 */
   /* make text window 30 cols wide, starting at col 25 */

   /* make the window 3 lines tall and start text at line 2 */
   /* 25-3 = 22 ... half that is 11 */

   /* drop shadow */

   _settextwindow(11, 26, 13, 55);
   _setbkcolor(0);                     /* black */
   _clearscreen(_GWINDOW);

   /* pop-up window */

   _settextwindow(10, 25, 12, 54);
   _setbkcolor(4);                     /* red */
   _clearscreen(_GWINDOW);

   /* message */

   _settextcolor(15);                  /* bright white */
   _settextposition(2, 2);
   _outtext("Press any key to continue...");

   /* wait for key */

   getch();

   /* done */

   _displaycursor(_GCURSORON);
   _setvideomode(_DEFAULTMODE);

   return 0;
}

Practice program 1

Practice program 2.

Write a "visual" version of the FreeDOS ECHO command. Set the background to cyan, and draw a brown pop-up message with blue drop-shadow that prints whatever text was passed to ECHO on the command line. Wait for the user to press a key on the keyboard, then clear the screen and exit.

This program is very similar to the previous practice program. Clear the screen with a background color, then draw the drop shadow and pop-up window. Print your text inside the pop-up window.

If your text is longer than will fit in the window, it will wrap to the next line in the window.

#include <conio.h>
#include <graph.h>

int
main(int argc, char **argv)
{
   int i;

   /* set video mode and hide cursor */

   _setvideomode(_TEXTC80);
   _displaycursor(_GCURSOROFF);

   /* clear screen */

   _setbkcolor(3);                     /* cyan */
   _clearscreen(_GCLEARSCREEN);

   /* draw a pop-up window */

   /* drop shadow */

   _settextwindow(10, 5, 15, 75);
   _setbkcolor(1);                     /* blue */
   _clearscreen(_GWINDOW);

   /* pop-up window */

   _settextwindow(9, 4, 14, 74);
   _setbkcolor(6);                     /* brown */
   _clearscreen(_GWINDOW);

   /* message */

   _settextcolor(7);                   /* white */
   _settextposition(2, 2);

   for (i = 1; i < argc; i++) {
      _outtext(argv[i]);
      _outtext(" ");
   }

   /* wait for key */

   getch();

   /* done */

   _displaycursor(_GCURSORON);
   _setvideomode(_DEFAULTMODE);

   return 0;
}

This sample output used a really long command line, to demonstrate text that is too wide for the current text window:

Practice program 2

Practice program 3.

Write a program that draws a progress bar in ten percent increments using a for loop. Display a message at the bottom of the screen that indicates the user should press a key for the next iteration on the progress bar. Center the progress bar as 50 characters wide on the screen, and three rows tall. Use a blue background on the screen, and draw the progress bar using solid black for the "uncompleted" portion and solid green for the "completed" portion of the progress bar.

Since this program requires drawing updated progress bars, and printing new message text, we can use functions to manage the screen display. I wrote my sample program with a show_message function that displayed a text message at the bottom of the screen. And I wrote a show_progress function to draw a progress bar.

If you know that your progress bar will only increase in size (this is a safe assumption for a progress bar) you can improve this function to only draw the updated portion of the progress bar.

This sample program includes extra comments to help you figure out the center position for the progress bar:

#include <conio.h>
#include <graph.h>

void
show_message(char *msg)
{
_settextwindow(25, 1, 25, 80);
_setbkcolor(3);                     /* cyan */
_clearscreen(_GWINDOW);

_settextcolor(15);                  /* bright white */
_settextposition(1, 1);
_outtext(msg);
}

void
show_progress(int n, int nmax)
{
int width;

/* progress bar (background) */
/* 80-50 = 30 .. half that is 15 */
/* a 50-col progress bar will be centered if started at col 15 */

_settextwindow(10, 15, 12, 64);     /* 15 + 50 - 1 = 64 */
_setbkcolor(0);                     /* black */
_clearscreen(_GWINDOW);

/* progress bar (progress) */
/* using integet math .. the bar will be 50 cols wide, so this: */

width = 50 * n / nmax;
_settextwindow(10, 15, 12, 15 + width - 1);
_setbkcolor(2);                     /* green */
_clearscreen(_GWINDOW);
}

int
main()
{
int pct;
char message[80];

/* set video mode and hide cursor */

_setvideomode(_TEXTC80);
_displaycursor(_GCURSOROFF);

/* clear screen */

_setbkcolor(1);                     /* blue */
_clearscreen(_GCLEARSCREEN);

/* loop */

for (pct = 10; pct <= 100; pct += 10) {
show_progress(pct, 100);

      /* wait for key */

      sprintf(message, "press any key for next .. (%d%%)", pct);
      show_message(message);
      getch();
   }

   /* done */

   _displaycursor(_GCURSORON);
   _setvideomode(_DEFAULTMODE);

   return 0;
}

Practice program 3

Practice program 4.

Write a test program that reads the keyboard using getch and displays the result in a text window. (In OpenWatcom's conio, getch will return 0 if the user pressed an extended function key, and the next call too getch returns a value for the extended key.) Exit if the user enters Q or q.

This sample program is similar to the others, with only a minor variation. I first write the message into a string variable using sprintf. That allows me to create a slightly different message if the key is an extended key.

I used strlen and simple arithmetic to center the text in the message window.

#include <conio.h>
#include <graph.h>
#include <string.h>                    /* strlen */

void
show_message(char *msg)
{
int col;

/* drop shadow */

_settextwindow(11, 25, 15, 55);
_setbkcolor(0);                     /* black */
_clearscreen(_GWINDOW);

/* pop-up window */

_settextwindow(10, 24, 14, 54);
_setbkcolor(4);                     /* red */
_clearscreen(_GWINDOW);

/* show message */

col = (30 - strlen(msg)) / 2 + 1;

_settextcolor(15);                  /* bright white */
_settextposition(3, col);
_outtext(msg);
}

int
main()
{
int key;
char message[80];

/* set video mode and hide cursor */

_setvideomode(_TEXTC80);
_displaycursor(_GCURSOROFF);

/* clear screen */

_setbkcolor(1);                     /* blue */
_clearscreen(_GCLEARSCREEN);

/* prompt */

_settextcolor(14);                  /* bright yellow */
_settextposition(1, 1);
_outtext("press any key (Q to quit)");

/* loop */

do {
key = getch();

if (key == 0) {
 /* extended key .. call getch again */
 key = getch();
 sprintf(message, "key is %d (EXTENDED)", key);
}
else {
 sprintf(message, "key is %d", key);
}

show_message(message);
} while ((key != 'q') && (key != 'Q'));

/* done */

_displaycursor(_GCURSORON);
_setvideomode(_DEFAULTMODE);

return 0;
}

Practice program 4

Practice program 5.

Write a sample program that displays text in every color text color and background color combination. Since there are eight background colors, draw the text in 10-character columns, with each column representing a different background color.

This is a no-frills sample program that displays the string ...test... (exactly 10 characters long) in each text color and background color. This is a handy program to remind you what colors go well together. Bright white and bright yellow are easy to read on any background color. The blue background color makes it easy to read almost all of the text colors, except blue and black.

#include <conio.h>
#include <graph.h>

int
main()
{
   int fg, bg;
   int row, col;

   /* set video mode and hide cursor */

   _setvideomode(_TEXTC80);
   _displaycursor(_GCURSOROFF);

   /* clear screen */

   _setbkcolor(0);                     /* black */
   _clearscreen(_GCLEARSCREEN);

   /* title and footer */

   _settextcolor(15);                  /* bright white */
   _settextposition(1, 35);
   _outtext("COLOR DEMO");

   _settextcolor(7);                   /* white */
   _settextposition(25, 1);
   _outtext("press any key to quit");

   /* demo the colors */

   for (bg = 0; bg <= 7; bg++) {
      for (fg = 0; fg <= 15; fg++) {
         row = 5 + fg;
         col = bg * 10 + 1;

         _settextcolor(fg);
         _setbkcolor(bg);

         _settextposition(row, col);
         _outtext("...test...");
      }
   }

   /* wait for a key */

   getch();

   /* done */

   _displaycursor(_GCURSORON);
   _setvideomode(_DEFAULTMODE);

   return 0;
}

Practice program 5

Many programmers use white text on a blue background for most of their applications. White text on a black background is also fine, but it's plain. Error message pop-up windows show up well as white on a red background, with the title in bright white or bright yellow. Dialog windows might use black text on a white background, with a bright white title. Title bars or status displays (a one-line bar at the top or bottom of the screen, usually to show a title or quick status, might use a cyan background with black text for information, or bright white for a title.