The following program compiles (in VC6.0) and executes, but it fails
in one important area: echoing user input in secondary created DOS
windows. If you examine the MkWin routine to see how I'm creating these
windows (cobbled from MS Help code), something is not being done to make
the fgets show data input after the base window's i/o.
Specifically, you will see the the prompt for "First Name" works, but
the processing for "Last Name" (in the 3rd window) doesn't echo the user
input. However, the data is entered in the variable...
Comments? Thoughts? TIA

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <ostream>
#include <sstream>
#include <string>
#include <windows.h>
#include <conio.h>

#define strMax 1024
#define winMax 30
#define DYelBlk 0x0006 // Yellow-on-Black
#define LCynBlk 0x000b // Light Cyan-on-Black
#define LYelBlk 0x000e // Yellow-on-Black
#define HiNorm 0x000f // Bright White-on-Black
#define LBluWht 0x00f9 // Gray-on-Bright White

// Type Declarations
typedef char Str80[81];
struct S_W
{ // screen Window type
short X1, Y1, X2, Y2;
short WinType;
short x, y;
HANDLE oScreen, iScreen;
DWORD fwMode;
SMALL_RECT srctReadRect;
SMALL_RECT srctWriteRect;
} s_w[winMax]; // available windows

// Global Variables
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
WORD wOldColorAttrs;
int Attr = HiNorm;
DWORD cRead, cWritten, fdwMode, fdwOldMode;
short c_w = 0; // current window
short ParamCount = 0; // system parameter count, via argc
Str80 ParamStr[10] = {""}; // File Name(s) storage

using namespace std;

void Pause(); // Pause execution; wait for user action
void Fatal (char *s, int num); // Fatal Error processing
void gotoXY(int X, int Y);
char* RJust(char *s, unsigned int len); // Right-Justify
char* Replicate(int n, char c); // replicate character

void SystemInit(int ac, char *av[]) // System Initialization
{
ParamCount = ac; // set up "system globals"
for (int i = 0; i < ac; i++)
{
strcpy(ParamStr[i], av[i]);
}
if (!GetConsoleScreenBufferInfo(hCon, &csbi))
{
MessageBox(NULL, "GetConsoleScreenBufferInfo", "Console Error",
MB_OK);
exit (300);
}
wOldColorAttrs = csbi.wAttributes;
for (i = 0; i < winMax; i++)// initialize system screen windows
{ // set defaults
s_w[i].WinType = 0;
s_w[i].X1 = 1; s_w[i].Y1 = 1;
s_w[i].X2 = 80; s_w[i].Y2 = 25;
s_w[i].x = s_w[i].y = 1;
s_w[i].oScreen = s_w[i].iScreen = NULL;
} // for
s_w[0].oScreen = hCon;
s_w[0].iScreen = hStdin;
GetConsoleMode(s_w[0].iScreen, &s_w[0].fwMode);

if (!GetConsoleMode(hStdin, &fdwOldMode))
{
MessageBox(NULL, "GetConsoleMode", "Console Error", MB_OK);
Pause();
}
fdwMode = fdwOldMode;
if (!SetConsoleMode(hStdin, fdwMode))
{
MessageBox(NULL, "SetConsoleMode", "Console Error", MB_OK);
Pause();
}
return;
} // SystemInit

void FastWrite (short col, short row, const WORD attr, char *str)
{
BOOL fSuccess;
COORD coord;
DWORD cWritten;
int len = strlen(str);
WORD szAttr[4132];

coord.X = col-1; coord.Y = row-1;
memset(szAttr, attr, len*2);
fSuccess = WriteConsoleOutputAttribute(s_w[c_w].oScreen, szAttr,
len, coord, &cWritten);
fSuccess = WriteConsoleOutputCharacter(s_w[c_w].oScreen, str, len,
coord, &cWritten);
if (!fSuccess)
{
MessageBox(NULL, "FastWrite", "Console Error", MB_OK);
exit (100);
}
} // FastWrite

