changing code pages

New to FreeBASIC? Post your questions here.
ron77
Posts: 77
Joined: Feb 21, 2019 19:24
Location: Israel

changing code pages

Postby ron77 » Aug 14, 2020 10:13

hello.

i have a question... is there any way to change the code page of the console window so it can print and display hebrew?

thank you...

ron77
MrSwiss
Posts: 3605
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: changing code pages

Postby MrSwiss » Aug 14, 2020 16:10

ron77 wrote:is there any way to change the code page of the console window ...
Yes, that can be done with Open Pipe.
However, I don't know whether 'hebrew' also works (not tested, CP unkown to me).

See: Code Page - the way you want it! (in Tips & Tricks section, about 3 years ago)
It even goes a step further, by saving current CP first and restores it again, before
the program quits.
ron77
Posts: 77
Joined: Feb 21, 2019 19:24
Location: Israel

Re: changing code pages

Postby ron77 » Aug 14, 2020 16:14

thank you very much MrSwiss :)

this sure helps alot...

ron77
jj2007
Posts: 1692
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: changing code pages

Postby jj2007 » Aug 15, 2020 0:54

Code: Select all

#include "Windows.bi"
Print "Current codepage is ";GetConsoleOutputCP()
SetConsoleOutputCP(862)
Print "The new codepage is ";GetConsoleOutputCP()
Print "Put Hebrew text here"
sleep
robert
Posts: 122
Joined: Aug 06, 2019 18:45

Re: changing code pages

Postby robert » Aug 15, 2020 2:06

jj2007 wrote:

Code: Select all

#include "Windows.bi"
Print "Current codepage is ";GetConsoleOutputCP()
SetConsoleOutputCP(862)
Print "The new codepage is ";GetConsoleOutputCP()
Print "Put Hebrew text here"
sleep


The console font must be changed to one that has Hebrew glyphs.

There are few, Courier New, Miriam are two. Even so, only letters, not vowel-points or cantillation marks are in fonts that support code page 862.

Unicode would be much better way to go.

Code: Select all


#include "Windows.bi"

dim as  _CONSOLE_FONT_INFOEX  x
with x
    .cbsize=sizeof(_CONSOLE_FONT_INFOEX)
    .nfont=0
    .dwfontsize=type(16,32)'new font size
    .fontfamily=0
    .fontweight=100
    .facename="Courier New"
end with

setcurrentconsolefontex(GetStdHandle(STD_OUTPUT_HANDLE),1, @x )

Print "Current codepage is ";GetConsoleOutputCP()
SetConsoleOutputCP(862)
Print "The new codepage is ";GetConsoleOutputCP()

Print CHR(128,129,130,131.132,133,134,135,136)

print "Press a key"
sleep

jj2007
Posts: 1692
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: changing code pages

Postby jj2007 » Aug 15, 2020 9:46

robert wrote:Unicode would be much better way to go
Don't expect miracles. The console should produce the same output with Utf8 (65001) or Utf16 (65000) but, as you wrote above, you need a font that supports the codepage.

Anyway, it's a can of worms. Print "This is Russian: Добро пожаловать" used to work fine, now it doesn't, and I don't have the faintest idea why it stopped working (it still works fine in other programming languages, and under the hood I see that codepage is Utf8 and a Utf8 string is being passed to the print function).

Code: Select all

#include "Windows.bi"
#include "crt.bi"

SetConsoleOutputCP(65001)
Print "The new codepage is ";GetConsoleOutputCP()
Print "FB:  this is Russian: Добро пожаловать"
Printf("Crt: this is Russian: Добро пожаловать"+chr(10))
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), @"WC:  this is Russian: Добро пожаловать", 53, 0, 0)
sleep

Output:

Code: Select all

The new codepage is 65001
FB:  this is Russian: ���������� ��������������������
Crt: this is Russian: �"�����?�� �����������������'�O
WC:  this is Russian: Добро пожаловать

I don't know what Print uses but apparently it's not WriteConsole
marcov
Posts: 3010
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Re: changing code pages

Postby marcov » Aug 15, 2020 10:43

IIRC for some locales you had to start your command box with "cmd /w"

In Free Pascal I use the following API call to set the font to consolas, since it is mostly API calls, it should be easily translatable. Or just google them in MSDN

Code: Select all

unit setdefaultcodepages;
 
interface
 
uses
  Windows;
 
implementation
 
Const
  LF_FACESIZE = 32;
 
Type
  CONSOLE_FONT_INFOEX = record
    cbSize     : ULONG;
    nFont      : DWORD;
    dwFontSize : COORD;
    FontFamily : UINT;
    FontWeight : UINT;
    FaceName   : array [0..LF_FACESIZE-1] of WCHAR;
  end;
 
{ Only supported in Vista and onwards!}
 
function SetCurrentConsoleFontEx(hConsoleOutput: HANDLE; bMaximumWindow: BOOL; var CONSOLE_FONT_INFOEX): BOOL; stdcall; external kernel32;
 
var
  New_CONSOLE_FONT_INFOEX: CONSOLE_FONT_INFOEX;

