Console RainBow of Colored Text example:
/+****************************************************************
* Program : Rainbow.exe (a Windows' console colored text example)
* Source : Rainbow.d
* Author : David L. 'SpottedTiger' Davis
* Created Date : 31.Jul.04 Compiled and Tested with dmd v0.97
* Modified Date : 18.Jun.05 Compiled and Tested with dmd v0.127
* : 04.Jun.06 Compiled and Tested with dmd v0.160
* : 21.Jan.07 Compiled and Tested with dmd v1.0
* Requirements : std.c.windows.windows and std.c.windows.wincon
* License : Public Domain
*****************************************************************
*
* Note: wincon.d needs to be copied into C:\dmd\src\phobos\std\c\windows
*
* To Compiled: C:\dmd_MKod_ex>dmd rainbow.d ..\src\phobos\std\c\windows\wincon.d
+/
private import std.c.windows.windows;
private import std.c.windows.wincon;
extern( Windows )
{
// -- WinBase.h --
enum : uint
{
STD_INPUT_HANDLE = -10,
STD_OUTPUT_HANDLE = -11,
STD_ERROR_HANDLE = -12
}
struct OVERLAPPED
{
DWORD Internal;
DWORD InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
HANDLE hEvent;
};
alias OVERLAPPED *LPOVERLAPPED;
HANDLE GetStdHandle
(
DWORD nStdHandle
);
BOOL SetStdHandle
(
DWORD nStdHandle,
HANDLE hHandle
);
BOOL WriteFile
(
HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
}
HANDLE hStdout;
HANDLE hStdin;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
// BLACK = 0 .. WHITE = 15
static char[][ 16 ] sColors =
[
"Color Black\0",
"Color Dark Blue:\0",
"Color Dark Green:\0",
"Color Dark Aqua:\0",
"Color Dark Red:\0",
"Color Dark Purple:\0",
"Color Dark Yellow:\0",
"Color Dark White:\0",
"Color Gray:\0",
"Color Blue:\0",
"Color Green:\0",
"Color Aqua:\0",
"Color Red:\0",
"Color Purple:\0",
"Color Yellow:\0",
"Color White: \0"
];
int main()
{
CHAR chBuffer[ 256 ];
DWORD cWritten;
DWORD fdwOldMode;
WORD wOldColorAttrs;
// Get handles to STDIN and STDOUT.
hStdin = GetStdHandle( STD_INPUT_HANDLE );
hStdout = GetStdHandle( STD_OUTPUT_HANDLE );
if ( hStdin == INVALID_HANDLE_VALUE || hStdout == INVALID_HANDLE_VALUE )
{
MessageBoxA( null, "GetStdHandle", "Console Error", MB_OK );
return 0;
}
// Save the current text colors.
if ( !GetConsoleScreenBufferInfo( hStdout, cast(PCONSOLE_SCREEN_BUFFER_INFO)&csbiInfo ) )
{
MessageBoxA( null, "GetConsoleScreenBufferInfo", "Console Error", MB_OK );
return 0;
}
wOldColorAttrs = csbiInfo.wAttributes;
SetConsoleTextAttribute( hStdout, FG_Color.WHITE | BG_Color.BLACK );
NewLine();
// Show all 16x16 (256) Foreground to Background colors in a Rainbow.
for( int iz = 0; iz < 256; iz += 16 )
{
for( int ix = 0; ix < 16; ix++ )
{
// Start new line at item 5 and 10.
if( ( ix == 5 ) || ( ix == 10 ) ) NewLine();
SetConsoleTextAttribute( hStdout, ix + iz );
WriteFile( hStdout, cast(LPCSTR)sColors[][ ix ], cast(DWORD)sColors[][ ix ].length, &cWritten, null );
}
NewLine();
}
// Restore the original console mode.
SetConsoleMode( hStdin, fdwOldMode );
// Restore the original text colors.
SetConsoleTextAttribute( hStdout, wOldColorAttrs );
return 0;
} // end int main()
/+
' The NewLine function handles carriage returns when the processed
' input mode is disabled. It gets the current cursor position
' and resets it to the first cell of the next row.
'
+/
void NewLine()
{
if ( !GetConsoleScreenBufferInfo( hStdout, cast(PCONSOLE_SCREEN_BUFFER_INFO)&csbiInfo ) )
{
MessageBoxA( null, "GetConsoleScreenBufferInfo", "Console Error", MB_OK );
return;
}
csbiInfo.dwCursorPosition.X = 0;
// If it is the last line in the screen buffer, scroll
// the buffer up.
if ( ( csbiInfo.dwSize.Y - 1 ) == csbiInfo.dwCursorPosition.Y )
{
ScrollScreenBuffer( hStdout, 1 );
}
// Otherwise, advance the cursor to the next line.
else csbiInfo.dwCursorPosition.Y += 1;
if ( !SetConsoleCursorPosition( hStdout, csbiInfo.dwCursorPosition ) )
{
MessageBoxA( null, "SetConsoleCursorPosition", "Console Error", MB_OK );
return;
}
} // end void NewLine()
void ScrollScreenBuffer
(
in HANDLE h,
in INT x
)
{
SMALL_RECT srctScrollRect;
SMALL_RECT srctClipRect;
CHAR_INFO chiFill;
COORD coordDest;
srctScrollRect.Left = 0;
srctScrollRect.Top = 1;
srctScrollRect.Right = csbiInfo.dwSize.X - x;
srctScrollRect.Bottom = csbiInfo.dwSize.Y - x;
// The destination for the scroll rectangle is one row up.
coordDest.X = 0;
coordDest.Y = 0;
// The clipping rectangle is the same as the scrolling rectangle.
// The destination row is left unchanged.
srctClipRect = srctScrollRect;
// Set the fill character and attributes.
// (Trick: the foreground and background colors can be mixed together.)
chiFill.Attributes = FG_Color.WHITE | BG_Color.BLACK;
chiFill.Char.AsciiChar = cast(char)' ';
// Scroll up one line.
ScrollConsoleScreenBufferA(
h, // screen buffer handle
&srctScrollRect, // scrolling rectangle
&srctClipRect, // clipping rectangle
coordDest, // top left destination cell
&chiFill ); // fill character and color
} // end void ScrollScreenBuffer( in HANDLE, in INT )