void clrscr()
{
DWORD dwWritten = 0;
COORD coord = {0, 0};

GetConsoleScreenBufferInfo(s_w[c_w].oScreen, &csbi);
FillConsoleOutputCharacter(s_w[c_w].oScreen, ' ',
csbi.dwSize.X*csbi.dwSize.Y, coord,
&dwWritten);
FillConsoleOutputAttribute(s_w[c_w].oScreen, HiNorm,
csbi.dwSize.X*csbi.dwSize.Y, coord, &dwWritten);
SetConsoleCursorPosition(s_w[c_w].oScreen, coord);
} // clrscr

short ulc[2] = {218, 201}; // Upper Left char
short hlc[2] = {196, 205}; // Horizontal Line Char
short urc[2] = {191, 187}; // Upper Right Char
short vlc[2] = {179, 186}; // Verticle Line Char
short lmc[2] = {195, 204}; // Left Middle Char
short rmc[2] = {180, 185}; // Right Middle Char
short llc[2] = {192, 200}; // Lower Left Char
short lrc[2] = {217, 188}; // Lower Right Char

void BoxTop(short bt)
{
short bc = bt-1;
char work[161], wline[161];
short nw = (s_w[c_w].X2)-(s_w[c_w].X1);
sprintf(wline, "%s", Replicate(80, (char)hlc[bc]));
wline[nw-1] = '\0';
sprintf(work,"%c%s%c",(char)ulc[bc],wline,(char)urc[bc]);
FastWrite(s_w[c_w].X1, s_w[c_w].Y1, Attr, work);
return;
} // BoxTop

void BoxBot(short bt)
{
short bc = bt-1;
char wline[161], work[161];
short nw = (s_w[c_w].X2)-(s_w[c_w].X1);
sprintf(wline, "%s", Replicate(80, (char)hlc[bc]));
wline[nw-1] = '\0';
sprintf(work,"%c%s%c",(char)llc[bc],wline,(char)lrc[bc]);
FastWrite(s_w[c_w].X1, s_w[c_w].Y2, Attr, work);
return;
} // BoxBot

void BoxLine(short bt, short row, char *s)
{
char wline[161], work[161];
short bc = bt-1;
short nw = (s_w[c_w].X2)-(s_w[c_w].X1);
sprintf(wline, "%s%*s", s, nw, " "); wline[nw-1] = '\0';
sprintf(work, "%c%s%c", (char)vlc[bc], wline, (char)vlc[bc]);
FastWrite(s_w[c_w].X1, row, Attr, work);
return;
} // BoxLine

