Reputation: 55
I know the question I've asked seems similar to others however it doesn't seem to apply.
I am using delphi 10.3
I want to write two texts consecutively in the console application however I want them separate colors
writeln('yes just give me a minute, i need to talk to the manager'); {i want this in the default color}
writeln('Oi Dave we got another thick one shall i just pass him through as self employed'); {i want this to be in red}
writeln('Dont worry u dont have to complete this one') {and this one back to the default color}
Upvotes: 5
Views: 4442
Reputation: 1532
Here is my solution:
Writeln('Standard write without special color');
ColoredWrite('This {color:yellow}Text {color:red}is {color:blue}very {color:black_on_blue} colorful{color:reset} but ends without color');
Writeln('');
ColoredWrite('{color:red}Red{color:red2}Red2{color:green}Green{color:green2}Green2{color:blue}Blue{color:blue2}Blue2'
+ '{color:yellow}Yellow{color:yellow2}Yellow2{color:purple}Purple{color:purple2}Purple2'
+ '{color:gray}Gray{color:black_on_blue}Black on Blue{color:white} White {color:red_on_white}Red on White'
+ '{color:reset} Original Color');
Writeln('');
Writeln('Standard write without special color');
And here is the necessary function:
uses Winapi.Windows, System.Generics.Collections;
procedure ColoredWrite(sString: string);
var
ConOut: THandle;
BufInfo: TConsoleScreenBufferInfo;
ColorDict: TDictionary<string, integer>;
iPos, iFirstPos: integer;
sFirstFind: string;
sKey: string;
begin
ColorDict := TDictionary<string, integer>.Create();
ColorDict.Add('{color:red}', FOREGROUND_RED);
ColorDict.Add('{color:red2}', FOREGROUND_INTENSITY or FOREGROUND_RED);
ColorDict.Add('{color:green}', FOREGROUND_INTENSITY or FOREGROUND_GREEN);
ColorDict.Add('{color:green2}', FOREGROUND_GREEN);
ColorDict.Add('{color:blue}', FOREGROUND_BLUE);
ColorDict.Add('{color:blue2}', FOREGROUND_INTENSITY or FOREGROUND_BLUE);
ColorDict.Add('{color:yellow}', FOREGROUND_RED or FOREGROUND_GREEN);
ColorDict.Add('{color:yellow2}', FOREGROUND_INTENSITY or FOREGROUND_RED or FOREGROUND_GREEN);
ColorDict.Add('{color:purple}', FOREGROUND_BLUE or FOREGROUND_RED);
ColorDict.Add('{color:purple2}', FOREGROUND_INTENSITY or FOREGROUND_BLUE or FOREGROUND_RED);
ColorDict.Add('{color:gray}', FOREGROUND_INTENSITY);
ColorDict.Add('{color:white}', FOREGROUND_INTENSITY or FOREGROUND_RED or FOREGROUND_GREEN or FOREGROUND_BLUE);
ColorDict.Add('{color:black_on_blue}', 0 or {BACKGROUND_RED or} BACKGROUND_BLUE or BACKGROUND_GREEN);
ColorDict.Add('{color:red_on_white}', FOREGROUND_INTENSITY or FOREGROUND_RED or 0 or BACKGROUND_INTENSITY or BACKGROUND_RED or BACKGROUND_BLUE or BACKGROUND_GREEN);
//Write(' '); // If there is no text output before retrieving BufInfo.wAttributes, then {color:reset} will set foreground and background color to black...
ConOut := TTextRec(Output).Handle;
GetConsoleScreenBufferInfo(ConOut, BufInfo);
ColorDict.Add('{color:reset}', BufInfo.wAttributes);
while sString.Length > 0 do begin
iFirstPos := sString.Length;
for sKey in ColorDict.Keys do begin
if sString.Contains(sKey) then begin
iPos := Pos(sKey, sString);
if iPos < iFirstPos then begin
iFirstPos := iPos;
sFirstFind := sKey;
end;
end;
end;
if iFirstPos < sString.Length then begin
Write(Copy(sString, 1, iFirstPos-1));
sString := Copy(sString, iFirstPos+sFirstFind.Length);
SetConsoleTextAttribute(TTextRec(Output).Handle, ColorDict[sFirstFind]);
end else begin
Write(sString);
sString := '';
end;
end;
ColorDict.Free;
end;
Upvotes: 0
Reputation: 6848
I use too the SetConsoleTextAttribute
function defined in WinAPI.Windows
.
With this simple procedure (extensible):
/// <summary> Cambiar el color de la salida de consola </summary>
/// <summary> Change the color of console output</summary>
procedure SetColorConsole(AColor:TColor);
begin
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED or FOREGROUND_GREEN or FOREGROUND_BLUE);
case AColor of
clWhite: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED or FOREGROUND_GREEN or FOREGROUND_BLUE);
clRed: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED or FOREGROUND_INTENSITY);
clGreen: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN or FOREGROUND_INTENSITY);
clBlue: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE or FOREGROUND_INTENSITY);
clMaroon: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN or FOREGROUND_RED or FOREGROUND_INTENSITY);
clPurple: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED or FOREGROUND_BLUE or FOREGROUND_INTENSITY);
clAqua: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN or FOREGROUND_BLUE or FOREGROUND_INTENSITY);
end;
end;
You can use something like this:
WriteLn(' ');
SetColorConsole(clWhite);
WriteLn('clWhite');
SetColorConsole(clRed);
WriteLn('clRed');
SetColorConsole(clGreen);
WriteLn('clGreen');
SetColorConsole(clBlue);
WriteLn('clBlue');
SetColorConsole(clMaroon);
WriteLn('clYellow');
SetColorConsole(clPurple);
WriteLn('clPurple');
SetColorConsole(clAqua);
WriteLn('clAqua');
And the result is like this.
Upvotes: 3
Reputation: 6402
There is an very easy solution for that, using DelphiConsole
var
CurrentColor : TConsoleColor;
CurrentColor := Console.ForegroundColor;
Console.WriteLine('yes just give me a minute, i need to talk to the manager');
Console.ForegroundColor := TConsoleColor.Red;
Console.WriteLine('Oi Dave we got another thick one shall i just pass him through as self employed');
Console.ForegroundColor := DefaultColor;
Console.WriteLine('Dont worry u dont have to complete this one');
Upvotes: 0
Reputation: 54772
You can use SetConsoleTextAttribute
as already commented to the question. Example:
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, winapi.windows;
var
ConOut: THandle;
BufInfo: TConsoleScreenBufferInfo;
begin
writeln('yes just give me a minute, i need to talk to the manager');
// get console screen buffer handle
ConOut := TTextRec(Output).Handle; // or GetStdHandle(STD_OUTPUT_HANDLE)
// save current text attributes
GetConsoleScreenBufferInfo(ConOut, BufInfo);
// set foreground color to red
SetConsoleTextAttribute(TTextRec(Output).Handle, FOREGROUND_INTENSITY or FOREGROUND_RED);
writeln('Oi Dave we got another thick one shall i just pass him through as self employed');
// reset to defaults
SetConsoleTextAttribute(ConOut, BufInfo.wAttributes);
writeln('Dont worry u dont have to complete this one');
readln;
end.
Minimum required reading: SetConsoleTextAttribute
and character attributes.
Don't forget to add error handling.
Upvotes: 5