3

My Delphi (XE 10) program uses nonunicode (single byte) legacy Firebird database (character set NONE) and therefore its data (that are read from or saved into database) depends on the windows Locale for the nonunicode programs. Depending on this Windows setting the same database character can be displayed in the program as \u0101 (that is correct) or \u0432 (that is not correct). IBX serves as DB access technology.

My program works only for the specificed local for nonunicode programs and that is acceptable for the client. The question is - how can I make program to feel the specific predefined locale regardless of the Windows settings?

I guess that I should use SetThreadLocale for this. But where to put this call? Is it sufficient to call this function in the initialization section of the Main form or should I call it in the project source file (where application is initialized) or maybe I should call it in the initialization sections of each module?

Owing to comments I was made aware of GetThreadLocale returns different value than GetUserDefaultLCID? I now see that I should write a bit more code:

SetThreadLocale(my_preferred_locale_id); 
SysLocale.DefaultLCID := my_preferred_locale_id; 
GetFormatSettings;

But the main question still remains - where to put this code - should I put it into multiple places. I have WebSnap application and I guess that it can have automatic and complex tread management under the hood. Where code should go?

Nothing helps:

  • adding lc_ctype=WIN1257 to TIBDatabase.Params
  • setting SetThreadLocale... here, there and everywhere
  • setting Project Options - Version Info - Language - Locale ID

https://github.com/xupefei/Locale-Emulator Locale Emulator is the only tool that solves the problem but why Delphi does not allow to do this without external tool?

Community
  • 1
  • 1
TomR
  • 2,696
  • 6
  • 34
  • 87

1 Answers1

2

As I also posted on the Firebird-support mailing list (curiously the poster there had a different name, but the same problem):

It sounds to me like apart from your database using NONE, you also connect with character set NONE. To solve this, explicitly specifying lc_ctype = win1257 should be enough.

I don't know Delphi well enough, but assuming Delphi internally uses unicode, then it should work.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • No, this did not help! – TomR Feb 10 '17 at 12:36
  • Delphi 10 Seattle ignores this lc_ctype, it only reports incorrect value if lc_ctype specifies nonexisting characterset (or in lowercase format). Otherwise it does not work. Hard to believe but it happens with Delphi. – TomR Feb 13 '17 at 12:25
  • @TomR Maybe you should consider changing your database to be explicitly WIN1257 (or maybe UTF8), and connect with UTF8 instead. – Mark Rotteveel Feb 13 '17 at 12:27
  • Project constraints does not allow such change. Of course, I have done that in other projects and the results were worth of investment, but, sadly, it is not allowed in this case. – TomR Feb 13 '17 at 22:23
  • @TomR Then I can only suggest that you add more details to this question, like connection configuration used, some code, etc. Maybe some one with actual Delphi experience comes up with an actual solution. – Mark Rotteveel Feb 14 '17 at 10:01