void MkWin(short x1, short y1, short x2, short y2) // Make Window
{
int fSuccess = 0;
char emsg[strMax] = "";
COORD coordBufSize = {80,25};
COORD coordBufCoord = {0,0};
CHAR_INFO chiBuffer[81*51];

if(++c_w < winMax) // can we allocate this new window?
{
s_w[c_w].oScreen = CreateConsoleScreenBuffer(
GENERIC_READ | GENERIC_WRITE, 0, NULL,
CONSOLE_TEXTMODE_BUFFER, NULL);
if (s_w[c_w].oScreen != INVALID_HANDLE_VALUE)
{ // Make the new screen buffer the active screen buffer
if (!SetConsoleActiveScreenBuffer(s_w[c_w].oScreen))
{
sprintf(emsg, "SetConsoleActiveScreenBuffer
failure - Window #%d", c_w);
MessageBox(NULL, emsg, "Console Error",
MB_OK);
exit (298);
}

s_w[c_w].X1 = x1; s_w[c_w].Y1 = y1;
s_w[c_w].X2 = x2; s_w[c_w].Y2 = y2;
// Set the source rectangle
s_w[c_w].srctReadRect.Top = 0; // top left: row 0,
col 0
s_w[c_w].srctReadRect.Left = 0;
s_w[c_w].srctReadRect.Bottom = 24; // bottom right:
row 24, col 79
s_w[c_w].srctReadRect.Right = 79;
// Copy the block from the screen buffer to the temp.
buffer
fSuccess = ReadConsoleOutput(
s_w[c_w-1].oScreen,
// source screen buffer
chiBuffer, //
target buffer
coordBufSize, // col-row size of
chiBuffer
coordBufCoord,// top left destination
cell in chiBuffer
&s_w[c_w].srctReadRect); // screen
buffer source rectangle
if (!fSuccess)
{
MessageBox(NULL, "ReadConsoleOutput",
"Console Error", MB_OK);
exit (97);
}
// Set the destination rectangle
s_w[c_w].srctWriteRect.Top = 0; // top lt: row 0,
col 0
s_w[c_w].srctWriteRect.Left = 0;
s_w[c_w].srctWriteRect.Bottom = 24; // bot. rt:
row 24, col 79
s_w[c_w].srctWriteRect.Right = 79;
// Copy from the temporary buffer to the new screen buffer
fSuccess = WriteConsoleOutput(
s_w[c_w].oScreen, //
destination screen buffer
chiBuffer,
// source buffer
coordBufSize, // col-row
size of chiBuffer
coordBufCoord, // top left src
cell in chiBuffer
&s_w[c_w].srctWriteRect); //
destination screen buffer rectangle
if (!fSuccess)
{
MessageBox(NULL, "WriteConsoleOutput",
"Console Error", MB_OK);
exit (96);
}
}
else
{
sprintf(emsg, "*** Cannot open window #%d -
Terminating ***", c_w);
Fatal(emsg, 299);
}
}
else
{
c_w--;
Fatal("*** Maximum Windows Exceeded - Terminating ***",
299);
}
return;
} // MkWin

void DrWin(short bt) // display empty window box
{
short rowsave = s_w[c_w].y;
BoxTop(bt); // draw top of box
for (int n = 1; n < (s_w[c_w].Y2-s_w[c_w].Y1); n++)
BoxLine(bt, s_w[c_w].Y1+n, ""); // sides
s_w[c_w].y = rowsave;
BoxBot(bt); // bottom
} // DrWin

void gotoXY(int X, int Y)
{
GetConsoleScreenBufferInfo(s_w[c_w].oScreen, &csbi);
COORD coord = {X-1, Y-1};
SetConsoleCursorPosition(s_w[c_w].oScreen, coord);
} // gotoXY

void Pause() // Pause program & wait for user response
{
char c1, c2;

GetConsoleScreenBufferInfo(s_w[c_w].oScreen, &csbi);
FastWrite(csbi.dwCursorPosition.X+1,csbi.dwCursorPosition.Y+
1,Attr,"Press any key...");
c1 = getch();
if (c1 == '\0') // special/extended key; fetch scan code
c2 = getch();
GetConsoleScreenBufferInfo(s_w[c_w].oScreen, &csbi);
return;
} // Pause

void Pause(int x, int y) // Pause program, wait for user response
{
char c1, c2;

FastWrite(x,y,Attr,"Press any key...");
c1 = getch();
if (c1 == '\0') // special/extended key; fetch scan code
c2 = getch();
GetConsoleScreenBufferInfo(s_w[c_w].oScreen, &csbi);
return;
} // Pause

char* RJust (char *s, unsigned int len) // Right-Justify
{
static char w[strMax];

memset(w,' ',len); w[len] = '\0'; // blank fill for left
strcat(w, s);
return w;
} // RJust

void Fatal (char *s, int num) // Fatal Error processing
{
printf (s); exit (num);
} // Fatal

char* Replicate(int n, char c) // replicate a character
{
static char w[strMax];

memset(w, c, n-1); w[n] = NULL;
return w;
}

int main (int argc, char *argv[])
{
char szName[25] = "";

SystemInit(argc, argv); // creates window #0
DrWin(2); // draw window - double bar
FastWrite (2,7,LBluWht,"Enter your First name:");
gotoXY(25,7);
fgets(szName, sizeof(szName), stdin);
MkWin( 1, 1, 80, 25); // make window #1
Attr = LCynBlk;
DrWin(1); // draw window #1 - single bar
MkWin(11, 6, 70, 15); // make window #2
DrWin(2); // draw window #2 - double bar
FastWrite (12,10,LYelBlk,"Enter your Last name:");
gotoXY(34,10);
fgets(szName, sizeof(szName), stdin);
Pause(2,24);
return 0;
}