Code:
# include <windows.h>
# include <stdio.h>
# include <conio.h>
void Print (short x, short y, WORD Color, char *String, ...);
void ClrScr (short x, short y, short EraseLength, short NoOfLines, WORD EraseColor, char ErasePattern);
int main ()
{
ClrScr (0, 0, 79, 24, BACKGROUND_BLUE, ' ');
getch ();
Print (5, 5, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | BACKGROUND_GREEN, "Hello!");
getch ();
return 0;
}
void ClrScr (short x, short y, short EraseLength, short NoOfLines, WORD EraseColor, char ErasePattern)
{
short i = 0, j = 0;
char Erase[25*80] = {0};
for (i = 0; i < NoOfLines; i++)
{
for (j = 0; j < EraseLength; j++)
{
Erase[i+j] = ErasePattern;
}
}
Erase[i+j] = '\0';
Print (x, y, EraseColor, "%s", Erase);
}
void Print (short x, short y, WORD Color, char *String, ...)
{
HANDLE hStdout, hNewScreenBuffer;
SMALL_RECT srctReadRect;
SMALL_RECT srctWriteRect;
CHAR_INFO chiBuffer[25*80]; // [25][80];
COORD coordBufSize = {0};
COORD coordBufCoord = {0};
BOOL fSuccess;
short i = 0, j = 0, FormattedStringLength = 0;
va_list List;
char FormattedString[25*80] = {0};
// Get a handle to the STDOUT screen buffer to copy from and
// create a new screen buffer to copy to.
//printf("CreateConsoleScreenBuffer");
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
hNewScreenBuffer = CreateConsoleScreenBuffer(
GENERIC_READ | // read/write access
GENERIC_WRITE,
0, // not shared
NULL, // no security attributes
CONSOLE_TEXTMODE_BUFFER, // must be TEXTMODE
NULL); // reserved; must be NULL
if (hStdout == INVALID_HANDLE_VALUE ||
hNewScreenBuffer == INVALID_HANDLE_VALUE)
{
printf("CreateConsoleScreenBuffer");
}
va_start (List, String);
vsprintf (FormattedString, String, List);
FormattedStringLength = (short) strlen (FormattedString);
va_end (List);
// Make the new screen buffer the active screen buffer.
/* if (! SetConsoleActiveScreenBuffer(hNewScreenBuffer) )
printf("SetConsoleActiveScreenBuffer");
*/ // Set the source rectangle.
srctReadRect.Top = x; // top left: row 0, col 0
srctReadRect.Left = y;
srctReadRect.Bottom = 25; // bot. right: row 25, col 80
srctReadRect.Right = 80;
// The temporary buffer size is 25 rows x 80 columns.
coordBufSize.Y = 25;
coordBufSize.X = 80;
// The top left destination cell of the temporary buffer is
// row 0, col 0.
coordBufCoord.X = 0;
coordBufCoord.Y = 0;
// Copy the block from the screen buffer to the temp. buffer.
fSuccess = ReadConsoleOutput(
hStdout, // screen buffer to read from
chiBuffer, // buffer to copy into
coordBufSize, // col-row size of chiBuffer
coordBufCoord, // top left dest. cell in chiBuffer
&srctReadRect); // screen buffer source rectangle
if (! fSuccess) printf("ReadConsoleOutput");
// Set the destination rectangle.
srctWriteRect.Top = x; // top lt: row 10, col 0
srctWriteRect.Left = y;
srctWriteRect.Bottom = 25; // bot. rt: row 11, col 79
srctWriteRect.Right = 80;
for (i = 0; i < 25*80; i++)
{
chiBuffer[i].Attributes = Color;
chiBuffer[i].Char.AsciiChar = FormattedString[i];
}
// Copy from the temporary buffer to the new screen buffer.
WriteConsoleOutput(
hStdout, // screen buffer to write to
chiBuffer, // buffer to copy from
coordBufSize, // col-row size of chiBuffer
coordBufCoord, // top left src cell in chiBuffer
&srctWriteRect); // dest. screen buffer rectangle
}