Colours/styles in command prompt lazarus / 34-Windows ---------------------------------------------------------------------- geraldholdsworth · 2023-07-14 16:23 I've recently found out how to change the colours and styles in a command window (and macOS/Linux bash), just by sending the escape character (27) followed by some specific characters. However, I can't get Lazarus to do the same in Windows (but fine in macOS and Linux). i.e., if you send [31m you should then get red text. So, I do: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i WriteLn(#$1B'[31m');But this doesn't work in Windows, even if I do, beforehand: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   AllocConsole;  IsConsole:=True;  SysInitStdIO;  SetConsoleOutputCP(CP_UTF8);I can get the escape character, but the following characters are then just printed as normal text. But, I have got a *.cmd file that does work with the exact same character sequences (this is done using 'echo'). ---------------------------------------------------------------------- dseligo · 2023-07-14 20:05 I tried this in Windows 11 and it works: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program testboje; begin  WriteLn(#$1B'[31m');  WriteLn('Test');  ReadLn;end. I attached screenshot of running this program. ---------------------------------------------------------------------- Awkward · 2023-07-14 20:35 it will not work in win7 coz command interpreters (consoles) are different. ---------------------------------------------------------------------- PascalDragon · 2023-07-14 21:45 Quote from: geraldholdsworth on July 14, 2023, 06:23:43 pmHowever, I can't get Lazarus to do the same in Windows (but fine in macOS and Linux). ANSI escape sequences are only supported starting from some Windows 10 version from around 2020 or so. For earlier versions you need to use the Windows console API. ---------------------------------------------------------------------- TRon · 2023-07-15 00:26 I addition to the answer of PascalDragon, for windows versions < 10 you can make use of 'console wrappers' and/or 'terminal emulators' that have implemented ANSI support such as for example ConEmu. As stated by PascalDragon starting from Windows 10 (afaik build 16257 and later) support for ANSI Escape Sequences was added but seems not enabled by default. ---------------------------------------------------------------------- dseligo · 2023-07-15 07:57 Quote from: TRon on July 15, 2023, 02:26:43 amAs stated by PascalDragon starting from Windows 10 (afaik build 16257 and later) support for ANSI Escape Sequences was added but seems not enabled by default. And if you want to enable it, you can change registry value VirtualTerminalLevel to 1 (or create new DWORD value with that name if it doesn't exists), under HKEY_CURRENT_USER/Console key. You don't have to restart Windows after that, just open new 'cmd'. ---------------------------------------------------------------------- geraldholdsworth · 2023-07-15 08:42 Hi all. I do appear to have it enabled, because if I run the attached I get colours (and the font styles at the top). It's only when I send the exact same sequence from Lazarus that it doesn't work. This is using Windows 10 which, I'm assuming, has all the latest updates. Haven't tried 7 or 11 yet. Cheers, Gerald. ---------------------------------------------------------------------- geraldholdsworth · 2023-07-15 08:49 Maybe I am being stupid here - as suggested, if I add that key it works. So why did the .cmd file work without it? (sorry, not great with Windows) ---------------------------------------------------------------------- dseligo · 2023-07-15 08:59 Quote from: geraldholdsworth on July 15, 2023, 10:49:15 amMaybe I am being stupid here - as suggested, if I add that key it works. So why did the .cmd file work without it? Can you upload this .cmd file? Maybe someone can spot why it works. ---------------------------------------------------------------------- geraldholdsworth · 2023-07-15 09:06 Quote from: dseligo on July 15, 2023, 10:59:25 amCan you upload this .cmd file? Maybe someone can spot why it works. Yep, I did...message above that one. I had to zip it up to get it to upload. I have found a fudge which works: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  {$IFDEF Windows} if Application.HasOption('c','console') then begin  R:=TRegistry.Create;  R.OpenKey('Console',True);  R.WriteInteger('VirtualTerminalLevel',1);  R.Free;  AllocConsole;  IsConsole:=True;  SysInitStdIO;  SetConsoleOutputCP(CP_UTF8); end; {$ENDIF} Although I think I need to tinker with it for older versions of Windows. ---------------------------------------------------------------------- KodeZwerg · 2023-07-15 09:36 Here you can find a very huge custom CRT replacement, made for Delphi, untested if it works with FreePascal together hand-in-hand. ---------------------------------------------------------------------- dseligo · 2023-07-15 12:13 Quote from: geraldholdsworth on July 15, 2023, 10:49:15 amMaybe I am being stupid here - as suggested, if I add that key it works. So why did the .cmd file work without it? (sorry, not great with Windows) Cmd file works probably because windows set virtual terminal when executing batch scripts. Try this code below. It prints red 'Test' in Windows 10 without setting VirtualTerminalLevel in registry. If you get errror 87 ($57, The parameter is incorrect) it means that your Windows version doesn't support virtual terminal processing parameter. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program testboje; uses Windows; var hwConsole: hWnd;    lwMode: LongWord; begin  hwConsole := GetStdHandle(STD_OUTPUT_HANDLE);   If not GetConsoleMode(hwConsole, @lwMode) then begin    WriteLn('Last error: ', GetLastError);    Exit;  end;   lwMode := lwMode or ENABLE_VIRTUAL_TERMINAL_PROCESSING;   If not SetConsoleMode(hwConsole, lwMode) then begin    WriteLn('Last error: ', GetLastError);    Exit  end;   Write(#$1B'[31m');  WriteLn('Test');  Write(#$1B'[0m');  WriteLn('Test1');end. ---------------------------------------------------------------------- geraldholdsworth · 2023-07-15 12:58 Ah, thank you. I'll have a tinker later on. That would be useful to see if it is capable, or not, of this and then only output coloured/styled text if the OS is able to. ---------------------------------------------------------------------- dseligo · 2023-07-15 14:07 Quote from: geraldholdsworth on July 15, 2023, 02:58:36 pmThat would be useful to see if it is capable, or not, of this and then only output coloured/styled text if the OS is able to. Yes. I tried it on Windows Server 2016 and it works, while on Windows 7, Windows Server 2012R2 and 2008 I get error 87. ---------------------------------------------------------------------- geraldholdsworth · 2023-07-15 14:47 Beautiful...it works. I've tinkered with it and come up with this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   {$IFDEF Windows}  redstyle:='';  nostyle :='';  AllocConsole;  IsConsole:=True;  SysInitStdIO;  SetConsoleOutputCP(CP_UTF8);  hwConsole:=GetStdHandle(STD_OUTPUT_HANDLE);  If GetConsoleMode(hwConsole,@lwMode)then  begin   lwMode:=lwMode or ENABLE_VIRTUAL_TERMINAL_PROCESSING;   if SetConsoleMode(hwConsole,lwMode)then   begin    {$ENDIF}    redstyle:=#$1B'[91m';    nostyle :=#$1B'[0m';    {$IFDEF Windows}   end;  end;  {$ENDIF}  WriteLn(redstyle+StringOfChar('*',80)+nostyle);This way, if it runs on macOS or Linux we get the styles anyway. If it runs on Windows that does support it, we get the styles. And, if we run on Windows that doesn't support it, we get plain text, but it still runs. Tried this on Windows 7 and 10 and I get plain text on 7 and red text on 10, with no control characters. So, again, thank you. ---------------------------------------------------------------------- dseligo · 2023-07-15 15:39 Np, I'm glad it worked for you. ---------------------------------------------------------------------- creaothceann · 2026-08-23 19:12 *bump* Quote from: geraldholdsworth on July 15, 2023, 04:47:30 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i [...]  Just for the record, here are the other colors... I'm using the Unleashed fork, but should be trivial to adjust for standard Free Pascal. Also, my program uses {$AppType Console} so the console window initialization wasn't needed. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit U_Console;  // Unit for setting console text colors. Should work on Windows 10 and above; on older versions of Windows the colors won't appear.  {$Mode Unleashed} interface  //////////////////////////////// ////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////{$ifdef Windows} uses Windows; {$endif}  type        ConsoleColor =  // same as in unit CRT                ( Black        =  0                , Blue         =  1              , Green        =  2                , Cyan         =  3              , Red          =  4                , Magenta      =  5              , Brown        =  6                , LightGray    =  7              , DarkGray     =  8                , LightBlue    =  9              , LightGreen   = 10                , LightCyan    = 11              , LightRed     = 12                , LightMagenta = 13              , Yellow       = 14                , White        = 15);  procedure TextColor     (const cc : ConsoleColor);  inline;procedure TextBackground(const cc : ConsoleColor);  inline;  implementation  //////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// //////////////////////////////  const        Styles_Foreground : array[ConsoleColor] of AnsiString =  // https://learn.microsoft.com/en-us/windows/console/console-virtual- terminal-sequences                ( #27'[' +   '0' + 'm'    // Black              , #27'[' +  '34' + 'm'    // Blue                , #27'[' +  '32' + 'm'    // Green                , #27'[' +  '36' + 'm'    // Cyan                , #27'[' +  '31' + 'm'    // Red                , #27'[' +  '35' + 'm'    // Magenta                , #27'[' +  '33' + 'm'    // Brown                , #27'[' +  '37' + 'm'    // LightGray                , #27'[' +  '90' + 'm'    // DarkGray                , #27'[' +  '94' + 'm'    // LightBlue                , #27'[' +  '92' + 'm'    // LightGreen                , #27'[' +  '96' + 'm'    // LightCyan                , #27'[' +  '91' + 'm'    // LightRed              , #27'[' +  '95' + 'm'    // LightMagenta                , #27'[' +  '93' + 'm'    // Yellow                , #27'[' +  '97' + 'm');  // White          Styles_Background : array[ConsoleColor] of AnsiString =                ( #27'[' +  '40' + 'm'    // Black              , #27'[' +  '44' + 'm'    // Blue                , #27'[' +  '42' + 'm'    // Green                , #27'[' +  '46' + 'm'    // Cyan                , #27'[' +  '41' + 'm'    // Red                , #27'[' +  '45' + 'm'    // Magenta                , #27'[' +  '43' + 'm'    // Brown                , #27'[' +  '47' + 'm'    // LightGray                , #27'[' + '100' + 'm'    // DarkGray                , #27'[' + '104' + 'm'    // LightBlue                , #27'[' + '102' + 'm'    // LightGreen                , #27'[' + '106' + 'm'    // LightCyan                , #27'[' + '101' + 'm'    // LightRed              , #27'[' + '105' + 'm'    // LightMagenta                , #27'[' + '103' + 'm'    // Yellow                , #27'[' + '107' + 'm');  // White var        supported : boolean = False;  procedure TextColor     (const cc : ConsoleColor);  begin  if supported then Write(StdOut, Styles_Foreground[cc]);  end;procedure TextBackground(const cc : ConsoleColor);  begin  if supported then Write(StdOut, Styles_Background[cc]);  end;  procedure Console_Init;  inline;  // https://forum.lazarus.freepascal.org/index.php/topic,6397 8.msg485497.html#msg485497begin{$ifdef Windows}        // IsConsole := True;        // AllocConsole;        // SysInitStdIO;        // SetConsoleOutputCP(CP_UTF8);         const Flags = Enable_Processed_Output OR Enable_Virtual_Terminal_Processing;        var   Mode  : DWord;         var h := GetStdHandle  (STD_OUTPUT_HANDLE  );  if (h = 0) or (h = Invalid_Handle_Value) then exit;        var b := GetConsoleMode(h,  DWord((@Mode)^));  if not b                               then exit;  // GetConsoleMode uses a var parameter; some pointer magic prevents a compiler warning        ;   b := SetConsoleMode(h, Flags OR Mode   );  if not b                               then exit;{$endif}        supported := True;end;  //////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////  initialization        Console_Init;  end. ---------------------------------------------------------------------- geraldholdsworth · 2026-08-23 20:57 There are a load of colours, styles and other effects. They're listed on a few webpages - just do a websearch. I only listed a couple as an example here. I recently started using the escape character used to move the cursor about to great effect - updates progress for the user without cluttering up the display.