initialization

  FillChar(New_CONSOLE_FONT_INFOEX, SizeOf(CONSOLE_FONT_INFOEX), 0);
  New_CONSOLE_FONT_INFOEX.cbSize := SizeOf(CONSOLE_FONT_INFOEX);
  New_CONSOLE_FONT_INFOEX.FaceName := 'Consolas';
//  New_CONSOLE_FONT_INFOEX.FaceName := 'Lucida Console';  //use Lucida Console for Win XP
  New_CONSOLE_FONT_INFOEX.FontWeight := 400;
  New_CONSOLE_FONT_INFOEX.dwFontSize.Y := 16;
 
  SetCurrentConsoleFontEx(StdOutputHandle, False, New_CONSOLE_FONT_INFOEX);
end.


P.s. there is also a way to change to utf8 by manifest in recent Windows 10s. This means that all -A apis also accept utf8:
https://docs.microsoft.com/en-us/window ... -code-page
dodicat
Posts: 6687
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: changing code pages

Postby dodicat » Aug 15, 2020 11:19

No problems using my own quick run program

Code: Select all

This is Russian: Добро пожаловать
Free basic version 1.07-(08).0

 

I save the file via wordpad (write.exe) then run the saved file.
jj2007
Posts: 1692
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: changing code pages

Postby jj2007 » Aug 15, 2020 12:21

dodicat wrote:No problems using my own quick run program

Code: Select all

This is Russian: Добро пожаловать
Free basic version 1.07-(08).0

 

I save the file via wordpad (write.exe) then run the saved file.
I'm not sure if I understand. Did you mean you save the *.bas file with Wordpad, then you build and run using this file?
dodicat
Posts: 6687
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: changing code pages

Postby dodicat » Aug 15, 2020 12:32

I saved it as russian.txt and compiled and ran (through my own quick run ide/editor, which is basically command line via a little gui).
fbide doesn't handle these characters.
Notepad on this machine also curupts the characters.
Win 10.
marcov
Posts: 3010
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Re: changing code pages

Postby marcov » Aug 15, 2020 12:47

dodicat wrote:I saved it as russian.txt and compiled and ran (through my own quick run ide/editor, which is basically command line via a little gui).
fbide doesn't handle these characters.
Notepad on this machine also curupts the characters.
Win 10.


Notepad probably scans for bom. Emit a BOM if you want to let it autoguess utf8.
jj2007
Posts: 1692
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: changing code pages

Postby jj2007 » Aug 15, 2020 13:47

In my case it's not the IDE (I use my own editor, it does emit Utf8).

Code: Select all

The new codepage is 65001
FB:  this is Russian: ���������� ��������������������
Crt: this is Russian: �"�����?�� �����������������'�O
WC:  this is Russian: Добро пожаловать

The problem is another one: in all three cases, standard FB print, Printf(), and WriteConsole, a Utf8 String is passed correctly (checked in the debugger at assembly level). But only WriteFile and WriteConsole produce the correct output. What does FB use for its default Print? I debugged print but so far I could not find the call to the Windows API. The last one I see is a call to GetConsoleScreenBufferInfo, afterwards it returns in an unusual way. Note that the Ansi part of the string gets printed correctly - it's just the cyrillic bit that misbehaves...

Code: Select all

#include "Windows.bi"
#include "crt.bi"
SetConsoleOutputCP(65001)   ' Utf8
Print "Print:   Добро пожаловать"
Printf("Printf:   Добро пожаловать")
Print
Dim As integer hOut=GetStdHandle(STD_OUTPUT_HANDLE)
WriteFile(hOut, @"WriteFile:   Добро пожаловать", 42, 0, 0)
Print
WriteConsole(hOut, @"WriteConsole:   Добро пожаловать", 45, 0, 0)
sleep

Output:

Code: Select all

Print:  ���������� ��������������������
Printf: �"�����?�� �����������������'�O
WriteFile:      Добро пожаловать
WriteConsole:   Добро пожаловать

P.S.: I suspect it stopped working after I updated to FB 1.07. With version 1.05, print definitely displayed Russian correctly.
dodicat
Posts: 6687
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: changing code pages

Postby dodicat » Aug 15, 2020 15:20

My result

Code: Select all

Print:   Добро пожаловать
Printf:   ????? ??????????
W r i t e F i l e :       >1@>  ?>
W r i t e C o n s o l e :       >1@>  ?
v1ctor
Site Admin
Posts: 3801
Joined: May 27, 2005 8:08
Location: SP / Bra[s]il
Contact:

Re: changing code pages

Postby v1ctor » Aug 15, 2020 18:42

The source file must have a BOM header to allow literal unicode strings to be correctly parsed.

See: https://github.com/freebasic/fbc/tree/m ... es/unicode
SARG
Posts: 1140
Joined: May 27, 2005 7:15
Location: FRANCE

Re: changing code pages

Postby SARG » Aug 15, 2020 20:53

@jj2007
With gas64 only WriteFile and WriteConsole displays the right string however the lenght should be respectively 44 et 47 otherwise the last character is lost. I counted effectively 2 more. eg for writeconsole 17 ascii + 15 x 2 unicodes.
Just curious, did you really get all the characters with 42 and 45 ?

Return to “Beginners”

Who is online

Users browsing this forum: No registered users and 2 guests