🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.internationalization
Article #8

Re: Problem with Polish chars

#8
From: Roland Seidel
Date: Wed, 25 Oct 2006 01:37
139 lines
7351 bytes
Hi Tomek,

I'm developing in English (basic locale) using BCB6 and BDS C++2006 for 
a client who asked specifically about Polish and Korean. I can't offer 
much help in sorting out your code but here's what I did.

There are several problems - display, input, load, save.  Display and 
input are both managed by letting the user select the font (including 
charset - East European for Polish) that will be used for all controls 
and display elements.
In a central class (TMainLib) I have
   TFont* SystemFont;  // font for holding charset for edit fields etc.
and on a preferences dialog I let them change that to anything they want.
   FontDialog->Font = MainLib->SystemFont;
   FontDialog->Execute();
   MainLib->SystemFont->Assign(FontDialog->Font);
[Note that you have to use ->Assign() for a TFont*]

DISPLAY, INPUT-----------------------
Then everytime a dialog opens I assign that font to any controls that 
might display or input language specific text
   edit->Font = MainLib->SystemFont;
   label->Font = MainLib->SystemFont;
That covered display. For input I had to install other language options 
in Control Panel | Regional and Language | Language tab including 
setting extra keyboards in Input Langages | Details. After doing that I 
could select the Polish keyboard (EN/PO bottom left near the systray) 
and use Alt-a to get the ogenek into a control as long as it had East 
European charset. Sending Text to a TCanvas is handled the same way - 
set the Canvas->Font=SystemFont before calling TextOut etc.

SAVE, LOAD ---------------------------
File save and load seemed to be handled ok by ANSI. I retrieve the text 
from the control in the normal way (edit->Text) and write it to ANSI 
files. When I load it it still looks Polish - but if I change charset to 
Cyrillic it looks Russian.

This is ok if you have only one language you want to accommodate. But if 
you want to see Polish and Korean in the same program you can juggle 
lots of  different fonts for different TextOut calls or different 
controls but it is not satisfactory. For that you need Unicode, although 
you do not need to go all the way to defining _UNICODE and there is one 
very good reason why you would not (see later).

UNICODE, TNT -----------------------------------
VCL does not handle Unicode, it might in the future but for now you have 
to use a third party set of controls but they are extremely good and 
free. http://www.tntware.com/delphicontrols/unicode/ Download the 
installation program - it does a great job putting it into your 
compilers. Replace every control with its Tnt equivalent (TEdit becomes 
TTntEdit) and start using wide chars for all your text handling.

WIDE CODE ----------------------------
You don't need to define _UNICODE to use wide string functions. Use 
WideStrings instead of AnsiStrings, wchar_t* instead of char*, wcslen() 
instead of strlen(), etc.

It's a big conversion job and I started off using the switchable version 
like _TCHAR and _tcslen() but I don't like it. That meant defining 
_UNICODE to get the wide versions and that caused a problem. I want to 
use COM/ATL and there is a bug in Borland's code that makes it 
impossible to add a COM object with _UNICODE defined (see the exchange 
in the ActiveX forum on Unicode and COM/ATL).

DISPLAY, INPUT -----------------------------------
The Tnt controls take care of the display - as long as you read/write to 
them with WideString or wchar_t*. Input still depends on selecting 
language and keyboard and having the right charset available in the 
control. Writing text to a canvas has to be done differently. Instead of
   Canvas->TextOut(x,y,"something")
you use
   WideCanvasTextOut(Canvas,x,y,"something");
There are Tnt replacements for all the canvas functions. I had to look 
in ProgramFiles/TntWare/DelphiUnicodeControls/Source/Graphics.hpp to 
find them - there's no online help for the Tnt controls.


FILE SAVE/LOAD, UTF8 ------------------------------
There's lots of ways to do file access, I use TFileStreams and you can 
replace these with TTntFileStreams (in TntClasses.hpp).
Open a file for writing (note the L before the name - long string)
   TTntFileStream* fs = new TTntFileStream(L"test.txt", fmCreate);
You can write ANSI files just like you used to
   char* tx = "something";
   fs->Write(tx, strlen(tx));
You can write Unicode files (note the *2 in the size param because it is 
still a byte stream and wchar_t has double the bytes - your files will 
be twice as big)
   wchar_t* wx = L"something";
   fs->Write(wx, wcslen(tx)*2);
Or you can have the best of both worlds and write UTF8. This is single 
byte and looks identical to ANSI if you have no characters outside the 
basic code page and uses multibytes for others.
   WideString ws = L"something";
   AnsiString as = UTF8Encode(ws);
   fs->Write(as.c_str(), as.Length());

You can read ANSI
   TTntFileStream* fs = new TTntFileStream(L"test.txt", fmOpenRead);
   char buf[100];
   fs->Read(buf,100);
You can read Unicode
   wchar_t buf[100];
   fs->Read(buf,200);  // note - 200 bytes for 100 wide chars
You can read UTF8
   char buf[100];
   fs->Read(buf,100);
   WideString ws = UTF8Decode(buf);

BYTE ORDER MARKS ---------------------------------
You might have to concern yourself with byte order marks - special chars 
at the start of a file indicating if it is ANSI, UTF8 or Unicode. These 
are optional but you might run into them.
Unicode files might start with two bytes FF FE
UTF8 files might start with three bytes EE BB BF
ANSI files never have special chars at the start.

Hope some of that was helpful

Roland






Tomek Kuchta wrote:
> Thank you very much for your time and help.
> I will try to change the locale.
> 
> I have also thought about idea of changing character encoding of source 
> code files to Unicode or ISO-8856-2 (under Linux) to eliminate problems 
> with those strings, that are declared inside the code (for example 
> strings showing on dialog boxes). Do you think that it could partially 
> solve the problem?
> 
> Best regards,
> 
> Tomek Kuchta
Technical Details
Message-ID: <453ebff3@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news2.google.com!news3.google.com!news1.google.com!news.germany.com!solnet.ch!solnet.ch!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
References: <453921bf@newsgroups.borland.com> <453c6e24$1@newsgroups.borland.com> <453cd43b$1@newsgroups.borland.com> <453d9e95$2@newsgroups.borland.com> <453db43f$1@newsgroups.borland.com> <453e1f47@newsgroups.borland.com> <453e51da$1@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 10297d,55383b06559e4818
X-Google-Attributes: gid10297d,public
X-Google-Language: ENGLISH,ASCII-7-bit
Date: Wed, 25 Oct 2006 11:37:56 +1000
From: Roland Seidel <roland@redcentresoftware.com>
User-Agent: Thunderbird 1.5.0.7 (Windows/20060909)
MIME-Version: 1.0
Newsgroups: borland.public.cppbuilder.internationalization
Subject: Re: Problem with Polish chars
References: <453921bf@newsgroups.borland.com> <453c6e24$1@newsgroups.borland.com> <453cd43b$1@newsgroups.borland.com> <453d9e95$2@newsgroups.borland.com> <453db43f$1@newsgroups.borland.com> <453e1f47@newsgroups.borland.com> <453e51da$1@newsgroups.borland.com>
In-Reply-To: <453e51da$1@newsgroups.borland.com>
Content-Type: text/plain; charset=ISO-8859-2; format=flowed
Content-Transfer-Encoding: 7bit
NNTP-Posting-Host: 202.164.198.171
Message-ID: <453ebff3@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1161740275 202.164.198.171 (24 Oct 2006 18:37:55 -0700)
Lines: 139
Path: arc1-ca.pugleaf.net!g2news2.google.com!news3.google.com!news1.google.com!news.germany.com!solnet.ch!solnet.ch!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail